From b3134ce50ba348d13c0a5ee27a34d0f1d41c8f6d Mon Sep 17 00:00:00 2001 From: duckietm Date: Wed, 3 Apr 2024 09:27:56 +0200 Subject: [PATCH] Move to Renderer V2 --- .browserslistrc | 3 +- .editorconfig | 16 + .eslintrc.json | 110 - .gitignore | 32 +- LICENSE | 674 ++++ README.md | 45 +- index.html | 36 - index.ts | 1 + package.json | 66 +- packages/api/.gitignore | 51 + packages/api/index.ts | 1 + packages/api/package.json | 22 + packages/api/src/asset/IAsset.ts | 9 + packages/api/src/asset/IAssetAlias.ts | 6 + packages/api/src/asset/IAssetData.ts | 23 + packages/api/src/asset/IAssetManager.ts | 18 + packages/api/src/asset/IAssetPalette.ts | 12 + packages/api/src/asset/IGraphicAsset.ts | 19 + .../api/src/asset/IGraphicAssetCollection.ts | 24 + .../api/src/asset/IGraphicAssetPalette.ts | 8 + .../src/asset/animation/IAssetAnimation.ts | 23 + .../src/asset/animation/IAssetAnimationAdd.ts | 8 + .../asset/animation/IAssetAnimationAvatar.ts | 6 + .../animation/IAssetAnimationDirection.ts | 4 + .../asset/animation/IAssetAnimationFrame.ts | 8 + .../animation/IAssetAnimationFramePart.ts | 14 + .../animation/IAssetAnimationFramePartItem.ts | 5 + .../animation/IAssetAnimationOverride.ts | 8 + .../asset/animation/IAssetAnimationRemove.ts | 4 + .../asset/animation/IAssetAnimationShadow.ts | 4 + .../asset/animation/IAssetAnimationSprite.ts | 11 + .../IAssetAnimationSpriteDirection.ts | 7 + packages/api/src/asset/animation/index.ts | 12 + packages/api/src/asset/index.ts | 19 + .../src/asset/logic/IAssetLogicCustomVars.ts | 4 + .../api/src/asset/logic/IAssetLogicData.ts | 17 + .../asset/logic/IAssetLogicPlanetSystem.ts | 11 + packages/api/src/asset/logic/ISoundSample.ts | 5 + packages/api/src/asset/logic/index.ts | 6 + .../src/asset/logic/model/IAssetDimension.ts | 6 + .../src/asset/logic/model/IAssetLogicModel.ts | 7 + packages/api/src/asset/logic/model/index.ts | 2 + .../logic/particlesystem/IParticleSystem.ts | 11 + .../particlesystem/IParticleSystemEmitter.ts | 15 + .../particlesystem/IParticleSystemParticle.ts | 7 + .../IParticleSystemSimulation.ts | 9 + .../src/asset/logic/particlesystem/index.ts | 4 + .../asset/room-visualization/IAssetPlane.ts | 8 + .../room-visualization/IAssetPlaneMask.ts | 7 + .../room-visualization/IAssetPlaneMaskData.ts | 6 + .../IAssetPlaneMaskVisualization.ts | 7 + .../room-visualization/IAssetPlaneMaterial.ts | 7 + .../IAssetPlaneMaterialCell.ts | 7 + .../IAssetPlaneMaterialCellColumn.ts | 8 + .../IAssetPlaneMaterialCellExtraItemData.ts | 6 + .../IAssetPlaneMaterialCellMatrix.ts | 12 + .../room-visualization/IAssetPlaneTexture.ts | 7 + .../IAssetPlaneTextureBitmap.ts | 8 + .../IAssetPlaneVisualization.ts | 10 + .../IAssetPlaneVisualizationAnimatedLayer.ts | 6 + ...ssetPlaneVisualizationAnimatedLayerItem.ts | 11 + .../IAssetPlaneVisualizationData.ts | 10 + .../IAssetPlaneVisualizationLayer.ts | 7 + .../IAssetRoomVisualizationData.ts | 10 + .../api/src/asset/room-visualization/index.ts | 17 + .../src/asset/spritesheet/ISpritesheetData.ts | 9 + .../asset/spritesheet/ISpritesheetFrame.ts | 25 + .../src/asset/spritesheet/ISpritesheetMeta.ts | 12 + packages/api/src/asset/spritesheet/index.ts | 3 + .../visualization/IAssetVisualizationData.ts | 20 + .../IAssetVisualizationDirection.ts | 6 + .../visualization/IAssetVisualizationLayer.ts | 10 + .../animation/IAssetVisualAnimation.ts | 10 + .../animation/IAssetVisualAnimationLayer.ts | 9 + .../IAssetVisualAnimationSequence.ts | 8 + .../IAssetVisualAnimationSequenceFrame.ts | 11 + ...AssetVisualAnimationSequenceFrameOffset.ts | 6 + .../asset/visualization/animation/index.ts | 5 + .../asset/visualization/color/IAssetColor.ts | 6 + .../visualization/color/IAssetColorLayer.ts | 4 + .../src/asset/visualization/color/index.ts | 2 + .../visualization/gestures/IAssetGesture.ts | 5 + .../src/asset/visualization/gestures/index.ts | 1 + packages/api/src/asset/visualization/index.ts | 7 + .../visualization/postures/IAssetPosture.ts | 5 + .../src/asset/visualization/postures/index.ts | 1 + packages/api/src/common/IDisposable.ts | 5 + packages/api/src/common/IEventDispatcher.ts | 10 + packages/api/src/common/ILinkEventTracker.ts | 5 + packages/api/src/common/INitroEvent.ts | 4 + packages/api/src/common/INitroManager.ts | 10 + packages/api/src/common/IUpdateReceiver.ts | 6 + packages/api/src/common/index.ts | 6 + packages/api/src/communication/ICodec.ts | 9 + .../communication/ICommunicationManager.ts | 10 + packages/api/src/communication/IConnection.ts | 17 + .../communication/IConnectionStateListener.ts | 4 + .../api/src/communication/IMessageComposer.ts | 5 + .../communication/IMessageConfiguration.ts | 5 + .../src/communication/IMessageDataWrapper.ts | 15 + .../api/src/communication/IMessageEvent.ts | 11 + .../api/src/communication/IMessageParser.ts | 7 + .../enums/ClientDeviceCategoryEnum.ts | 5 + .../communication/enums/ClientPlatformEnum.ts | 7 + .../communication/enums/WebSocketEventEnum.ts | 7 + packages/api/src/communication/enums/index.ts | 3 + packages/api/src/communication/index.ts | 10 + packages/api/src/index.ts | 43 + .../avatar/IAvatarAssetDownloadLibrary.ts | 6 + .../src/nitro/avatar/IAvatarEffectListener.ts | 4 + .../nitro/avatar/IAvatarFigureContainer.ts | 10 + packages/api/src/nitro/avatar/IAvatarImage.ts | 29 + .../src/nitro/avatar/IAvatarImageListener.ts | 6 + .../src/nitro/avatar/IAvatarRenderManager.ts | 22 + .../avatar/IEffectAssetDownloadLibrary.ts | 9 + packages/api/src/nitro/avatar/IOutfit.ts | 5 + .../nitro/avatar/actions/IActionDefinition.ts | 19 + .../nitro/avatar/actions/IActiveActionData.ts | 11 + .../api/src/nitro/avatar/actions/index.ts | 2 + .../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 + .../api/src/nitro/avatar/animation/index.ts | 5 + .../api/src/nitro/avatar/enum/AvatarAction.ts | 127 + .../nitro/avatar/enum/AvatarDirectionAngle.ts | 7 + .../avatar/enum/AvatarEditorFigureCategory.ts | 10 + .../avatar/enum/AvatarEditorInstanceId.ts | 7 + .../avatar/enum/AvatarEditorSideCategory.ts | 5 + .../nitro/avatar/enum/AvatarFigurePartType.ts | 29 + .../nitro/avatar/enum/AvatarGuideStatus.ts | 6 + .../src/nitro/avatar/enum/AvatarScaleType.ts | 5 + .../src/nitro/avatar/enum/AvatarSetType.ts | 6 + .../api/src/nitro/avatar/enum/GeometryType.ts | 8 + .../api/src/nitro/avatar/enum/RenderMode.ts | 7 + packages/api/src/nitro/avatar/enum/index.ts | 11 + .../nitro/avatar/figuredata/IFigureData.ts | 8 + .../avatar/figuredata/IFigureDataColor.ts | 8 + .../figuredata/IFigureDataHiddenLayer.ts | 4 + .../avatar/figuredata/IFigureDataPalette.ts | 7 + .../avatar/figuredata/IFigureDataPart.ts | 8 + .../nitro/avatar/figuredata/IFigureDataSet.ts | 15 + .../avatar/figuredata/IFigureDataSetType.ts | 12 + .../api/src/nitro/avatar/figuredata/index.ts | 7 + packages/api/src/nitro/avatar/index.ts | 13 + .../src/nitro/avatar/structure/IFigurePart.ts | 9 + .../nitro/avatar/structure/IFigurePartSet.ts | 16 + .../nitro/avatar/structure/IFigureSetData.ts | 7 + .../src/nitro/avatar/structure/IPalette.ts | 9 + .../src/nitro/avatar/structure/IPartColor.ts | 8 + .../src/nitro/avatar/structure/ISetType.ts | 12 + .../nitro/avatar/structure/IStructureData.ts | 12 + .../api/src/nitro/avatar/structure/index.ts | 7 + .../nitro/camera/IRoomCameraWidgetEffect.ts | 10 + .../nitro/camera/IRoomCameraWidgetManager.ts | 11 + .../camera/IRoomCameraWidgetSelectedEffect.ts | 7 + packages/api/src/nitro/camera/index.ts | 3 + .../src/nitro/enums/RelationshipStatusEnum.ts | 10 + .../api/src/nitro/enums/ToolbarIconEnum.ts | 10 + packages/api/src/nitro/enums/index.ts | 2 + packages/api/src/nitro/index.ts | 18 + .../localization/ILocalizationManager.ts | 16 + packages/api/src/nitro/localization/index.ts | 1 + .../api/src/nitro/room/IGetImageListener.ts | 7 + packages/api/src/nitro/room/IImageResult.ts | 9 + .../api/src/nitro/room/IPetColorResult.ts | 10 + .../src/nitro/room/IRoomContentListener.ts | 4 + .../api/src/nitro/room/IRoomContentLoader.ts | 33 + packages/api/src/nitro/room/IRoomCreator.ts | 51 + packages/api/src/nitro/room/IRoomEngine.ts | 89 + .../api/src/nitro/room/IRoomEngineServices.ts | 41 + .../src/nitro/room/IRoomObjectEventManager.ts | 6 + .../src/nitro/room/ISelectedRoomObjectData.ts | 18 + .../enums/FriendFurniEngravingWidgetType.ts | 8 + .../room/enums/RoomObjectPlacementSource.ts | 5 + packages/api/src/nitro/room/enums/index.ts | 2 + packages/api/src/nitro/room/index.ts | 15 + .../src/nitro/room/object/IPetFigureData.ts | 12 + .../api/src/nitro/room/object/IRoomMapData.ts | 11 + .../nitro/room/object/RoomObjectCategory.ts | 9 + .../nitro/room/object/RoomObjectLogicType.ts | 74 + .../room/object/RoomObjectOperationType.ts | 15 + .../src/nitro/room/object/RoomObjectType.ts | 7 + .../nitro/room/object/RoomObjectUserType.ts | 40 + .../nitro/room/object/RoomObjectVariable.ts | 144 + .../object/RoomObjectVisualizationType.ts | 40 + .../src/nitro/room/object/data/IObjectData.ts | 17 + .../nitro/room/object/data/ObjectDataBase.ts | 99 + .../room/object/data/ObjectDataFactory.ts | 44 + .../nitro/room/object/data/ObjectDataFlags.ts | 4 + .../nitro/room/object/data/ObjectDataKey.ts | 11 + .../api/src/nitro/room/object/data/index.ts | 6 + .../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 | 131 + .../room/object/data/type/LegacyDataType.ts | 59 + .../room/object/data/type/MapDataType.ts | 90 + .../room/object/data/type/NumberDataType.ts | 91 + .../room/object/data/type/StringDataType.ts | 90 + .../room/object/data/type/VoteDataType.ts | 66 + .../src/nitro/room/object/data/type/index.ts | 9 + packages/api/src/nitro/room/object/index.ts | 11 + .../room/utils/IFurnitureStackingHeightMap.ts | 11 + .../nitro/room/utils/ILegacyWallGeometry.ts | 18 + .../src/nitro/room/utils/ITileObjectMap.ts | 11 + .../api/src/nitro/room/utils/ObjectRolling.ts | 40 + packages/api/src/nitro/room/utils/index.ts | 4 + .../api/src/nitro/session/BreedingPetInfo.ts | 55 + .../api/src/nitro/session/FurnitureType.ts | 10 + .../api/src/nitro/session/IFurnitureData.ts | 33 + .../nitro/session/IFurnitureDataListener.ts | 4 + .../nitro/session/IGroupInformationManager.ts | 5 + .../src/nitro/session/IIgnoredUsersManager.ts | 9 + .../api/src/nitro/session/IPetCustomPart.ts | 6 + packages/api/src/nitro/session/IPollChoice.ts | 6 + .../api/src/nitro/session/IPollQuestion.ts | 14 + .../api/src/nitro/session/IProductData.ts | 6 + .../src/nitro/session/IProductDataListener.ts | 6 + packages/api/src/nitro/session/IQuestion.ts | 12 + .../src/nitro/session/IRoomHandlerListener.ts | 8 + .../nitro/session/IRoomModerationSettings.ts | 6 + .../api/src/nitro/session/IRoomPetData.ts | 30 + .../api/src/nitro/session/IRoomSession.ts | 64 + .../src/nitro/session/IRoomSessionManager.ts | 11 + .../api/src/nitro/session/IRoomUserData.ts | 26 + .../src/nitro/session/ISessionDataManager.ts | 56 + .../api/src/nitro/session/IUserDataManager.ts | 23 + .../nitro/session/PetBreedingResultData.ts | 58 + .../api/src/nitro/session/PetCustomPart.ts | 45 + .../api/src/nitro/session/PetFigureData.ts | 229 ++ .../src/nitro/session/RarityCategoryData.ts | 40 + .../nitro/session/enum/GenericErrorEnum.ts | 5 + .../nitro/session/enum/NoobnessLevelEnum.ts | 6 + .../api/src/nitro/session/enum/PetType.ts | 38 + .../nitro/session/enum/RoomControllerLevel.ts | 9 + .../session/enum/RoomTradingLevelEnum.ts | 22 + .../src/nitro/session/enum/SecurityLevel.ts | 13 + packages/api/src/nitro/session/enum/index.ts | 6 + packages/api/src/nitro/session/index.ts | 25 + .../api/src/nitro/sound/IMusicController.ts | 25 + .../src/nitro/sound/IPlaylistController.ts | 16 + packages/api/src/nitro/sound/ISongInfo.ts | 12 + packages/api/src/nitro/sound/ISoundManager.ts | 8 + packages/api/src/nitro/sound/index.ts | 4 + .../api/src/room/IPetBreedingResultData.ts | 10 + packages/api/src/room/IRoomGeometry.ts | 21 + packages/api/src/room/IRoomInstance.ts | 27 + .../api/src/room/IRoomInstanceContainer.ts | 8 + packages/api/src/room/IRoomManager.ts | 16 + packages/api/src/room/IRoomManagerListener.ts | 5 + packages/api/src/room/IRoomObjectManager.ts | 14 + .../api/src/room/IRoomObjectUpdateMessage.ts | 7 + .../api/src/room/IRoomSpriteMouseEvent.ts | 17 + packages/api/src/room/RoomObjectSpriteData.ts | 18 + packages/api/src/room/index.ts | 15 + packages/api/src/room/object/IRoomObject.ts | 22 + .../src/room/object/IRoomObjectController.ts | 18 + .../api/src/room/object/IRoomObjectModel.ts | 8 + .../room/object/IRoomObjectModelController.ts | 11 + .../src/room/object/enum/AlphaTolerance.ts | 6 + .../room/object/enum/RoomObjectSpriteType.ts | 7 + packages/api/src/room/object/enum/index.ts | 2 + packages/api/src/room/object/index.ts | 7 + .../object/logic/IRoomObjectEventHandler.ts | 20 + .../object/logic/IRoomObjectLogicFactory.ts | 10 + .../object/logic/IRoomObjectMouseHandler.ts | 7 + packages/api/src/room/object/logic/index.ts | 3 + .../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 + .../room/object/visualization/IRoomPlane.ts | 10 + .../object/visualization/ISortableSprite.ts | 9 + .../src/room/object/visualization/index.ts | 10 + .../room/renderer/IRoomCanvasMouseListener.ts | 8 + .../api/src/room/renderer/IRoomRenderer.ts | 9 + .../src/room/renderer/IRoomRendererBase.ts | 10 + .../src/room/renderer/IRoomRenderingCanvas.ts | 36 + .../renderer/IRoomSpriteCanvasContainer.ts | 8 + packages/api/src/room/renderer/index.ts | 5 + packages/api/src/ui/MouseEventType.ts | 12 + packages/api/src/ui/TouchEventType.ts | 8 + .../api/src/ui/enums/AvatarExpressionEnum.ts | 28 + packages/api/src/ui/enums/ContextMenuEnum.ts | 12 + .../FriendWidgetEngravingWidgetTypeEnum.ts | 8 + packages/api/src/ui/enums/RoomWidgetEnum.ts | 57 + .../RoomWidgetEnumItemExtradataParameter.ts | 10 + .../RoomWidgetFurniInfoUsagePolicyEnum.ts | 6 + .../api/src/ui/enums/SystemChatStyleEnum.ts | 6 + packages/api/src/ui/enums/index.ts | 7 + packages/api/src/ui/index.ts | 3 + packages/api/src/utils/IAdvancedMap.ts | 22 + packages/api/src/utils/IBinaryReader.ts | 12 + packages/api/src/utils/IBinaryWriter.ts | 11 + packages/api/src/utils/IVector3D.ts | 16 + packages/api/src/utils/index.ts | 4 + packages/api/tsconfig.json | 31 + packages/assets/.eslintrc.json | 3 + packages/assets/.gitignore | 51 + packages/assets/index.ts | 1 + packages/assets/package.json | 25 + packages/assets/src/AssetManager.ts | 151 + packages/assets/src/GetAssetManager.ts | 5 + packages/assets/src/GraphicAsset.ts | 140 + packages/assets/src/GraphicAssetCollection.ts | 372 ++ packages/assets/src/GraphicAssetPalette.ts | 57 + packages/assets/src/index.ts | 5 + packages/assets/tsconfig.json | 31 + packages/avatar/.eslintrc.json | 3 + packages/avatar/.gitignore | 51 + packages/avatar/index.ts | 1 + packages/avatar/package.json | 22 + .../avatar/src/AvatarAssetDownloadLibrary.ts | 65 + .../avatar/src/AvatarAssetDownloadManager.ts | 246 ++ packages/avatar/src/AvatarFigureContainer.ts | 116 + packages/avatar/src/AvatarImage.ts | 764 ++++ .../src/AvatarImageBodyPartContainer.ts | 88 + .../avatar/src/AvatarImagePartContainer.ts | 133 + packages/avatar/src/AvatarRenderManager.ts | 292 ++ packages/avatar/src/AvatarStructure.ts | 619 ++++ .../avatar/src/EffectAssetDownloadLibrary.ts | 75 + .../avatar/src/EffectAssetDownloadManager.ts | 206 ++ packages/avatar/src/FigureDataContainer.ts | 241 ++ packages/avatar/src/GetAvatarRenderManager.ts | 5 + packages/avatar/src/PlaceHolderAvatarImage.ts | 18 + .../avatar/src/actions/ActionDefinition.ts | 220 ++ packages/avatar/src/actions/ActionType.ts | 44 + .../avatar/src/actions/ActiveActionData.ts | 73 + .../avatar/src/actions/AvatarActionManager.ts | 186 + packages/avatar/src/actions/index.ts | 4 + packages/avatar/src/alias/AssetAlias.ts | 37 + .../avatar/src/alias/AssetAliasCollection.ts | 89 + packages/avatar/src/alias/index.ts | 2 + .../avatar/src/animation/AddDataContainer.ts | 61 + packages/avatar/src/animation/Animation.ts | 311 ++ .../avatar/src/animation/AnimationManager.ts | 49 + .../src/animation/AvatarAnimationLayerData.ts | 109 + .../src/animation/AvatarDataContainer.ts | 136 + .../src/animation/DirectionDataContainer.ts | 16 + .../src/animation/SpriteDataContainer.ts | 94 + packages/avatar/src/animation/index.ts | 7 + .../src/cache/AvatarImageActionCache.ts | 57 + .../src/cache/AvatarImageBodyPartCache.ts | 96 + packages/avatar/src/cache/AvatarImageCache.ts | 444 +++ .../src/cache/AvatarImageDirectionCache.ts | 59 + packages/avatar/src/cache/ImageData.ts | 65 + packages/avatar/src/cache/index.ts | 5 + .../avatar/src/data/HabboAvatarAnimations.ts | 827 +++++ .../avatar/src/data/HabboAvatarGeometry.ts | 1830 +++++++++ .../avatar/src/data/HabboAvatarPartSets.ts | 418 +++ .../src/geometry/AvatarModelGeometry.ts | 287 ++ packages/avatar/src/geometry/AvatarSet.ts | 92 + .../avatar/src/geometry/GeometryBodyPart.ts | 192 + packages/avatar/src/geometry/GeometryItem.ts | 54 + packages/avatar/src/geometry/index.ts | 4 + packages/avatar/src/index.ts | 25 + .../src/structure/AvatarAnimationData.ts | 57 + packages/avatar/src/structure/AvatarCanvas.ts | 47 + .../avatar/src/structure/FigureSetData.ts | 129 + packages/avatar/src/structure/PartSetsData.ts | 118 + .../structure/animation/AnimationAction.ts | 138 + .../animation/AnimationActionPart.ts | 30 + .../animation/AvatarAnimationFrame.ts | 21 + .../avatar/src/structure/animation/index.ts | 3 + .../avatar/src/structure/figure/FigurePart.ts | 53 + .../src/structure/figure/FigurePartSet.ts | 134 + .../avatar/src/structure/figure/Palette.ts | 46 + .../avatar/src/structure/figure/PartColor.ts | 46 + .../avatar/src/structure/figure/SetType.ts | 104 + packages/avatar/src/structure/figure/index.ts | 5 + packages/avatar/src/structure/index.ts | 7 + .../src/structure/parts/ActivePartSet.ts | 26 + .../src/structure/parts/PartDefinition.ts | 64 + packages/avatar/src/structure/parts/index.ts | 2 + packages/avatar/tsconfig.json | 31 + packages/camera/.eslintrc.json | 3 + packages/camera/.gitignore | 51 + packages/camera/index.ts | 1 + packages/camera/package.json | 23 + .../camera/src/GetRoomCameraWidgetManager.ts | 5 + packages/camera/src/RoomCameraWidgetEffect.ts | 60 + .../camera/src/RoomCameraWidgetManager.ts | 103 + .../src/RoomCameraWidgetSelectedEffect.ts | 23 + packages/camera/src/index.ts | 4 + packages/camera/tsconfig.json | 31 + packages/communication/.eslintrc.json | 3 + packages/communication/.gitignore | 51 + packages/communication/index.ts | 1 + packages/communication/package.json | 21 + .../communication/src/CommunicationManager.ts | 97 + .../communication/src/GetCommunication.ts | 5 + packages/communication/src/NitroMessages.ts | 1179 ++++++ .../communication/src/SocketConnection.ts | 261 ++ packages/communication/src/codec/Byte.ts | 14 + packages/communication/src/codec/Short.ts | 14 + .../src/codec/evawire/EvaWireDataWrapper.ts | 78 + .../src/codec/evawire/EvaWireFormat.ts | 89 + .../communication/src/codec/evawire/index.ts | 2 + packages/communication/src/codec/index.ts | 3 + packages/communication/src/index.ts | 235 ++ .../src/messages/MessageClassManager.ts | 128 + .../src/messages/incoming/IncomingHeader.ts | 473 +++ .../advertisement/InterstitialMessageEvent.ts | 16 + .../advertisement/RoomAdErrorEvent.ts | 16 + .../messages/incoming/advertisement/index.ts | 2 + .../AvailabilityStatusMessageEvent.ts | 16 + .../AvailabilityTimeMessageEvent.ts | 16 + .../availability/HotelClosedAndOpensEvent.ts | 16 + .../HotelClosesAndWillOpenAtEvent.ts | 16 + .../HotelWillCloseInMinutesEvent.ts | 16 + .../MaintenanceStatusMessageEvent.ts | 16 + .../messages/incoming/availability/index.ts | 6 + .../ChangeUserNameResultMessageEvent.ts | 25 + .../avatar/CheckUserNameResultMessageEvent.ts | 16 + .../incoming/avatar/FigureUpdateEvent.ts | 16 + .../incoming/avatar/WardrobeMessageEvent.ts | 16 + .../src/messages/incoming/avatar/index.ts | 4 + .../incoming/bots/BotAddedToInventoryEvent.ts | 16 + .../incoming/bots/BotInventoryMessageEvent.ts | 16 + .../incoming/bots/BotReceivedMessageEvent.ts | 16 + .../bots/BotRemovedFromInventoryEvent.ts | 16 + .../src/messages/incoming/bots/index.ts | 4 + .../callforhelp/CfhSanctionMessageEvent.ts | 16 + .../callforhelp/CfhTopicsInitEvent.ts | 16 + .../callforhelp/SanctionStatusEvent.ts | 16 + .../messages/incoming/callforhelp/index.ts | 3 + .../camera/CameraPublishStatusMessageEvent.ts | 16 + .../camera/CameraPurchaseOKMessageEvent.ts | 16 + .../camera/CameraSnapshotMessageEvent.ts | 16 + .../camera/CameraStorageUrlMessageEvent.ts | 16 + .../camera/CompetitionStatusMessageEvent.ts | 16 + .../incoming/camera/InitCameraMessageEvent.ts | 16 + .../camera/ThumbnailStatusMessageEvent.ts | 16 + .../src/messages/incoming/camera/index.ts | 7 + .../CampaignCalendarDataMessageEvent.ts | 16 + .../CampaignCalendarDoorOpenedMessageEvent.ts | 16 + .../src/messages/incoming/campaign/index.ts | 2 + .../catalog/BonusRareInfoMessageEvent.ts | 16 + .../BuildersClubFurniCountMessageEvent.ts | 16 + ...ldersClubSubscriptionStatusMessageEvent.ts | 16 + .../BundleDiscountRulesetMessageEvent.ts | 16 + .../catalog/CatalogPageExpirationEvent.ts | 16 + .../catalog/CatalogPageMessageEvent.ts | 16 + ...talogPageWithEarliestExpiryMessageEvent.ts | 16 + .../incoming/catalog/CatalogPagesListEvent.ts | 16 + .../catalog/CatalogPublishedMessageEvent.ts | 16 + .../incoming/catalog/ClubGiftInfoEvent.ts | 16 + .../incoming/catalog/ClubGiftSelectedEvent.ts | 16 + .../DirectSMSClubBuyAvailableMessageEvent.ts | 16 + .../catalog/FireworkChargeDataEvent.ts | 16 + .../catalog/GiftReceiverNotFoundEvent.ts | 16 + .../catalog/GiftWrappingConfigurationEvent.ts | 16 + .../HabboClubExtendOfferMessageEvent.ts | 16 + .../catalog/HabboClubOffersMessageEvent.ts | 16 + .../catalog/IsOfferGiftableMessageEvent.ts | 16 + .../catalog/LimitedEditionSoldOutEvent.ts | 16 + .../LimitedOfferAppearingNextMessageEvent.ts | 16 + .../catalog/NotEnoughBalanceMessageEvent.ts | 16 + .../incoming/catalog/ProductOfferEvent.ts | 16 + .../catalog/PurchaseErrorMessageEvent.ts | 16 + .../catalog/PurchaseNotAllowedMessageEvent.ts | 16 + .../catalog/PurchaseOKMessageEvent.ts | 16 + .../catalog/RoomAdPurchaseInfoEvent.ts | 16 + .../SeasonalCalendarDailyOfferMessageEvent.ts | 16 + .../SellablePetPalettesMessageEvent.ts | 16 + .../incoming/catalog/TargetedOfferEvent.ts | 16 + .../catalog/TargetedOfferNotFoundEvent.ts | 16 + .../catalog/VoucherRedeemErrorMessageEvent.ts | 16 + .../catalog/VoucherRedeemOkMessageEvent.ts | 16 + .../src/messages/incoming/catalog/index.ts | 32 + .../incoming/client/ClientPingEvent.ts | 16 + .../src/messages/incoming/client/index.ts | 1 + .../CompetitionEntrySubmitResultEvent.ts | 16 + .../CompetitionVotingInfoMessageEvent.ts | 16 + .../CurrentTimingCodeMessageEvent.ts | 16 + .../IsUserPartOfCompetitionMessageEvent.ts | 16 + .../NoOwnedRoomsAlertMessageEvent.ts | 16 + .../competition/SecondsUntilMessageEvent.ts | 16 + .../messages/incoming/competition/index.ts | 6 + .../crafting/CraftableProductsEvent.ts | 16 + .../incoming/crafting/CraftingRecipeEvent.ts | 16 + .../crafting/CraftingRecipesAvailableEvent.ts | 16 + .../incoming/crafting/CraftingResultEvent.ts | 16 + .../src/messages/incoming/crafting/index.ts | 4 + .../incoming/desktop/DesktopViewEvent.ts | 16 + .../src/messages/incoming/desktop/index.ts | 1 + .../friendlist/AcceptFriendResultEvent.ts | 16 + .../FindFriendsProcessResultEvent.ts | 16 + .../friendlist/FollowFriendFailedEvent.ts | 16 + .../friendlist/FriendListFragmentEvent.ts | 16 + .../friendlist/FriendListUpdateEvent.ts | 16 + .../friendlist/FriendNotificationEvent.ts | 16 + .../friendlist/FriendRequestsEvent.ts | 16 + .../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 + .../src/messages/incoming/friendlist/index.ts | 17 + .../Game2AccountGameStatusMessageEvent.ts | 16 + .../Game2GameDirectoryStatusMessageEvent.ts | 16 + .../Game2InArenaQueueMessageEvent.ts | 16 + .../Game2JoiningGameFailedMessageEvent.ts | 16 + .../Game2StartingGameFailedMessageEvent.ts | 16 + .../directory/Game2StopCounterMessageEvent.ts | 16 + .../Game2UserLeftGameMessageEvent.ts | 16 + .../messages/incoming/game/directory/index.ts | 7 + .../src/messages/incoming/game/index.ts | 3 + ...ievementResolutionCompletedMessageEvent.ts | 16 + ...hievementResolutionProgressMessageEvent.ts | 16 + .../AchievementResolutionsMessageEvent.ts | 16 + .../lobby/GameAchievementsMessageEvent.ts | 16 + .../game/lobby/GameInviteMessageEvent.ts | 16 + .../game/lobby/GameListMessageEvent.ts | 16 + .../game/lobby/GameStatusMessageEvent.ts | 16 + .../game/lobby/JoinedQueueMessageEvent.ts | 16 + .../lobby/JoiningQueueFailedMessageEvent.ts | 16 + .../game/lobby/LeftQueueMessageEvent.ts | 16 + .../game/lobby/LoadGameMessageEvent.ts | 16 + .../incoming/game/lobby/LoadGameUrlEvent.ts | 16 + .../game/lobby/UnloadGameMessageEvent.ts | 16 + .../lobby/UserGameAchievementsMessageEvent.ts | 16 + .../src/messages/incoming/game/lobby/index.ts | 14 + .../Game2WeeklyFriendsLeaderboardEvent.ts | 16 + .../game/score/Game2WeeklyLeaderboardEvent.ts | 16 + ...eeklyCompetitiveFriendsLeaderboardEvent.ts | 16 + .../WeeklyCompetitiveLeaderboardEvent.ts | 16 + .../game/score/WeeklyGameRewardEvent.ts | 16 + .../score/WeeklyGameRewardWinnersEvent.ts | 16 + .../src/messages/incoming/game/score/index.ts | 6 + .../incoming/generic/GenericErrorEvent.ts | 16 + .../src/messages/incoming/generic/index.ts | 1 + .../gifts/PhoneCollectionStateMessageEvent.ts | 16 + .../gifts/TryPhoneNumberResultMessageEvent.ts | 16 + .../TryVerificationCodeResultMessageEvent.ts | 16 + .../src/messages/incoming/gifts/index.ts | 3 + .../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/GroupPurchasedEvent.ts | 16 + .../incoming/group/GroupSettingsEvent.ts | 16 + .../HabboGroupDeactivatedMessageEvent.ts | 16 + .../src/messages/incoming/group/index.ts | 8 + .../groupforums/ForumDataMessageEvent.ts | 16 + .../groupforums/ForumsListMessageEvent.ts | 16 + .../groupforums/GuildForumThreadsEvent.ts | 16 + .../groupforums/PostMessageMessageEvent.ts | 16 + .../groupforums/PostThreadMessageEvent.ts | 16 + .../groupforums/ThreadMessagesMessageEvent.ts | 16 + .../UnreadForumsCountMessageEvent.ts | 16 + .../groupforums/UpdateMessageMessageEvent.ts | 16 + .../groupforums/UpdateThreadMessageEvent.ts | 16 + .../messages/incoming/groupforums/index.ts | 9 + .../handshake/CompleteDiffieHandshakeEvent.ts | 16 + .../handshake/DisconnectReasonEnum.ts | 46 + .../handshake/DisconnectReasonEvent.ts | 33 + .../handshake/IdentityAccountsEvent.ts | 16 + .../handshake/InitDiffieHandshakeEvent.ts | 16 + .../handshake/NoobnessLevelMessageEvent.ts | 16 + .../src/messages/incoming/handshake/index.ts | 6 + .../CallForHelpDisabledNotifyMessageEvent.ts | 16 + ...lForHelpPendingCallsDeletedMessageEvent.ts | 16 + .../CallForHelpPendingCallsMessageEvent.ts | 16 + .../help/CallForHelpReplyMessageEvent.ts | 16 + .../help/CallForHelpResultMessageEvent.ts | 16 + .../ChatReviewSessionDetachedMessageEvent.ts | 16 + ...ReviewSessionOfferedToGuideMessageEvent.ts | 16 + .../ChatReviewSessionResultsMessageEvent.ts | 16 + .../ChatReviewSessionStartedMessageEvent.ts | 16 + ...atReviewSessionVotingStatusMessageEvent.ts | 16 + .../help/GuideOnDutyStatusMessageEvent.ts | 16 + .../help/GuideReportingStatusMessageEvent.ts | 16 + .../help/GuideSessionAttachedMessageEvent.ts | 16 + .../help/GuideSessionDetachedMessageEvent.ts | 16 + .../help/GuideSessionEndedMessageEvent.ts | 16 + .../help/GuideSessionErrorMessageEvent.ts | 16 + ...deSessionInvitedToGuideRoomMessageEvent.ts | 16 + .../help/GuideSessionMessageMessageEvent.ts | 16 + ...GuideSessionPartnerIsTypingMessageEvent.ts | 16 + .../GuideSessionRequesterRoomMessageEvent.ts | 16 + .../help/GuideSessionStartedMessageEvent.ts | 16 + .../GuideTicketCreationResultMessageEvent.ts | 16 + .../help/GuideTicketResolutionMessageEvent.ts | 16 + .../help/HotelMergeNameChangeEvent.ts | 16 + .../IssueCloseNotificationMessageEvent.ts | 16 + .../incoming/help/QuizDataMessageEvent.ts | 16 + .../incoming/help/QuizResultsMessageEvent.ts | 16 + .../src/messages/incoming/help/index.ts | 27 + .../src/messages/incoming/index.ts | 76 + .../achievements/AchievementEvent.ts | 16 + .../achievements/AchievementsEvent.ts | 16 + .../achievements/AchievementsScoreEvent.ts | 16 + .../incoming/inventory/achievements/index.ts | 3 + .../AvatarEffectActivatedEvent.ts | 16 + .../avatareffect/AvatarEffectAddedEvent.ts | 16 + .../avatareffect/AvatarEffectExpiredEvent.ts | 16 + .../avatareffect/AvatarEffectSelectedEvent.ts | 16 + .../avatareffect/AvatarEffectsEvent.ts | 16 + .../incoming/inventory/avatareffect/index.ts | 5 + .../inventory/badges/BadgePointLimitsEvent.ts | 16 + .../inventory/badges/BadgeReceivedEvent.ts | 16 + .../incoming/inventory/badges/BadgesEvent.ts | 16 + .../badges/IsBadgeRequestFulfilledEvent.ts | 16 + .../incoming/inventory/badges/index.ts | 4 + .../clothes/FigureSetIdsMessageEvent.ts | 16 + .../incoming/inventory/clothes/_Str_16135.ts | 16 + .../incoming/inventory/clothes/_Str_17532.ts | 16 + .../incoming/inventory/clothes/index.ts | 3 + .../furni/FurnitureListAddOrUpdateEvent.ts | 16 + .../inventory/furni/FurnitureListEvent.ts | 16 + .../furni/FurnitureListInvalidateEvent.ts | 16 + .../furni/FurnitureListRemovedEvent.ts | 16 + .../furni/FurniturePostItPlacedEvent.ts | 16 + .../furni/gifts/PresentOpenedMessageEvent.ts | 16 + .../incoming/inventory/furni/gifts/index.ts | 1 + .../incoming/inventory/furni/index.ts | 6 + .../src/messages/incoming/inventory/index.ts | 8 + .../pets/ConfirmBreedingRequestEvent.ts | 16 + .../pets/ConfirmBreedingResultEvent.ts | 16 + .../pets/GoToBreedingNestFailureEvent.ts | 16 + .../pets/NestBreedingSuccessEvent.ts | 16 + .../pets/PetAddedToInventoryEvent.ts | 16 + .../inventory/pets/PetInventoryEvent.ts | 16 + .../inventory/pets/PetReceivedMessageEvent.ts | 16 + .../pets/PetRemovedFromInventoryEvent.ts | 16 + .../messages/incoming/inventory/pets/index.ts | 8 + .../inventory/trading/TradingAcceptEvent.ts | 26 + .../inventory/trading/TradingCloseEvent.ts | 21 + .../trading/TradingCompletedEvent.ts | 16 + .../trading/TradingConfirmationEvent.ts | 16 + .../inventory/trading/TradingListItemEvent.ts | 56 + .../trading/TradingNoSuchItemEvent.ts | 16 + .../inventory/trading/TradingNotOpenEvent.ts | 16 + .../inventory/trading/TradingOpenEvent.ts | 36 + .../trading/TradingOpenFailedEvent.ts | 16 + .../trading/TradingOtherNotAllowedEvent.ts | 16 + .../trading/TradingYouAreNotAllowedEvent.ts | 16 + .../incoming/inventory/trading/index.ts | 11 + .../landingview/PromoArticlesMessageEvent.ts | 16 + .../messages/incoming/landingview/index.ts | 2 + .../votes/CommunityGoalVoteMessageEvent.ts | 16 + .../incoming/landingview/votes/index.ts | 1 + .../MarketplaceBuyOfferResultEvent.ts | 17 + .../MarketplaceCanMakeOfferResult.ts | 17 + .../MarketplaceCancelOfferResultEvent.ts | 16 + .../MarketplaceConfigurationEvent.ts | 16 + .../marketplace/MarketplaceItemStatsEvent.ts | 16 + .../marketplace/MarketplaceMakeOfferResult.ts | 17 + .../marketplace/MarketplaceOffersEvent.ts | 16 + .../marketplace/MarketplaceOwnOffersEvent.ts | 16 + .../messages/incoming/marketplace/index.ts | 8 + .../incoming/moderation/CfhChatlogEvent.ts | 16 + .../moderation/IssueDeletedMessageEvent.ts | 16 + .../moderation/IssueInfoMessageEvent.ts | 16 + .../moderation/IssuePickFailedMessageEvent.ts | 16 + .../ModeratorActionResultMessageEvent.ts | 16 + .../moderation/ModeratorCautionEvent.ts | 16 + .../moderation/ModeratorInitMessageEvent.ts | 16 + .../moderation/ModeratorMessageEvent.ts | 16 + .../moderation/ModeratorRoomInfoEvent.ts | 16 + .../ModeratorToolPreferencesEvent.ts | 16 + .../moderation/ModeratorUserInfoEvent.ts | 16 + .../incoming/moderation/RoomChatlogEvent.ts | 16 + .../incoming/moderation/RoomVisitsEvent.ts | 16 + .../moderation/UserBannedMessageEvent.ts | 16 + .../incoming/moderation/UserChatlogEvent.ts | 16 + .../src/messages/incoming/moderation/index.ts | 15 + .../CancelMysteryBoxWaitMessageEvent.ts | 16 + .../GotMysteryBoxPrizeMessageEvent.ts | 16 + .../mysterybox/MysteryBoxKeysEvent.ts | 16 + .../ShowMysteryBoxWaitMessageEvent.ts | 16 + .../src/messages/incoming/mysterybox/index.ts | 4 + .../incoming/navigator/CanCreateRoomEvent.ts | 16 + .../navigator/CanCreateRoomEventEvent.ts | 16 + .../CategoriesWithVisitorCountEvent.ts | 16 + .../CompetitionRoomsDataMessageEvent.ts | 16 + .../navigator/ConvertedRoomIdEvent.ts | 16 + .../navigator/DoorbellMessageEvent.ts | 21 + .../navigator/FavouriteChangedEvent.ts | 16 + .../incoming/navigator/FavouritesEvent.ts | 16 + .../navigator/FlatAccessDeniedMessageEvent.ts | 16 + .../incoming/navigator/FlatCreatedEvent.ts | 16 + .../navigator/GetGuestRoomResultEvent.ts | 16 + .../navigator/GuestRoomSearchResultEvent.ts | 16 + .../navigator/NavigatorCollapsedEvent.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 + .../navigator/PopularRoomTagsResultEvent.ts | 16 + .../navigator/RoomEventCancelEvent.ts | 16 + .../incoming/navigator/RoomEventEvent.ts | 16 + .../RoomFilterSettingsMessageEvent.ts | 16 + .../navigator/RoomSettingsUpdatedEvent.ts | 16 + .../RoomThumbnailUpdateResultEvent.ts | 16 + .../incoming/navigator/UserEventCatsEvent.ts | 16 + .../incoming/navigator/UserFlatCatsEvent.ts | 16 + .../src/messages/incoming/navigator/index.ts | 28 + .../AchievementNotificationMessageEvent.ts | 16 + .../ActivityPointNotificationMessageEvent.ts | 16 + .../incoming/notifications/BotErrorEvent.ts | 16 + .../ClubGiftNotificationEvent.ts | 16 + .../notifications/ConnectionErrorEvent.ts | 16 + .../ElementPointerMessageEvent.ts | 16 + .../HabboBroadcastMessageEvent.ts | 16 + .../notifications/HotelWillShutdownEvent.ts | 16 + .../InfoFeedEnableMessageEvent.ts | 16 + .../notifications/MOTDNotificationEvent.ts | 16 + .../NotificationDialogMessageEvent.ts | 16 + .../OfferRewardDeliveredMessageEvent.ts | 16 + .../PetLevelNotificationEvent.ts | 16 + .../notifications/PetPlacingErrorEvent.ts | 16 + .../RestoreClientMessageEvent.ts | 16 + .../notifications/SimpleAlertMessageEvent.ts | 16 + .../notifications/UnseenItemsEvent.ts | 16 + .../messages/incoming/notifications/index.ts | 17 + .../incoming/nux/NewUserExperienceGift.ts | 37 + .../NewUserExperienceGiftOfferMessageEvent.ts | 16 + .../nux/NewUserExperienceGiftOptions.ts | 40 + .../nux/NewUserExperienceNotCompleteEvent.ts | 16 + .../src/messages/incoming/nux/ProductOffer.ts | 28 + .../src/messages/incoming/nux/index.ts | 5 + .../perk/PerkAllowancesMessageEvent.ts | 16 + .../src/messages/incoming/perk/index.ts | 1 + .../OpenPetPackageRequestedMessageEvent.ts | 16 + .../pet/OpenPetPackageResultMessageEvent.ts | 16 + .../pet/PetLevelUpdateMessageEvent.ts | 16 + .../pet/PetScratchFailedMessageEvent.ts | 16 + .../pet/PetTrainingPanelMessageEvent.ts | 16 + .../pet/breeding/PetBreedingMessageEvent.ts | 16 + .../messages/incoming/pet/breeding/index.ts | 1 + .../src/messages/incoming/pet/index.ts | 6 + .../incoming/poll/PollContentsEvent.ts | 16 + .../messages/incoming/poll/PollErrorEvent.ts | 16 + .../messages/incoming/poll/PollOfferEvent.ts | 16 + .../incoming/poll/QuestionAnsweredEvent.ts | 16 + .../messages/incoming/poll/QuestionEvent.ts | 16 + .../incoming/poll/QuestionFinishedEvent.ts | 16 + .../incoming/poll/RoomPollResultEvent.ts | 16 + .../incoming/poll/StartRoomPollEvent.ts | 16 + .../src/messages/incoming/poll/index.ts | 8 + .../CommunityGoalEarnedPrizesMessageEvent.ts | 16 + .../CommunityGoalHallOfFameMessageEvent.ts | 16 + .../CommunityGoalProgressMessageEvent.ts | 16 + ...ConcurrentUsersGoalProgressMessageEvent.ts | 16 + .../incoming/quest/EpicPopupMessageEvent.ts | 16 + .../quest/QuestCancelledMessageEvent.ts | 16 + .../quest/QuestCompletedMessageEvent.ts | 16 + .../incoming/quest/QuestDailyMessageEvent.ts | 16 + .../incoming/quest/QuestMessageEvent.ts | 16 + .../incoming/quest/QuestsMessageEvent.ts | 16 + .../quest/SeasonalQuestsMessageEvent.ts | 16 + .../src/messages/incoming/quest/index.ts | 11 + .../recycler/RecyclerFinishedMessageEvent.ts | 19 + .../recycler/RecyclerStatusMessageEvent.ts | 20 + .../src/messages/incoming/recycler/index.ts | 2 + .../room/access/RoomEnterErrorEvent.ts | 16 + .../incoming/room/access/RoomEnterEvent.ts | 16 + .../incoming/room/access/RoomForwardEvent.ts | 16 + .../doorbell/RoomDoorbellAcceptedEvent.ts | 16 + .../incoming/room/access/doorbell/index.ts | 1 + .../messages/incoming/room/access/index.ts | 5 + .../access/rights/RoomRightsClearEvent.ts | 16 + .../room/access/rights/RoomRightsEvent.ts | 16 + .../access/rights/RoomRightsOwnerEvent.ts | 16 + .../incoming/room/access/rights/index.ts | 3 + .../room/bots/BotCommandConfigurationEvent.ts | 16 + .../room/bots/BotForceOpenContextMenuEvent.ts | 16 + .../room/bots/BotSkillListUpdateEvent.ts | 16 + .../src/messages/incoming/room/bots/index.ts | 3 + .../room/data/RoomChatSettingsEvent.ts | 16 + .../room/data/RoomEntryInfoMessageEvent.ts | 16 + .../incoming/room/data/RoomScoreEvent.ts | 16 + .../src/messages/incoming/room/data/index.ts | 3 + .../FavoriteMembershipUpdateMessageEvent.ts | 16 + .../room/engine/ObjectsDataUpdateEvent.ts | 16 + .../room/engine/ObjectsRollingEvent.ts | 16 + .../messages/incoming/room/engine/index.ts | 3 + .../CustomUserNotificationMessageEvent.ts | 16 + .../room/furniture/DiceValueMessageEvent.ts | 16 + .../FurniRentOrBuyoutOfferMessageEvent.ts | 16 + .../room/furniture/FurnitureAliasesEvent.ts | 16 + .../room/furniture/FurnitureDataEvent.ts | 16 + .../furniture/FurnitureStackHeightEvent.ts | 16 + .../GroupFurniContextMenuInfoMessageEvent.ts | 16 + .../furniture/ItemDataUpdateMessageEvent.ts | 16 + .../furniture/LoveLockFurniFinishedEvent.ts | 16 + .../LoveLockFurniFriendConfirmedEvent.ts | 16 + .../room/furniture/LoveLockFurniStartEvent.ts | 16 + .../furniture/OneWayDoorStatusMessageEvent.ts | 16 + .../RentableSpaceRentFailedMessageEvent.ts | 16 + .../RentableSpaceRentOkMessageEvent.ts | 16 + .../RentableSpaceStatusMessageEvent.ts | 16 + .../RequestSpamWallPostItMessageEvent.ts | 16 + .../RoomDimmerPresetsMessageEvent.ts | 16 + .../RoomMessageNotificationMessageEvent.ts | 16 + .../room/furniture/WelcomeGiftStatusEvent.ts | 16 + .../furniture/floor/FurnitureFloorAddEvent.ts | 16 + .../furniture/floor/FurnitureFloorEvent.ts | 16 + .../floor/FurnitureFloorRemoveEvent.ts | 16 + .../floor/FurnitureFloorUpdateEvent.ts | 16 + .../incoming/room/furniture/floor/index.ts | 4 + .../messages/incoming/room/furniture/index.ts | 22 + .../furniture/wall/FurnitureWallAddEvent.ts | 16 + .../room/furniture/wall/FurnitureWallEvent.ts | 16 + .../wall/FurnitureWallRemoveEvent.ts | 16 + .../wall/FurnitureWallUpdateEvent.ts | 16 + .../incoming/room/furniture/wall/index.ts | 4 + .../YoutubeControlVideoMessageEvent.ts | 16 + .../youtube/YoutubeDisplayPlaylistsEvent.ts | 16 + .../YoutubeDisplayVideoMessageEvent.ts | 16 + .../incoming/room/furniture/youtube/index.ts | 3 + .../src/messages/incoming/room/index.ts | 15 + .../room/mapping/FloorHeightMapEvent.ts | 16 + .../room/mapping/RoomEntryTileMessageEvent.ts | 16 + .../room/mapping/RoomHeightMapEvent.ts | 16 + .../room/mapping/RoomHeightMapUpdateEvent.ts | 16 + .../mapping/RoomOccupiedTilesMessageEvent.ts | 16 + .../incoming/room/mapping/RoomPaintEvent.ts | 16 + .../room/mapping/RoomReadyMessageEvent.ts | 16 + .../mapping/RoomVisualizationSettingsEvent.ts | 16 + .../messages/incoming/room/mapping/index.ts | 8 + .../room/pet/PetBreedingResultEvent.ts | 16 + .../incoming/room/pet/PetExperienceEvent.ts | 16 + .../incoming/room/pet/PetFigureUpdateEvent.ts | 16 + .../incoming/room/pet/PetInfoEvent.ts | 16 + .../incoming/room/pet/PetStatusUpdateEvent.ts | 16 + .../src/messages/incoming/room/pet/index.ts | 5 + .../room/session/YouArePlayingGameEvent.ts | 16 + .../session/YouAreSpectatorMessageEvent.ts | 16 + .../messages/incoming/room/session/index.ts | 2 + .../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 + .../messages/incoming/room/unit/chat/index.ts | 6 + .../src/messages/incoming/room/unit/index.ts | 12 + .../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 + .../src/messages/incoming/roomevents/index.ts | 7 + .../roomsettings/BannedUsersFromRoomEvent.ts | 16 + .../roomsettings/FlatControllerAddedEvent.ts | 16 + .../FlatControllerRemovedEvent.ts | 16 + .../roomsettings/FlatControllersEvent.ts | 16 + .../roomsettings/MuteAllInRoomEvent.ts | 16 + .../incoming/roomsettings/NoSuchFlatEvent.ts | 16 + .../roomsettings/RoomSettingsDataEvent.ts | 16 + .../roomsettings/RoomSettingsErrorEvent.ts | 16 + .../RoomSettingsSaveErrorEvent.ts | 16 + .../roomsettings/RoomSettingsSavedEvent.ts | 16 + .../ShowEnforceRoomCategoryDialogEvent.ts | 16 + .../roomsettings/UserUnbannedFromRoomEvent.ts | 16 + .../messages/incoming/roomsettings/index.ts | 12 + .../incoming/security/AuthenticatedEvent.ts | 16 + .../src/messages/incoming/security/index.ts | 1 + .../sound/JukeboxPlayListFullMessageEvent.ts | 16 + .../sound/JukeboxSongDisksMessageEvent.ts | 16 + .../incoming/sound/NowPlayingMessageEvent.ts | 16 + .../sound/OfficialSongIdMessageEvent.ts | 16 + .../incoming/sound/PlayListMessageEvent.ts | 16 + .../sound/PlayListSongAddedMessageEvent.ts | 16 + .../sound/TraxSongInfoMessageEvent.ts | 16 + .../UserSongDisksInventoryMessageEvent.ts | 16 + .../src/messages/incoming/sound/index.ts | 8 + .../incoming/talent/TalentLevelUpEvent.ts | 16 + .../talent/TalentTrackLevelMessageEvent.ts | 16 + .../talent/TalentTrackMessageEvent.ts | 16 + .../src/messages/incoming/talent/index.ts | 3 + ...countSafetyLockStatusChangeMessageEvent.ts | 16 + .../incoming/user/ApproveNameMessageEvent.ts | 16 + .../incoming/user/ChangeEmailResultEvent.ts | 16 + .../incoming/user/EmailStatusResultEvent.ts | 16 + .../ExtendedProfileChangedMessageEvent.ts | 16 + .../user/GroupDetailsChangedMessageEvent.ts | 16 + .../GroupMembershipRequestedMessageEvent.ts | 16 + .../user/GuildEditFailedMessageEvent.ts | 16 + .../user/GuildMemberMgmtFailedMessageEvent.ts | 16 + .../user/GuildMembershipsMessageEvent.ts | 16 + .../user/HabboGroupBadgesMessageEvent.ts | 16 + .../user/HabboGroupJoinFailedMessageEvent.ts | 16 + .../incoming/user/IgnoreResultEvent.ts | 16 + .../incoming/user/IgnoredUsersEvent.ts | 16 + .../incoming/user/InClientLinkEvent.ts | 16 + .../src/messages/incoming/user/MemberData.ts | 70 + .../user/PetRespectNoficationEvent.ts | 16 + .../user/PetSupplementedNotificationEvent.ts | 16 + .../incoming/user/RespectReceivedEvent.ts | 16 + .../user/ScrSendKickbackInfoMessageEvent.ts | 16 + .../user/WelcomeGiftChangeEmailResultEvent.ts | 16 + .../user/access/UserPermissionsEvent.ts | 16 + .../messages/incoming/user/access/index.ts | 1 + .../user/data/RelationshipStatusInfoEvent.ts | 16 + .../user/data/UserCurrentBadgesEvent.ts | 16 + .../incoming/user/data/UserInfoEvent.ts | 16 + .../user/data/UserNameChangeMessageEvent.ts | 16 + .../incoming/user/data/UserProfileEvent.ts | 16 + .../incoming/user/data/UserSettingsEvent.ts | 16 + .../user/data/UserTagsMessageEvent.ts | 16 + .../src/messages/incoming/user/data/index.ts | 7 + .../src/messages/incoming/user/index.ts | 27 + .../inventory/currency/UserCreditsEvent.ts | 16 + .../inventory/currency/UserCurrencyEvent.ts | 16 + .../incoming/user/inventory/currency/index.ts | 2 + .../messages/incoming/user/inventory/index.ts | 2 + .../subscription/UserSubscriptionEvent.ts | 16 + .../user/inventory/subscription/index.ts | 1 + .../user/wardrobe/UserWardrobePageEvent.ts | 16 + .../messages/incoming/user/wardrobe/index.ts | 1 + .../UserClassificationMessageEvent.ts | 16 + .../incoming/userclassification/index.ts | 1 + packages/communication/src/messages/index.ts | 4 + .../src/messages/outgoing/OutgoingHeader.ts | 471 +++ .../GetInterstitialMessageComposer.ts | 21 + .../InterstitialShownMessageComposer.ts | 21 + .../RequestAchievementsMessageComposer.ts | 21 + .../messages/outgoing/advertisement/index.ts | 3 + .../avatar/ChangeUserNameMessageComposer.ts | 21 + .../avatar/CheckUserNameMessageComposer.ts | 21 + .../avatar/GetWardrobeMessageComposer.ts | 21 + .../SaveWardrobeOutfitMessageComposer.ts | 21 + .../src/messages/outgoing/avatar/index.ts | 4 + .../camera/PhotoCompetitionMessageComposer.ts | 21 + .../camera/PublishPhotoMessageComposer.ts | 21 + .../camera/PurchasePhotoMessageComposer.ts | 21 + .../camera/RenderRoomMessageComposer.ts | 43 + .../RenderRoomThumbnailMessageComposer.ts | 9 + .../RequestCameraConfigurationComposer.ts | 21 + .../src/messages/outgoing/camera/index.ts | 6 + ...OpenCampaignCalendarDoorAsStaffComposer.ts | 21 + .../OpenCampaignCalendarDoorComposer.ts | 21 + .../src/messages/outgoing/campaign/index.ts | 2 + ...uildersClubPlaceRoomItemMessageComposer.ts | 21 + ...uildersClubPlaceWallItemMessageComposer.ts | 21 + ...ldersClubQueryFurniCountMessageComposer.ts | 21 + .../GetBonusRareInfoMessageComposer.ts | 21 + .../GetBundleDiscountRulesetComposer.ts | 21 + .../catalog/GetCatalogIndexComposer.ts | 21 + .../catalog/GetCatalogPageComposer.ts | 21 + .../GetCatalogPageExpirationComposer.ts | 21 + ...etCatalogPageWithEarliestExpiryComposer.ts | 21 + .../outgoing/catalog/GetClubGiftInfo.ts | 21 + .../catalog/GetClubOffersMessageComposer.ts | 21 + .../GetDirectClubBuyAvailableComposer.ts | 21 + .../GetGiftWrappingConfigurationComposer.ts | 21 + ...HabboBasicMembershipExtendOfferComposer.ts | 21 + .../GetHabboClubExtendOfferMessageComposer.ts | 21 + .../catalog/GetIsOfferGiftableComposer.ts | 21 + .../GetLimitedOfferAppearingNextComposer.ts | 21 + .../catalog/GetNextTargetedOfferComposer.ts | 21 + .../catalog/GetProductOfferComposer.ts | 21 + .../catalog/GetRoomAdPurchaseInfoComposer.ts | 21 + .../GetSeasonalCalendarDailyOfferComposer.ts | 21 + .../catalog/GetSellablePetPalettesComposer.ts | 21 + .../catalog/GetTargetedOfferComposer.ts | 21 + ...rkCatalogNewAdditionsPageOpenedComposer.ts | 21 + ...urchaseBasicMembershipExtensionComposer.ts | 21 + .../PurchaseFromCatalogAsGiftComposer.ts | 21 + .../catalog/PurchaseFromCatalogComposer.ts | 21 + .../catalog/PurchaseRoomAdMessageComposer.ts | 21 + .../catalog/PurchaseTargetedOfferComposer.ts | 21 + .../PurchaseVipMembershipExtensionComposer.ts | 21 + .../catalog/RedeemVoucherMessageComposer.ts | 21 + .../RoomAdPurchaseInitiatedComposer.ts | 21 + .../catalog/SelectClubGiftComposer.ts | 21 + .../catalog/SetTargetedOfferStateComposer.ts | 21 + .../ShopTargetedOfferViewedComposer.ts | 21 + .../src/messages/outgoing/catalog/index.ts | 35 + ...orwardToACompetitionRoomMessageComposer.ts | 21 + ...orwardToASubmittableRoomMessageComposer.ts | 21 + ...dToRandomCompetitionRoomMessageComposer.ts | 21 + .../GetCurrentTimingCodeMessageComposer.ts | 21 + ...tIsUserPartOfCompetitionMessageComposer.ts | 21 + .../GetSecondsUntilMessageComposer.ts | 21 + .../RoomCompetitionInitMessageComposer.ts | 21 + .../SubmitRoomToCompetitionMessageComposer.ts | 26 + .../competition/VoteForRoomMessageComposer.ts | 21 + .../messages/outgoing/competition/index.ts | 9 + .../outgoing/crafting/CraftComposer.ts | 21 + .../outgoing/crafting/CraftSecretComposer.ts | 21 + .../crafting/GetCraftableProductsComposer.ts | 21 + .../crafting/GetCraftingRecipeComposer.ts | 21 + .../GetCraftingRecipesAvailableComposer.ts | 21 + .../src/messages/outgoing/crafting/index.ts | 5 + .../outgoing/desktop/DesktopViewComposer.ts | 21 + .../src/messages/outgoing/desktop/index.ts | 1 + .../FriendFurniConfirmLockMessageComposer.ts | 21 + .../messages/outgoing/friendfurni/index.ts | 1 + .../friendlist/AcceptFriendMessageComposer.ts | 21 + .../DeclineFriendMessageComposer.ts | 21 + .../FindNewFriendsMessageComposer.ts | 21 + .../friendlist/FollowFriendMessageComposer.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 + .../src/messages/outgoing/friendlist/index.ts | 14 + .../arena/Game2ExitGameMessageComposer.ts | 21 + .../arena/Game2GameChatMessageComposer.ts | 21 + .../Game2LoadStageReadyMessageComposer.ts | 21 + .../arena/Game2PlayAgainMessageComposer.ts | 21 + .../src/messages/outgoing/game/arena/index.ts | 4 + ...CheckGameDirectoryStatusMessageComposer.ts | 21 + ...ame2GetAccountGameStatusMessageComposer.ts | 21 + .../messages/outgoing/game/directory/index.ts | 2 + .../src/messages/outgoing/game/index.ts | 5 + ...2RequestFullStatusUpdateMessageComposer.ts | 21 + .../messages/outgoing/game/ingame/index.ts | 1 + .../lobby/AcceptGameInviteMessageComposer.ts | 21 + .../game/lobby/GameUnloadedMessageComposer.ts | 21 + .../GetGameAchievementsMessageComposer.ts | 21 + .../game/lobby/GetGameListMessageComposer.ts | 21 + .../lobby/GetGameStatusMessageComposer.ts | 21 + ...etResolutionAchievementsMessageComposer.ts | 21 + .../GetUserGameAchievementsMessageComposer.ts | 21 + .../game/lobby/JoinQueueMessageComposer.ts | 21 + .../game/lobby/LeaveQueueMessageComposer.ts | 21 + ...setResolutionAchievementMessageComposer.ts | 21 + .../src/messages/outgoing/game/lobby/index.ts | 10 + ...ame2GetWeeklyFriendsLeaderboardComposer.ts | 21 + .../Game2GetWeeklyLeaderboardComposer.ts | 21 + .../game/score/GetWeeklyGameRewardComposer.ts | 21 + .../GetWeeklyGameRewardWinnersComposer.ts | 21 + .../src/messages/outgoing/game/score/index.ts | 4 + .../outgoing/gifts/GetGiftMessageComposer.ts | 23 + .../ResetPhoneNumberStateMessageComposer.ts | 21 + ...NumberVerificationStatusMessageComposer.ts | 23 + .../gifts/TryPhoneNumberMessageComposer.ts | 21 + .../gifts/VerifyCodeMessageComposer.ts | 21 + .../src/messages/outgoing/gifts/index.ts | 5 + ...oveAllMembershipRequestsMessageComposer.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 + .../outgoing/group/GroupFavoriteComposer.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 + .../outgoing/group/GroupUnfavoriteComposer.ts | 21 + .../src/messages/outgoing/group/index.ts | 21 + .../GetForumStatsMessageComposer.ts | 21 + .../GetForumsListMessageComposer.ts | 21 + .../groupforums/GetMessagesMessageComposer.ts | 21 + .../groupforums/GetThreadMessageComposer.ts | 21 + .../groupforums/GetThreadsMessageComposer.ts | 21 + .../GetUnreadForumsCountMessageComposer.ts | 21 + .../ModerateMessageMessageComposer.ts | 21 + .../ModerateThreadMessageComposer.ts | 21 + .../groupforums/PostMessageMessageComposer.ts | 21 + .../UpdateForumReadMarkerMessageComposer.ts | 33 + .../UpdateForumSettingsMessageComposer.ts | 21 + .../UpdateThreadMessageComposer.ts | 21 + .../messages/outgoing/groupforums/index.ts | 12 + .../AuthenticationMessageComposer.ts | 32 + .../handshake/ClientHelloMessageComposer.ts | 22 + .../CompleteDiffieHandshakeMessageComposer.ts | 21 + .../handshake/DisconnectMessageComposer.ts | 21 + .../handshake/InfoRetrieveMessageComposer.ts | 21 + .../InitDiffieHandshakeMessageComposer.ts | 21 + .../outgoing/handshake/PongMessageComposer.ts | 21 + .../handshake/SSOTicketMessageComposer.ts | 21 + .../handshake/UniqueIDMessageComposer.ts | 21 + .../handshake/VersionCheckMessageComposer.ts | 21 + .../src/messages/outgoing/handshake/index.ts | 10 + ...lForHelpFromForumMessageMessageComposer.ts | 21 + ...llForHelpFromForumThreadMessageComposer.ts | 21 + .../help/CallForHelpFromIMMessageComposer.ts | 21 + .../CallForHelpFromPhotoMessageComposer.ts | 21 + .../CallForHelpFromSelfieMessageComposer.ts | 21 + .../help/CallForHelpMessageComposer.ts | 21 + ...eviewGuideDecidesOnOfferMessageComposer.ts | 21 + .../ChatReviewGuideDetachedMessageComposer.ts | 21 + .../ChatReviewGuideVoteMessageComposer.ts | 21 + .../ChatReviewSessionCreateMessageComposer.ts | 21 + ...eletePendingCallsForHelpMessageComposer.ts | 21 + .../help/GetCfhStatusMessageComposer.ts | 21 + .../help/GetFaqCategoryMessageComposer.ts | 21 + .../help/GetFaqTextMessageComposer.ts | 21 + .../GetGuideReportingStatusMessageComposer.ts | 21 + .../GetPendingCallsForHelpMessageComposer.ts | 21 + .../outgoing/help/GetQuizQuestionsComposer.ts | 21 + .../help/GuideSessionCreateMessageComposer.ts | 21 + .../GuideSessionFeedbackMessageComposer.ts | 21 + ...eSessionGetRequesterRoomMessageComposer.ts | 21 + ...GuideSessionGuideDecidesMessageComposer.ts | 21 + ...deSessionInviteRequesterMessageComposer.ts | 21 + .../GuideSessionIsTypingMessageComposer.ts | 21 + .../GuideSessionMessageMessageComposer.ts | 21 + ...GuideSessionOnDutyUpdateMessageComposer.ts | 21 + .../help/GuideSessionReportMessageComposer.ts | 21 + ...eSessionRequesterCancelsMessageComposer.ts | 21 + .../GuideSessionResolvedMessageComposer.ts | 21 + .../outgoing/help/PostQuizAnswersComposer.ts | 21 + .../help/SearchFaqsMessageComposer.ts | 21 + .../src/messages/outgoing/help/index.ts | 30 + .../src/messages/outgoing/index.ts | 74 + .../AvatarEffectActivatedComposer.ts | 21 + .../AvatarEffectSelectedComposer.ts | 21 + .../outgoing/inventory/avatareffect/index.ts | 2 + .../badges/GetBadgePointLimitsComposer.ts | 21 + .../GetIsBadgeRequestFulfilledComposer.ts | 21 + .../inventory/badges/RequestABadgeComposer.ts | 21 + .../inventory/badges/RequestBadgesComposer.ts | 21 + .../badges/SetActivatedBadgesComposer.ts | 29 + .../outgoing/inventory/badges/index.ts | 5 + .../inventory/bots/GetBotInventoryComposer.ts | 21 + .../messages/outgoing/inventory/bots/index.ts | 1 + .../inventory/furni/FurnitureListComposer.ts | 21 + ...uestFurniInventoryWhenNotInRoomComposer.ts | 21 + .../outgoing/inventory/furni/index.ts | 2 + .../src/messages/outgoing/inventory/index.ts | 7 + .../pets/CancelPetBreedingComposer.ts | 21 + .../pets/ConfirmPetBreedingComposer.ts | 21 + .../inventory/pets/RequestPetsComposer.ts | 21 + .../messages/outgoing/inventory/pets/index.ts | 3 + .../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 + .../outgoing/inventory/trading/index.ts | 9 + .../unseen/UnseenResetCategoryComposer.ts | 21 + .../unseen/UnseenResetItemsComposer.ts | 21 + .../outgoing/inventory/unseen/index.ts | 2 + .../landingview/GetPromoArticlesComposer.ts | 21 + .../messages/outgoing/landingview/index.ts | 2 + .../votes/CommunityGoalVoteMessageComposer.ts | 21 + .../outgoing/landingview/votes/index.ts | 1 + .../BuyMarketplaceOfferMessageComposer.ts | 21 + .../BuyMarketplaceTokensMessageComposer.ts | 21 + .../CancelMarketplaceOfferMessageComposer.ts | 21 + .../GetMarketplaceCanMakeOfferComposer.ts | 21 + ...MarketplaceConfigurationMessageComposer.ts | 21 + .../GetMarketplaceItemStatsComposer.ts | 21 + .../GetMarketplaceOffersMessageComposer.ts | 21 + .../GetMarketplaceOwnOffersMessageComposer.ts | 21 + .../marketplace/MakeOfferMessageComposer.ts | 21 + ...mMarketplaceOfferCreditsMessageComposer.ts | 21 + .../messages/outgoing/marketplace/index.ts | 10 + .../CloseIssueDefaultActionMessageComposer.ts | 21 + .../moderation/CloseIssuesMessageComposer.ts | 25 + .../DefaultSanctionMessageComposer.ts | 26 + .../GetCfhChatlogMessageComposer.ts | 22 + .../GetModeratorRoomInfoMessageComposer.ts | 21 + .../GetModeratorUserInfoMessageComposer.ts | 21 + .../GetRoomChatlogMessageComposer.ts | 21 + .../GetRoomVisitsMessageComposer.ts | 21 + .../GetUserChatlogMessageComposer.ts | 21 + .../moderation/ModAlertMessageComposer.ts | 26 + .../moderation/ModBanMessageComposer.ts | 27 + .../moderation/ModKickMessageComposer.ts | 27 + .../moderation/ModMessageMessageComposer.ts | 30 + .../moderation/ModMuteMessageComposer.ts | 26 + .../moderation/ModToolPreferencesComposer.ts | 21 + .../moderation/ModToolSanctionComposer.ts | 21 + .../ModTradingLockMessageComposer.ts | 27 + .../moderation/ModerateRoomMessageComposer.ts | 21 + .../ModeratorActionMessageComposer.ts | 28 + .../moderation/PickIssuesMessageComposer.ts | 21 + .../ReleaseIssuesMessageComposer.ts | 21 + .../src/messages/outgoing/moderation/index.ts | 21 + ...ysteryBoxWaitingCanceledMessageComposer.ts | 21 + .../src/messages/outgoing/mysterybox/index.ts | 1 + .../AddFavouriteRoomMessageComposer.ts | 21 + .../navigator/CanCreateRoomMessageComposer.ts | 21 + .../navigator/CancelEventMessageComposer.ts | 21 + .../CompetitionRoomsSearchMessageComposer.ts | 21 + .../navigator/ConvertGlobalRoomIdComposer.ts | 21 + .../navigator/CreateFlatMessageComposer.ts | 21 + .../DeleteFavouriteRoomMessageComposer.ts | 21 + .../navigator/EditEventMessageComposer.ts | 21 + ...ardToARandomPromotedRoomMessageComposer.ts | 21 + .../ForwardToSomeRoomMessageComposer.ts | 21 + ...tCategoriesWithUserCountMessageComposer.ts | 21 + .../GetCustomRoomFilterMessageComposer.ts | 21 + .../navigator/GetGuestRoomMessageComposer.ts | 21 + .../GetOfficialRoomsMessageComposer.ts | 21 + .../GetPopularRoomTagsMessageComposer.ts | 21 + .../GetUserEventCatsMessageComposer.ts | 21 + .../GetUserFlatCatsMessageComposer.ts | 21 + .../GuildBaseSearchMessageComposer.ts | 21 + .../MyFavouriteRoomsSearchMessageComposer.ts | 21 + ...requentRoomHistorySearchMessageComposer.ts | 21 + .../MyFriendsRoomsSearchMessageComposer.ts | 21 + .../MyGuildBasesSearchMessageComposer.ts | 21 + .../MyRecommendedRoomsMessageComposer.ts | 21 + .../MyRoomHistorySearchMessageComposer.ts | 21 + .../MyRoomRightsSearchMessageComposer.ts | 21 + .../navigator/MyRoomsSearchMessageComposer.ts | 21 + .../NavigatorCategoryListModeComposer.ts | 21 + .../NavigatorDeleteSavedSearchComposer.ts | 21 + .../navigator/NavigatorInitComposer.ts | 21 + .../navigator/NavigatorSearchCloseComposer.ts | 21 + .../navigator/NavigatorSearchComposer.ts | 21 + .../navigator/NavigatorSearchOpenComposer.ts | 21 + .../navigator/NavigatorSearchSaveComposer.ts | 21 + .../NavigatorSettingsSaveComposer.ts | 21 + .../PopularRoomsSearchMessageComposer.ts | 21 + .../navigator/RateFlatMessageComposer.ts | 21 + .../RemoveOwnRoomRightsRoomMessageComposer.ts | 21 + .../RoomAdEventTabAdClickedComposer.ts | 21 + .../navigator/RoomAdEventTabViewedComposer.ts | 21 + .../navigator/RoomAdSearchMessageComposer.ts | 21 + .../RoomTextSearchMessageComposer.ts | 21 + ...sWhereMyFriendsAreSearchMessageComposer.ts | 21 + ...msWithHighestScoreSearchMessageComposer.ts | 21 + .../SetRoomSessionTagsMessageComposer.ts | 21 + .../ToggleStaffPickMessageComposer.ts | 21 + .../UpdateHomeRoomMessageComposer.ts | 21 + .../UpdateRoomFilterMessageComposer.ts | 21 + .../UpdateRoomThumbnailMessageComposer.ts | 21 + .../src/messages/outgoing/navigator/index.ts | 48 + .../nux/NewUserExperienceGetGiftsComposer.ts | 28 + .../nux/NewUserExperienceGetGiftsSelection.ts | 28 + .../NewUserExperienceScriptProceedComposer.ts | 21 + .../src/messages/outgoing/nux/index.ts | 3 + .../outgoing/pet/GetPetCommandsComposer.ts | 21 + .../messages/outgoing/pet/PetMountComposer.ts | 21 + .../outgoing/pet/PetRespectComposer.ts | 21 + .../outgoing/pet/PetSupplementComposer.ts | 21 + .../outgoing/pet/RemovePetSaddleComposer.ts | 21 + .../outgoing/pet/RequestPetInfoComposer.ts | 21 + .../outgoing/pet/TogglePetBreedingComposer.ts | 21 + .../outgoing/pet/TogglePetRidingComposer.ts | 21 + .../outgoing/pet/UsePetProductComposer.ts | 21 + .../src/messages/outgoing/pet/index.ts | 9 + .../outgoing/poll/PollAnswerComposer.ts | 21 + .../outgoing/poll/PollRejectComposer.ts | 21 + .../outgoing/poll/PollStartComposer.ts | 21 + .../poll/VotePollCounterMessageComposer.ts | 21 + .../src/messages/outgoing/poll/index.ts | 4 + .../quest/AcceptQuestMessageComposer.ts | 21 + .../quest/ActivateQuestMessageComposer.ts | 21 + .../quest/CancelQuestMessageComposer.ts | 21 + ...iendRequestQuestCompleteMessageComposer.ts | 21 + ...ommunityGoalEarnedPrizesMessageComposer.ts | 21 + ...tCommunityGoalHallOfFameMessageComposer.ts | 21 + ...GetCommunityGoalProgressMessageComposer.ts | 21 + ...currentUsersGoalProgressMessageComposer.ts | 21 + ...GetConcurrentUsersRewardMessageComposer.ts | 21 + .../quest/GetDailyQuestMessageComposer.ts | 21 + .../quest/GetQuestsMessageComposer.ts | 21 + .../GetSeasonalQuestsOnlyMessageComposer.ts | 21 + .../quest/OpenQuestTrackerMessageComposer.ts | 21 + ...RedeemCommunityGoalPrizeMessageComposer.ts | 21 + .../quest/RejectQuestMessageComposer.ts | 21 + .../quest/StartCampaignMessageComposer.ts | 21 + .../src/messages/outgoing/quest/index.ts | 16 + .../GetRecyclerStatusMessageComposer.ts | 21 + .../recycler/RecycleItemsMessageComposer.ts | 31 + .../src/messages/outgoing/recycler/index.ts | 2 + .../room/RedeemItemClothingComposer.ts | 21 + .../room/access/RoomDoorbellAccessComposer.ts | 21 + .../outgoing/room/access/RoomEnterComposer.ts | 21 + .../messages/outgoing/room/access/index.ts | 2 + .../action/RemoveAllRightsMessageComposer.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/RoomMuteUserComposer.ts | 21 + .../room/action/RoomTakeRightsComposer.ts | 21 + .../room/action/RoomUnbanUserComposer.ts | 21 + .../messages/outgoing/room/action/index.ts | 9 + .../bots/RequestBotConfigurationComposer.ts | 21 + .../src/messages/outgoing/room/bots/index.ts | 1 + .../room/data/RoomBannedUsersComposer.ts | 21 + .../room/data/RoomSettingsComposer.ts | 21 + .../room/data/RoomUsersWithRightsComposer.ts | 21 + .../room/data/SaveRoomSettingsComposer.ts | 81 + .../src/messages/outgoing/room/data/index.ts | 4 + .../outgoing/room/engine/BotPlaceComposer.ts | 21 + .../outgoing/room/engine/BotRemoveComposer.ts | 21 + .../room/engine/BotSkillSaveComposer.ts | 21 + .../engine/CompostPlantMessageComposer.ts | 9 + .../room/engine/GetItemDataComposer.ts | 21 + .../room/engine/HarvestPetMessageComposer.ts | 9 + .../room/engine/PetMessageComposer.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 + .../SetClothingChangeDataMessageComposer.ts | 21 + .../room/engine/SetItemDataMessageComposer.ts | 21 + .../engine/SetObjectDataMessageComposer.ts | 23 + .../messages/outgoing/room/engine/index.ts | 14 + .../AddSpamWallPostItMessageComposer.ts | 21 + .../ExtendRentOrBuyoutFurniMessageComposer.ts | 21 + ...endRentOrBuyoutStripItemMessageComposer.ts | 21 + .../furniture/FurnitureAliasesComposer.ts | 21 + .../furniture/FurnitureGroupInfoComposer.ts | 21 + .../room/furniture/FurniturePickupComposer.ts | 21 + .../room/furniture/FurniturePlaceComposer.ts | 39 + .../furniture/FurniturePlacePaintComposer.ts | 21 + .../furniture/FurniturePostItPlaceComposer.ts | 21 + .../GetRentOrBuyoutOfferMessageComposer.ts | 21 + .../OpenMysteryTrophyMessageComposer.ts | 21 + .../OpenPetPackageMessageComposer.ts | 21 + .../room/furniture/OpenWelcomeGiftComposer.ts | 21 + .../RentableSpaceCancelRentMessageComposer.ts | 21 + .../RentableSpaceRentMessageComposer.ts | 21 + .../RentableSpaceStatusMessageComposer.ts | 21 + .../dimmer/MoodlightSettingsComposer.ts | 21 + .../dimmer/MoodlightSettingsSaveComposer.ts | 21 + .../dimmer/MoodlightTogggleStateComposer.ts | 21 + .../outgoing/room/furniture/dimmer/index.ts | 3 + .../floor/FurnitureFloorUpdateComposer.ts | 21 + .../outgoing/room/furniture/floor/index.ts | 1 + .../messages/outgoing/room/furniture/index.ts | 24 + .../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 + .../outgoing/room/furniture/logic/index.ts | 9 + .../FurnitureMannequinSaveLookComposer.ts | 21 + .../FurnitureMannequinSaveNameComposer.ts | 21 + .../room/furniture/mannequin/index.ts | 2 + .../furniture/presents/OpenPresentComposer.ts | 21 + .../outgoing/room/furniture/presents/index.ts | 1 + .../furniture/toner/ApplyTonerComposer.ts | 21 + .../outgoing/room/furniture/toner/index.ts | 1 + .../wall/FurnitureWallUpdateComposer.ts | 21 + .../outgoing/room/furniture/wall/index.ts | 1 + ...olYoutubeDisplayPlaybackMessageComposer.ts | 21 + .../GetYoutubeDisplayStatusMessageComposer.ts | 21 + ...etYoutubeDisplayPlaylistMessageComposer.ts | 21 + .../outgoing/room/furniture/youtube/index.ts | 3 + .../src/messages/outgoing/room/index.ts | 19 + .../layout/GetOccupiedTilesMessageComposer.ts | 21 + .../layout/GetRoomEntryDataMessageComposer.ts | 21 + .../layout/GetRoomEntryTileMessageComposer.ts | 21 + .../UpdateFloorPropertiesMessageComposer.ts | 21 + .../messages/outgoing/room/layout/index.ts | 4 + .../room/pets/BreedPetsMessageComposer.ts | 25 + .../room/pets/PetSelectedMessageComposer.ts | 21 + .../src/messages/outgoing/room/pets/index.ts | 2 + .../session/ChangeQueueMessageComposer.ts | 21 + .../room/session/GoToFlatMessageComposer.ts | 21 + .../messages/outgoing/room/session/index.ts | 2 + .../room/unit/RoomUnitActionComposer.ts | 21 + .../room/unit/RoomUnitDanceComposer.ts | 21 + .../room/unit/RoomUnitDropHandItemComposer.ts | 21 + .../room/unit/RoomUnitGiveHandItemComposer.ts | 21 + .../unit/RoomUnitGiveHandItemPetComposer.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 + .../messages/outgoing/room/unit/chat/index.ts | 6 + .../src/messages/outgoing/room/unit/index.ts | 10 + ...oomNetworkOpenConnectionMessageComposer.ts | 21 + .../messages/outgoing/roomdirectory/index.ts | 1 + .../ApplySnapshotMessageComposer.ts | 21 + .../roomevents/OpenMessageComposer.ts | 21 + .../outgoing/roomevents/RoomMuteComposer.ts | 21 + .../roomevents/UpdateActionMessageComposer.ts | 21 + .../UpdateConditionMessageComposer.ts | 21 + .../UpdateTriggerMessageComposer.ts | 21 + .../src/messages/outgoing/roomevents/index.ts | 6 + .../roomsettings/SaveableRoomSettingsData.ts | 267 ++ ...ateRoomCategoryAndTradeSettingsComposer.ts | 21 + .../messages/outgoing/roomsettings/index.ts | 2 + .../outgoing/sound/AddJukeboxDiskComposer.ts | 21 + .../GetJukeboxPlayListMessageComposer.ts | 21 + .../sound/GetNowPlayingMessageComposer.ts | 21 + .../sound/GetOfficialSongIdMessageComposer.ts | 21 + .../sound/GetSongInfoMessageComposer.ts | 21 + .../GetSoundMachinePlayListMessageComposer.ts | 21 + .../sound/GetSoundSettingsComposer.ts | 21 + .../sound/GetUserSongDisksMessageComposer.ts | 21 + .../sound/RemoveJukeboxDiskComposer.ts | 21 + .../src/messages/outgoing/sound/index.ts | 9 + .../GetTalentTrackLevelMessageComposer.ts | 21 + .../outgoing/talent/TalentTrackComposer.ts | 21 + .../src/messages/outgoing/talent/index.ts | 2 + .../LagWarningReportMessageComposer.ts | 21 + .../tracking/PerformanceLogMessageComposer.ts | 21 + .../src/messages/outgoing/tracking/index.ts | 2 + .../user/ApproveNameMessageComposer.ts | 21 + .../outgoing/user/CatalogGroupsComposer.ts | 21 + .../outgoing/user/ChangeEmailComposer.ts | 21 + .../outgoing/user/GetEmailStatusComposer.ts | 21 + .../GetHabboGroupBadgesMessageComposer.ts | 21 + .../user/ScrGetKickbackInfoMessageComposer.ts | 21 + .../user/UnblockGroupMemberMessageComposer.ts | 21 + .../outgoing/user/UserRespectComposer.ts | 21 + .../user/WelcomeGiftChangeEmailComposer.ts | 21 + ...GetExtendedProfileByNameMessageComposer.ts | 21 + .../user/data/GetIgnoredUsersComposer.ts | 21 + .../outgoing/user/data/GetUserTagsComposer.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 + .../outgoing/user/data/UserMottoComposer.ts | 21 + .../outgoing/user/data/UserProfileComposer.ts | 21 + .../user/data/UserRelationshipsComposer.ts | 21 + .../src/messages/outgoing/user/data/index.ts | 11 + .../src/messages/outgoing/user/index.ts | 14 + .../currency/UserCurrencyComposer.ts | 21 + .../outgoing/user/inventory/currency/index.ts | 1 + .../messages/outgoing/user/inventory/index.ts | 2 + .../subscription/UserSubscriptionComposer.ts | 21 + .../user/inventory/subscription/index.ts | 1 + .../UserSettingsCameraFollowComposer.ts | 21 + .../settings/UserSettingsOldChatComposer.ts | 21 + .../UserSettingsRoomInvitesComposer.ts | 21 + .../settings/UserSettingsSoundComposer.ts | 21 + .../messages/outgoing/user/settings/index.ts | 4 + .../PeerUsersClassificationMessageComposer.ts | 21 + .../RoomUsersClassificationMessageComposer.ts | 21 + .../outgoing/userclassification/index.ts | 2 + .../InterstitialMessageParser.ts | 27 + .../advertisement/RoomAdErrorMessageParser.ts | 35 + .../messages/parser/advertisement/index.ts | 2 + .../AvailabilityStatusMessageParser.ts | 47 + .../AvailabilityTimeMessageParser.ts | 35 + .../HotelClosedAndOpensMessageParser.ts | 35 + .../HotelClosesAndWillOpenAtMessageParser.ts | 43 + .../HotelWillCloseInMinutesMessageParser.ts | 27 + .../MaintenanceStatusMessageParser.ts | 47 + .../src/messages/parser/availability/index.ts | 6 + .../ChangeUserNameResultMessageParser.ts | 51 + .../CheckUserNameResultMessageParser.ts | 51 + .../parser/avatar/FigureUpdateParser.ts | 37 + .../src/messages/parser/avatar/OutfitData.ts | 30 + .../parser/avatar/WardrobeMessageParser.ts | 44 + .../src/messages/parser/avatar/index.ts | 5 + .../parser/bots/BotAddedToInventoryParser.ts | 36 + .../src/messages/parser/bots/BotData.ts | 46 + .../parser/bots/BotInventoryMessageParser.ts | 37 + .../parser/bots/BotReceivedMessageParser.ts | 36 + .../bots/BotRemovedFromInventoryParser.ts | 27 + .../src/messages/parser/bots/index.ts | 5 + .../callforhelp/CallForHelpCategoryData.ts | 48 + .../callforhelp/CallForHelpTopicData.ts | 31 + .../callforhelp/CfhSanctionMessageParser.ts | 44 + .../parser/callforhelp/CfhSanctionTypeData.ts | 49 + .../callforhelp/CfhTopicsInitMessageParser.ts | 37 + .../SanctionStatusMessageParser.ts | 114 + .../src/messages/parser/callforhelp/index.ts | 6 + .../CameraPublishStatusMessageParser.ts | 44 + .../camera/CameraPurchaseOKMessageParser.ts | 16 + .../camera/CameraSnapshotMessageParser.ts | 35 + .../camera/CameraStorageUrlMessageParser.ts | 27 + .../camera/CompetitionStatusMessageParser.ts | 35 + .../parser/camera/InitCameraMessageParser.ts | 44 + .../camera/ThumbnailStatusMessageParser.ts | 37 + .../src/messages/parser/camera/index.ts | 7 + .../parser/campaign/CampaignCalendarData.ts | 114 + .../CampaignCalendarDataMessageParser.ts | 29 + ...CampaignCalendarDoorOpenedMessageParser.ts | 51 + .../src/messages/parser/campaign/index.ts | 3 + .../catalog/BonusRareInfoMessageParser.ts | 49 + .../BuildersClubFurniCountMessageParser.ts | 27 + ...dersClubSubscriptionStatusMessageParser.ts | 53 + .../parser/catalog/BundleDiscountRuleset.ts | 53 + .../BundleDiscountRulesetMessageParser.ts | 28 + .../catalog/CatalogIndexMessageParser.ts | 42 + .../parser/catalog/CatalogLocalizationData.ts | 41 + .../catalog/CatalogPageExpirationParser.ts | 51 + .../catalog/CatalogPageMessageOfferData.ts | 105 + .../catalog/CatalogPageMessageParser.ts | 106 + .../catalog/CatalogPageMessageProductData.ts | 98 + ...alogPageWithEarliestExpiryMessageParser.ts | 43 + .../catalog/CatalogPublishedMessageParser.ts | 36 + .../messages/parser/catalog/ClubGiftData.ts | 37 + .../parser/catalog/ClubGiftInfoParser.ts | 77 + .../parser/catalog/ClubGiftSelectedParser.ts | 44 + .../messages/parser/catalog/ClubOfferData.ts | 105 + .../parser/catalog/ClubOfferExtendData.ts | 50 + .../DirectSMSClubBuyAvailableMessageParser.ts | 53 + .../parser/catalog/FireworkChargeData.ts | 51 + .../catalog/FireworkChargeDataParser.ts | 28 + .../messages/parser/catalog/FrontPageItem.ts | 108 + .../catalog/GiftReceiverNotFoundParser.ts | 20 + .../GiftWrappingConfigurationParser.ts | 105 + .../HabboClubExtendOfferMessageParser.ts | 28 + .../catalog/HabboClubOffersMessageParser.ts | 35 + .../src/messages/parser/catalog/INodeData.ts | 10 + .../catalog/IsOfferGiftableMessageParser.ts | 35 + .../catalog/LimitedEditionSoldOutParser.ts | 16 + .../LimitedOfferAppearingNextMessageParser.ts | 51 + .../src/messages/parser/catalog/NodeData.ts | 99 + .../catalog/NotEnoughBalanceMessageParser.ts | 44 + .../catalog/ProductOfferMessageParser.ts | 28 + .../catalog/PurchaseErrorMessageParser.ts | 27 + .../PurchaseNotAllowedMessageParser.ts | 27 + .../catalog/PurchaseOKMessageOfferData.ts | 117 + .../parser/catalog/PurchaseOKMessageParser.ts | 28 + .../catalog/RoomAdPurchaseInfoEventParser.ts | 44 + ...SeasonalCalendarDailyOfferMessageParser.ts | 36 + .../parser/catalog/SellablePetPaletteData.ts | 67 + .../catalog/SellablePetPalettesParser.ts | 44 + .../parser/catalog/TargetedOfferData.ts | 153 + .../catalog/TargetedOfferNotFoundParser.ts | 16 + .../parser/catalog/TargetedOfferParser.ts | 28 + .../VoucherRedeemErrorMessageParser.ts | 26 + .../catalog/VoucherRedeemOkMessageParser.ts | 34 + .../src/messages/parser/catalog/index.ts | 46 + .../parser/client/ClientPingParser.ts | 16 + .../src/messages/parser/client/index.ts | 1 + ...mpetitionEntrySubmitResultMessageParser.ts | 83 + .../CompetitionVotingInfoMessageParser.ts | 55 + .../CompetitionVotingInfoResult.ts | 6 + .../CurrentTimingCodeMessageParser.ts | 33 + .../IsUserPartOfCompetitionMessageParser.ts | 33 + .../NoOwnedRoomsAlertMessageParser.ts | 14 + .../competition/SecondsUntilMessageParser.ts | 33 + .../src/messages/parser/competition/index.ts | 7 + .../CraftableProductsMessageParser.ts | 52 + .../CraftingRecipeIngredientParser.ts | 23 + .../crafting/CraftingRecipeMessageParser.ts | 34 + .../CraftingRecipesAvailableMessageParser.ts | 32 + .../crafting/CraftingResultMessageParser.ts | 35 + .../crafting/CraftingResultObjectParser.ts | 23 + .../src/messages/parser/crafting/index.ts | 6 + .../parser/desktop/DesktopViewParser.ts | 16 + .../src/messages/parser/desktop/index.ts | 1 + .../friendlist/AcceptFriendFailureData.ts | 25 + .../friendlist/AcceptFriendResultParser.ts | 35 + .../FindFriendsProcessResultParser.ts | 27 + .../friendlist/FollowFriendFailedParser.ts | 27 + .../parser/friendlist/FriendCategoryData.ts | 25 + .../FriendListFragmentMessageParser.ts | 52 + .../friendlist/FriendListUpdateParser.ts | 81 + .../friendlist/FriendNotificationParser.ts | 43 + .../parser/friendlist/FriendParser.ts | 109 + .../parser/friendlist/FriendRequestData.ts | 39 + .../parser/friendlist/FriendRequestsParser.ts | 44 + .../friendlist/HabboSearchResultData.ts | 76 + .../friendlist/HabboSearchResultParser.ts | 51 + .../friendlist/InstantMessageErrorParser.ts | 43 + .../parser/friendlist/MessageErrorParser.ts | 35 + .../parser/friendlist/MessengerInitParser.ts | 59 + .../friendlist/MiniMailNewMessageParser.ts | 16 + .../friendlist/MiniMailUnreadCountParser.ts | 27 + .../friendlist/NewConsoleMessageParser.ts | 55 + .../NewFriendRequestMessageParser.ts | 28 + .../friendlist/RoomInviteErrorParser.ts | 43 + .../friendlist/RoomInviteMessageParser.ts | 35 + .../src/messages/parser/friendlist/index.ts | 22 + .../Game2AccountGameStatusMessageParser.ts | 45 + .../Game2GameDirectoryStatusMessageParser.ts | 61 + .../Game2InArenaQueueMessageParser.ts | 27 + .../Game2JoiningGameFailedMessageParser.ts | 36 + .../Game2StartingGameFailedMessageParser.ts | 30 + .../Game2StopCounterMessageParser.ts | 16 + .../Game2UserLeftGameMessageParser.ts | 27 + .../messages/parser/game/directory/index.ts | 7 + .../src/messages/parser/game/index.ts | 3 + ...evementResolutionCompletedMessageParser.ts | 32 + ...ievementResolutionProgressMessageParser.ts | 66 + .../AchievementResolutionsMessageParser.ts | 46 + .../parser/game/lobby/GameAchievementData.ts | 35 + .../lobby/GameAchievementsMessageParser.ts | 43 + .../game/lobby/GameConfigurationData.ts | 49 + .../game/lobby/GameInviteMessageParser.ts | 32 + .../game/lobby/GameListMessageParser.ts | 43 + .../game/lobby/GameStatusMessageParser.ts | 40 + .../game/lobby/JoinedQueueMessageParser.ts | 25 + .../lobby/JoiningQueueFailedMessageParser.ts | 34 + .../game/lobby/LeftQueueMessageParser.ts | 25 + .../game/lobby/LoadGameMessageParser.ts | 88 + .../parser/game/lobby/LoadGameUrlParser.ts | 43 + .../game/lobby/UnloadGameMessageParser.ts | 32 + .../UserGameAchievementsMessageParser.ts | 21 + .../src/messages/parser/game/lobby/index.ts | 16 + .../score/Game2WeeklyLeaderboardParser.ts | 59 + .../game/score/GameRewardWinnerEntry.ts | 44 + .../parser/game/score/LeaderboardEntry.ts | 51 + .../game/score/WeeklyGameRewardParser.ts | 59 + .../score/WeeklyGameRewardWinnersParser.ts | 42 + .../src/messages/parser/game/score/index.ts | 5 + .../parser/generic/GenericErrorParser.ts | 26 + .../src/messages/parser/generic/index.ts | 1 + .../gifts/PhoneCollectionStateParser.ts | 41 + .../gifts/TryPhoneNumberResultParser.ts | 33 + .../gifts/TryVerificationCodeResultParser.ts | 34 + .../src/messages/parser/gifts/index.ts | 3 + .../parser/group/GroupBadgePartsParser.ts | 109 + .../parser/group/GroupBuyDataParser.ts | 45 + .../group/GroupConfirmMemberRemoveParser.ts | 35 + .../parser/group/GroupInformationParser.ts | 156 + .../parser/group/GroupMembersParser.ts | 116 + .../parser/group/GroupPurchasedParser.ts | 35 + .../parser/group/GroupSettingsParser.ts | 149 + .../HabboGroupDeactivatedMessageParser.ts | 23 + .../src/messages/parser/group/index.ts | 9 + .../parser/group/utils/GroupDataBadgePart.ts | 22 + .../parser/group/utils/GroupMemberParser.ts | 76 + .../src/messages/parser/group/utils/index.ts | 2 + .../parser/groupforums/ExtendedForumData.ts | 118 + .../messages/parser/groupforums/ForumData.ts | 135 + .../groupforums/ForumDataMessageParser.ts | 28 + .../groupforums/GetForumsListMessageParser.ts | 69 + .../parser/groupforums/GuildForumThread.ts | 217 ++ .../groupforums/GuildForumThreadsParser.ts | 61 + .../parser/groupforums/MessageData.ts | 179 + .../groupforums/PostMessageMessageParser.ts | 44 + .../groupforums/PostThreadMessageParser.ts | 36 + .../ThreadMessagesMessageParser.ts | 74 + .../UnreadForumsCountMessageParser.ts | 27 + .../groupforums/UpdateMessageMessageParser.ts | 44 + .../groupforums/UpdateThreadMessageParser.ts | 36 + .../src/messages/parser/groupforums/index.ts | 13 + .../CompleteDiffieHandshakeParser.ts | 36 + .../handshake/DisconnectReasonParser.ts | 32 + .../handshake/IdentityAccountsParser.ts | 39 + .../handshake/InitDiffieHandshakeParser.ts | 32 + .../handshake/NoobnessLevelMessageParser.ts | 27 + .../src/messages/parser/handshake/index.ts | 5 + .../CallForHelpDisabledNotifyMessageParser.ts | 25 + ...ForHelpPendingCallsDeletedMessageParser.ts | 14 + .../CallForHelpPendingCallsMessageParser.ts | 46 + .../help/CallForHelpReplyMessageParser.ts | 23 + .../help/CallForHelpResultMessageParser.ts | 35 + .../ChatReviewSessionDetachedMessageParser.ts | 15 + ...eviewSessionOfferedToGuideMessageParser.ts | 23 + .../ChatReviewSessionResultsMessageParser.ts | 47 + .../ChatReviewSessionStartedMessageParser.ts | 29 + ...tReviewSessionVotingStatusMessageParser.ts | 38 + .../help/GuideOnDutyStatusMessageParser.ts | 51 + .../help/GuideReportingStatusMessageParser.ts | 49 + .../help/GuideSessionAttachedMessageParser.ts | 51 + .../help/GuideSessionDetachedMessageParser.ts | 16 + .../help/GuideSessionEndedMessageParser.ts | 27 + .../help/GuideSessionErrorMessageParser.ts | 33 + ...eSessionInvitedToGuideRoomMessageParser.ts | 35 + .../help/GuideSessionMessageMessageParser.ts | 35 + ...uideSessionPartnerIsTypingMessageParser.ts | 27 + .../GuideSessionRequesterRoomMessageParser.ts | 27 + .../help/GuideSessionStartedMessageParser.ts | 67 + .../GuideTicketCreationResultMessageParser.ts | 32 + .../GuideTicketResolutionMessageParser.ts | 31 + .../parser/help/HotelMergeNameChangeParser.ts | 16 + .../IssueCloseNotificationMessageParser.ts | 34 + .../parser/help/PendingGuideTicketData.ts | 91 + .../parser/help/QuizDataMessageParser.ts | 40 + .../parser/help/QuizResultsMessageParser.ts | 40 + .../src/messages/parser/help/index.ts | 28 + .../src/messages/parser/index.ts | 77 + .../inventory/achievements/AchievementData.ts | 156 + .../achievements/AchievementParser.ts | 28 + .../achievements/AchievementResolutionData.ts | 59 + .../achievements/AchievementsParser.ts | 46 + .../achievements/AchievementsScoreParser.ts | 27 + .../parser/inventory/achievements/index.ts | 5 + .../inventory/avatareffect/AvatarEffect.ts | 69 + .../AvatarEffectActivatedParser.ts | 43 + .../avatareffect/AvatarEffectAddedParser.ts | 51 + .../avatareffect/AvatarEffectExpiredParser.ts | 27 + .../AvatarEffectSelectedParser.ts | 27 + .../avatareffect/AvatarEffectsParser.ts | 44 + .../parser/inventory/avatareffect/index.ts | 6 + .../inventory/badges/BadgeAndPointLimit.ts | 25 + .../badges/BadgePointLimitsParser.ts | 45 + .../inventory/badges/BadgeReceivedParser.ts | 35 + .../parser/inventory/badges/BadgesParser.ts | 69 + .../badges/IsBadgeRequestFulfilledParser.ts | 32 + .../messages/parser/inventory/badges/index.ts | 5 + .../clothing/FigureSetIdsMessageParser.ts | 50 + .../parser/inventory/clothing/_Str_8728.ts | 27 + .../parser/inventory/clothing/_Str_9021.ts | 27 + .../parser/inventory/clothing/index.ts | 3 + .../FurnitureListAddOrUpdateParser.ts | 28 + .../FurnitureListInvalidateParser.ts | 16 + .../furniture/FurnitureListItemParser.ts | 217 ++ .../furniture/FurnitureListParser.ts | 54 + .../furniture/FurnitureListRemovedParser.ts | 27 + .../furniture/FurniturePostItPlacedParser.ts | 35 + .../inventory/furniture/IFurnitureItemData.ts | 28 + .../furniture/PresentOpenedMessageParser.ts | 70 + .../parser/inventory/furniture/index.ts | 8 + .../src/messages/parser/inventory/index.ts | 8 + .../pets/ConfirmBreedingRequestParser.ts | 80 + .../pets/ConfirmBreedingResultParser.ts | 35 + .../pets/GoToBreedingNestFailureParser.ts | 25 + .../pets/NestBreedingSuccessParser.ts | 33 + .../pets/PetAddedToInventoryParser.ts | 34 + .../pets/PetBreedingMessageParser.ts | 47 + .../messages/parser/inventory/pets/PetData.ts | 70 + .../inventory/pets/PetFigureDataParser.ts | 71 + .../inventory/pets/PetInventoryParser.ts | 52 + .../pets/PetReceivedMessageParser.ts | 34 + .../pets/PetRemovedFromInventoryParser.ts | 25 + .../messages/parser/inventory/pets/index.ts | 11 + .../purse/UserCreditsMessageParser.ts | 25 + .../messages/parser/inventory/purse/index.ts | 1 + .../inventory/trading/ItemDataStructure.ts | 162 + .../inventory/trading/TradingAcceptParser.ts | 35 + .../inventory/trading/TradingCloseParser.ts | 34 + .../trading/TradingCompletedParser.ts | 16 + .../trading/TradingConfirmationParser.ts | 16 + .../trading/TradingListItemParser.ts | 105 + .../trading/TradingNoSuchItemParser.ts | 16 + .../inventory/trading/TradingNotOpenParser.ts | 16 + .../trading/TradingOpenFailedParser.ts | 35 + .../inventory/trading/TradingOpenParser.ts | 51 + .../trading/TradingOtherNotAllowedParser.ts | 16 + .../trading/TradingYouAreNotAllowedParser.ts | 16 + .../parser/inventory/trading/index.ts | 12 + .../parser/landingview/PromoArticleData.ts | 62 + .../landingview/PromoArticlesMessageParser.ts | 32 + .../src/messages/parser/landingview/index.ts | 3 + .../votes/CommunityVoteReceivedParser.ts | 23 + .../parser/landingview/votes/index.ts | 1 + .../MarketplaceBuyOfferResultParser.ts | 50 + .../MarketplaceCanMakeOfferResultParser.ts | 35 + .../MarketplaceCancelOfferResultParser.ts | 35 + .../MarketplaceConfigurationMessageParser.ts | 83 + .../MarketplaceItemPostedParser.ts | 27 + .../marketplace/MarketplaceItemStatsParser.ts | 92 + .../parser/marketplace/MarketplaceOffer.ts | 84 + .../marketplace}/MarketplaceOfferData.ts | 6 +- .../marketplace/MarketplaceOffersParser.ts | 89 + .../marketplace/MarketplaceOwnOffersParser.ts | 88 + .../src/messages/parser/marketplace/index.ts | 10 + .../parser/moderation/CfhChatlogData.ts | 45 + .../moderation/CfhChatlogMessageParser.ts | 28 + .../parser/moderation/ChatRecordData.ts | 110 + .../parser/moderation/ChatlineData.ts | 42 + .../src/messages/parser/moderation/INamed.ts | 4 + .../moderation/IssueDeletedMessageParser.ts | 22 + .../moderation/IssueInfoMessageParser.ts | 52 + .../parser/moderation/IssueMessageData.ts | 162 + .../IssuePickFailedMessageParser.ts | 50 + .../messages/parser/moderation/ModRoomData.ts | 64 + .../moderation/ModerationCautionParser.ts | 35 + .../ModeratorActionResultMessageParser.ts | 32 + .../parser/moderation/ModeratorInitData.ts | 138 + .../moderation/ModeratorInitMessageParser.ts | 23 + .../moderation/ModeratorMessageParser.ts | 35 + .../ModeratorRoomInfoMessageParser.ts | 28 + .../ModeratorToolPreferencesMessageParser.ts | 47 + .../moderation/ModeratorUserInfoData.ts | 145 + .../ModeratorUserInfoMessageParser.ts | 28 + .../parser/moderation/PatternMatchData.ts | 44 + .../moderation/RoomChatlogMessageParser.ts | 27 + .../parser/moderation/RoomModerationData.ts | 72 + .../parser/moderation/RoomVisitData.ts | 37 + .../parser/moderation/RoomVisitsData.ts | 38 + .../moderation/RoomVisitsMessageParser.ts | 23 + .../moderation/UserBannedMessageParser.ts | 27 + .../parser/moderation/UserChatlogData.ts | 35 + .../moderation/UserChatlogMessageParser.ts | 28 + .../src/messages/parser/moderation/index.ts | 28 + .../CancelMysteryBoxWaitMessageParser.ts | 21 + .../GotMysteryBoxPrizeMessageParser.ts | 33 + .../parser/mysterybox/MysteryBoxKeysParser.ts | 35 + .../ShowMysteryBoxWaitMessageParser.ts | 21 + .../src/messages/parser/mysterybox/index.ts | 4 + .../navigator/CanCreateRoomEventParser.ts | 35 + .../navigator/CanCreateRoomMessageParser.ts | 35 + .../CategoriesWithVisitorCountParser.ts | 26 + .../CompetitionRoomsDataMessageParser.ts | 26 + .../navigator/ConvertedRoomIdMessageParser.ts | 32 + .../parser/navigator/DoorbellMessageParser.ts | 27 + .../FavouriteChangedMessageParser.ts | 32 + .../navigator/FavouritesMessageParser.ts | 39 + .../FlatAccessDeniedMessageParser.ts | 27 + .../navigator/FlatCreatedMessageParser.ts | 35 + .../GetGuestRoomResultMessageParser.ts | 79 + .../GuestRoomSearchResultMessageParser.ts | 27 + .../navigator/NavigatorCategoryDataParser.ts | 83 + .../navigator/NavigatorCollapsedParser.ts | 34 + .../NavigatorEventCategoryDataParser.ts | 51 + .../navigator/NavigatorHomeRoomParser.ts | 35 + .../navigator/NavigatorLiftedDataParser.ts | 59 + .../parser/navigator/NavigatorLiftedParser.ts | 35 + .../navigator/NavigatorMetadataParser.ts | 35 + .../NavigatorOpenRoomCreatorParser.ts | 16 + .../parser/navigator/NavigatorSearchParser.ts | 28 + .../navigator/NavigatorSearchesParser.ts | 35 + .../navigator/NavigatorSettingsParser.ts | 67 + .../parser/navigator/PopularRoomTagsData.ts | 46 + .../PopularRoomTagsResultMessageParser.ts | 28 + .../parser/navigator/PopularTagData.ts | 23 + .../navigator/RoomEventCancelMessageParser.ts | 15 + .../navigator/RoomEventMessageParser.ts | 23 + .../RoomFilterSettingsMessageParser.ts | 34 + .../navigator/RoomSettingsUpdatedParser.ts | 27 + .../RoomThumbnailUpdateResultMessageParser.ts | 30 + .../navigator/UserEventCatsMessageParser.ts | 35 + .../navigator/UserFlatCatsMessageParser.ts | 35 + .../src/messages/parser/navigator/index.ts | 34 + .../utils/CategoriesWithVisitorCountData.ts | 34 + .../navigator/utils/CompetitionRoomsData.ts | 36 + .../utils/GuestRoomSearchResultData.ts | 76 + .../navigator/utils/NavigatorSavedSearch.ts | 59 + .../utils/NavigatorSearchResultList.ts | 84 + .../utils/NavigatorSearchResultSet.ts | 60 + .../utils/NavigatorTopLevelContext.ts | 52 + .../navigator/utils/OfficialRoomEntryData.ts | 148 + .../parser/navigator/utils/RoomEventData.ts | 104 + .../messages/parser/navigator/utils/index.ts | 9 + .../notifications/AchievementLevelUpData.ts | 93 + .../AchievementNotificationMessageParser.ts | 28 + .../ActivityPointNotificationParser.ts | 43 + .../notifications/BotErrorEventParser.ts | 26 + .../ClubGiftNotificationParser.ts | 27 + .../ConnectionErrorMessageParser.ts | 43 + .../ElementPointerMessageParser.ts | 26 + .../HabboBroadcastMessageParser.ts | 27 + .../notifications/HotelWillShutdownParser.ts | 27 + .../InfoFeedEnableMessageParser.ts | 27 + .../notifications/MOTDNotificationParser.ts | 34 + .../NotificationDialogMessageParser.ts | 43 + .../OfferRewardDeliveredMessageParser.ts | 51 + .../PetLevelNotificationParser.ts | 52 + .../PetPlacingErrorEventParser.ts | 26 + .../RestoreClientMessageParser.ts | 14 + .../notifications/SimpleAlertMessageParser.ts | 37 + .../parser/notifications/UnseenItemsParser.ts | 52 + .../messages/parser/notifications/index.ts | 18 + ...NewUserExperienceGiftOfferMessageParser.ts | 34 + .../nux/NewUserExperienceNotCompleteParser.ts | 16 + .../src/messages/parser/nux/index.ts | 2 + .../perk/PerkAllowancesMessageParser.ts | 52 + .../messages/parser/perk/common/PerkData.ts | 28 + .../messages/parser/perk/common/PerkEnum.ts | 15 + .../src/messages/parser/perk/common/index.ts | 2 + .../src/messages/parser/perk/index.ts | 2 + .../OpenPetPackageRequestedMessageParser.ts | 36 + .../pet/OpenPetPackageResultMessageParser.ts | 41 + .../parser/pet/PetLevelUpdateMessageParser.ts | 41 + .../pet/PetScratchFailedMessageParser.ts | 33 + .../parser/pet/PetTrainingMessageParser.ts | 57 + .../src/messages/parser/pet/index.ts | 5 + .../src/messages/parser/poll/PollChoice.ts | 45 + .../parser/poll/PollContentsParser.ts | 98 + .../messages/parser/poll/PollErrorParser.ts | 14 + .../messages/parser/poll/PollOfferParser.ts | 46 + .../src/messages/parser/poll/PollQuestion.ts | 111 + .../parser/poll/QuestionAnsweredParser.ts | 49 + .../parser/poll/QuestionFinishedParser.ts | 39 + .../messages/parser/poll/QuestionParser.ts | 77 + .../parser/poll/RoomPollDataParser.ts | 41 + .../parser/poll/RoomPollResultParser.ts | 59 + .../src/messages/parser/poll/index.ts | 10 + .../parser/quest/CommunityGoalData.ts | 95 + .../CommunityGoalEarnedPrizesMessageParser.ts | 30 + .../quest/CommunityGoalHallOfFameData.ts | 41 + .../CommunityGoalHallOfFameMessageParser.ts | 26 + .../CommunityGoalProgressMessageParser.ts | 26 + ...oncurrentUsersGoalProgressMessageParser.ts | 41 + .../parser/quest/EpicPopupMessageParser.ts | 25 + .../parser/quest/HallOfFameEntryData.ts | 45 + .../parser/quest/ILandingPageUserEntry.ts | 6 + .../src/messages/parser/quest/PrizeData.ts | 51 + .../quest/QuestCancelledMessageParser.ts | 24 + .../quest/QuestCompletedMessageParser.ts | 33 + .../parser/quest/QuestDailyMessageParser.ts | 44 + .../messages/parser/quest/QuestMessageData.ts | 186 + .../parser/quest/QuestMessageParser.ts | 26 + .../parser/quest/QuestsMessageParser.ts | 40 + .../parser/quest/SeasonalQuestsParser.ts | 32 + .../src/messages/parser/quest/index.ts | 17 + .../recycler/RecyclerFinishedMessageParser.ts | 34 + .../recycler/RecyclerStatusMessageParser.ts | 34 + .../src/messages/parser/recycler/index.ts | 2 + .../room/access/CantConnectMessageParser.ts | 40 + .../parser/room/access/RoomEnterParser.ts | 16 + .../parser/room/access/RoomFowardParser.ts | 27 + .../doorbell/RoomDoorbellAcceptedParser.ts | 27 + .../parser/room/access/doorbell/index.ts | 1 + .../src/messages/parser/room/access/index.ts | 5 + .../access/rights/RoomRightsClearParser.ts | 16 + .../access/rights/RoomRightsOwnerParser.ts | 16 + .../room/access/rights/RoomRightsParser.ts | 27 + .../parser/room/access/rights/index.ts | 3 + .../bots/BotCommandConfigurationParser.ts | 42 + .../bots/BotForceOpenContextMenuParser.ts | 27 + .../messages/parser/room/bots/BotSkillData.ts | 23 + .../room/bots/BotSkillListUpdateParser.ts | 44 + .../src/messages/parser/room/bots/index.ts | 4 + .../room/data/RoomChatSettingsParser.ts | 28 + .../parser/room/data/RoomDataParser.ts | 301 ++ .../room/data/RoomEntryInfoMessageParser.ts | 35 + .../parser/room/data/RoomScoreParser.ts | 35 + .../src/messages/parser/room/data/index.ts | 4 + .../FavoriteMembershipUpdateMessageParser.ts | 51 + .../messages/parser/room/engine/ObjectData.ts | 30 + .../room/engine/ObjectsDataUpdateParser.ts | 40 + .../room/engine/ObjectsRollingParser.ts | 80 + .../src/messages/parser/room/engine/index.ts | 4 + .../CustomUserNotificationMessageParser.ts | 27 + .../room/furniture/DiceValueMessageParser.ts | 35 + .../FurniRentOrBuyoutOfferMessageParser.ts | 67 + .../room/furniture/FurnitureAliasesParser.ts | 34 + .../room/furniture/FurnitureDataParser.ts | 48 + .../furniture/FurnitureStackHeightParser.ts | 35 + .../GroupFurniContextMenuInfoMessageParser.ts | 67 + .../furniture/ItemDataUpdateMessageParser.ts | 35 + .../furniture/LoveLockFurniFinishedParser.ts | 23 + .../LoveLockFurniFriendConfirmedParser.ts | 23 + .../furniture/LoveLockFurniStartParser.ts | 31 + .../OneWayDoorStatusMessageParser.ts | 35 + .../RentableSpaceRentFailedMessageParser.ts | 25 + .../RentableSpaceRentOkMessageParser.ts | 25 + .../RentableSpaceStatusMessageParser.ts | 92 + .../RequestSpamWallPostItMessageParser.ts | 35 + .../furniture/RoomDimmerPresetsMessageData.ts | 9 + .../RoomDimmerPresetsMessageParser.ts | 57 + .../RoomMessageNotificationMessageParser.ts | 43 + .../room/furniture/WelcomeGiftStatusParser.ts | 59 + .../floor/FurnitureFloorAddParser.ts | 29 + .../floor/FurnitureFloorDataParser.ts | 159 + .../furniture/floor/FurnitureFloorParser.ts | 68 + .../floor/FurnitureFloorRemoveParser.ts | 51 + .../floor/FurnitureFloorUpdateParser.ts | 28 + .../parser/room/furniture/floor/index.ts | 5 + .../messages/parser/room/furniture/index.ts | 23 + .../furniture/wall/FurnitureWallAddParser.ts | 29 + .../furniture/wall/FurnitureWallDataParser.ts | 228 ++ .../furniture/wall/FurnitureWallParser.ts | 68 + .../wall/FurnitureWallRemoveParser.ts | 35 + .../wall/FurnitureWallUpdateParser.ts | 28 + .../parser/room/furniture/wall/index.ts | 5 + .../YoutubeControlVideoMessageParser.ts | 31 + .../youtube/YoutubeDisplayPlaylist.ts | 28 + .../YoutubeDisplayPlaylistsMessageParser.ts | 45 + .../YoutubeDisplayVideoMessageParser.ts | 50 + .../parser/room/furniture/youtube/index.ts | 4 + .../src/messages/parser/room/index.ts | 15 + .../mapping/FloorHeightMapMessageParser.ts | 167 + .../mapping/RoomEntryTileMessageParser.ts | 43 + .../room/mapping/RoomHeightMapParser.ts | 88 + .../room/mapping/RoomHeightMapUpdateParser.ts | 75 + .../mapping/RoomOccupiedTilesMessageParser.ts | 39 + .../parser/room/mapping/RoomPaintParser.ts | 65 + .../room/mapping/RoomReadyMessageParser.ts | 35 + .../RoomVisualizationSettingsParser.ts | 50 + .../src/messages/parser/room/mapping/index.ts | 8 + .../room/pet/PetBreedingResultParser.ts | 34 + .../parser/room/pet/PetExperienceParser.ts | 42 + .../parser/room/pet/PetFigureUpdateParser.ts | 54 + .../messages/parser/room/pet/PetInfoParser.ts | 220 ++ .../parser/room/pet/PetStatusUpdateParser.ts | 67 + .../src/messages/parser/room/pet/index.ts | 5 + .../room/session/YouArePlayingGameParser.ts | 27 + .../session/YouAreSpectatorMessageParser.ts | 14 + .../src/messages/parser/room/session/index.ts | 2 + .../parser/room/unit/RoomUnitDanceParser.ts | 35 + .../parser/room/unit/RoomUnitEffectParser.ts | 43 + .../room/unit/RoomUnitExpressionParser.ts | 35 + .../room/unit/RoomUnitHandItemParser.ts | 35 + .../unit/RoomUnitHandItemReceivedParser.ts | 35 + .../parser/room/unit/RoomUnitIdleParser.ts | 35 + .../parser/room/unit/RoomUnitInfoParser.ts | 59 + .../parser/room/unit/RoomUnitNumberParser.ts | 35 + .../parser/room/unit/RoomUnitParser.ts | 186 + .../parser/room/unit/RoomUnitRemoveParser.ts | 27 + .../parser/room/unit/RoomUnitStatusAction.ts | 21 + .../parser/room/unit/RoomUnitStatusMessage.ts | 100 + .../parser/room/unit/RoomUnitStatusParser.ts | 119 + .../parser/room/unit/UserMessageData.ts | 412 +++ .../room/unit/chat/FloodControlParser.ts | 27 + .../room/unit/chat/RemainingMuteParser.ts | 27 + .../room/unit/chat/RoomUnitChatParser.ts | 87 + .../room/unit/chat/RoomUnitTypingParser.ts | 35 + .../messages/parser/room/unit/chat/index.ts | 4 + .../src/messages/parser/room/unit/index.ts | 15 + .../parser/roomevents/ConditionDefinition.ts | 24 + .../parser/roomevents/TriggerDefinition.ts | 35 + .../messages/parser/roomevents/Triggerable.ts | 100 + .../roomevents/WiredActionDefinition.ts | 47 + .../roomevents/WiredFurniActionParser.ts | 28 + .../roomevents/WiredFurniConditionParser.ts | 28 + .../roomevents/WiredFurniTriggerParser.ts | 28 + .../parser/roomevents/WiredOpenParser.ts | 27 + .../WiredRewardResultMessageParser.ts | 27 + .../roomevents/WiredSaveSuccessParser.ts | 16 + .../roomevents/WiredValidationErrorParser.ts | 27 + .../src/messages/parser/roomevents/index.ts | 11 + .../parser/roomsettings/BannedUserData.ts | 24 + .../roomsettings/BannedUsersFromRoomParser.ts | 44 + .../roomsettings/FlatControllerAddedParser.ts | 36 + .../parser/roomsettings/FlatControllerData.ts | 35 + .../FlatControllerRemovedParser.ts | 35 + .../roomsettings/FlatControllersParser.ts | 46 + .../messages/parser/roomsettings/IFlatUser.ts | 5 + .../roomsettings/MuteAllInRoomParser.ts | 25 + .../parser/roomsettings/NoSuchFlatParser.ts | 27 + .../parser/roomsettings/RoomChatSettings.ts | 57 + .../roomsettings/RoomModerationSettings.ts | 34 + .../parser/roomsettings/RoomSettingsData.ts | 332 ++ .../roomsettings/RoomSettingsDataParser.ts | 59 + .../roomsettings/RoomSettingsErrorParser.ts | 35 + .../RoomSettingsSaveErrorParser.ts | 57 + .../roomsettings/RoomSettingsSavedParser.ts | 27 + .../ShowEnforceRoomCategoryDialogParser.ts | 27 + .../UserUnbannedFromRoomParser.ts | 35 + .../src/messages/parser/roomsettings/index.ts | 18 + .../parser/security/AuthenticatedParser.ts | 16 + .../src/messages/parser/security/index.ts | 1 + .../sound/JukeboxPlayListFullMessageParser.ts | 14 + .../sound/JukeboxSongDisksMessageParser.ts | 38 + .../parser/sound/NowPlayingMessageParser.ts | 56 + .../sound/OfficialSongIdMessageParser.ts | 31 + .../messages/parser/sound/PlayListEntry.ts | 46 + .../parser/sound/PlayListMessageParser.ts | 40 + .../sound/PlayListSongAddedMessageParser.ts | 24 + .../messages/parser/sound/SongInfoEntry.ts | 17 + .../parser/sound/TraxSongInfoMessageParser.ts | 35 + .../UserSongDisksInventoryMessageParser.ts | 47 + .../src/messages/parser/sound/index.ts | 10 + .../talent/TalentLevelUpMessageParser.ts | 75 + .../parser/talent/TalentTrackLevel.ts | 45 + .../talent/TalentTrackLevelMessageParser.ts | 43 + .../parser/talent/TalentTrackParser.ts | 79 + .../parser/talent/TalentTrackRewardPerk.ts | 16 + .../parser/talent/TalentTrackRewardProduct.ts | 21 + .../messages/parser/talent/TalentTrackTask.ts | 49 + .../src/messages/parser/talent/index.ts | 7 + .../AccountSafetyLockStatusChangeParser.ts | 28 + .../parser/user/ApproveNameResultParser.ts | 35 + .../parser/user/ChangeEmailResultParser.ts | 29 + .../messages/parser/user/EmailStatusParser.ts | 43 + .../ExtendedProfileChangedMessageParser.ts | 27 + .../user/GroupDetailsChangedMessageParser.ts | 27 + .../GroupMembershipRequestedMessageParser.ts | 36 + .../user/GuildEditFailedMessageParser.ts | 29 + .../GuildMemberMgmtFailedMessageParser.ts | 35 + .../user/GuildMembershipsMessageParser.ts | 35 + .../user/HabboGroupBadgesMessageParser.ts | 36 + .../parser/user/HabboGroupEntryData.ts | 65 + .../user/HabboGroupJoinFailedMessageParser.ts | 29 + .../parser/user/IgnoreResultParser.ts | 35 + .../parser/user/IgnoredUsersParser.ts | 36 + .../parser/user/InClientLinkParser.ts | 25 + .../user/PetRespectNotificationParser.ts | 49 + .../parser/user/PetSupplementTypeEnum.ts | 8 + .../user/PetSupplementedNotificationParser.ts | 43 + .../parser/user/RespectReceivedParser.ts | 35 + .../src/messages/parser/user/RoomEntryData.ts | 28 + .../messages/parser/user/ScrKickbackData.ts | 72 + .../user/ScrSendKickbackInfoMessageParser.ts | 23 + .../WelcomeGiftChangeEmailResultParser.ts | 27 + .../user/access/UserPermissionsParser.ts | 43 + .../src/messages/parser/user/access/index.ts | 1 + .../user/data/RelationshipStatusInfo.ts | 67 + .../RelationshipStatusInfoMessageParser.ts | 46 + .../user/data/UserCurrentBadgesParser.ts | 46 + .../parser/user/data/UserFigureParser.ts | 35 + .../parser/user/data/UserInfoDataParser.ts | 139 + .../parser/user/data/UserInfoParser.ts | 30 + .../user/data/UserNameChangeMessageParser.ts | 43 + .../parser/user/data/UserProfileParser.ts | 130 + .../parser/user/data/UserSettingsParser.ts | 83 + .../parser/user/data/UserTagsParser.ts | 43 + .../src/messages/parser/user/data/index.ts | 10 + .../src/messages/parser/user/index.ts | 30 + .../inventory/currency/UserCreditsParser.ts | 27 + .../inventory/currency/UserCurrencyParser.ts | 34 + .../parser/user/inventory/currency/index.ts | 2 + .../messages/parser/user/inventory/index.ts | 2 + .../subscription/UserSubscriptionParser.ts | 113 + .../user/inventory/subscription/index.ts | 1 + .../user/wardrobe/UserWardrobePageParser.ts | 40 + .../messages/parser/user/wardrobe/index.ts | 1 + .../UserClassificationMessageParser.ts | 57 + .../parser/userclassification/index.ts | 1 + packages/communication/tsconfig.json | 31 + packages/configuration/.eslintrc.json | 3 + packages/configuration/.gitignore | 51 + packages/configuration/index.ts | 1 + packages/configuration/package.json | 20 + .../configuration/src/ConfigurationManager.ts | 167 + .../configuration/src/GetConfiguration.ts | 6 + .../src/IConfigurationManager.ts | 12 + packages/configuration/src/index.ts | 3 + packages/configuration/tsconfig.json | 31 + packages/eslint-config/.eslintrc.json | 128 + packages/eslint-config/.gitignore | 51 + packages/eslint-config/index.js | 1 + packages/eslint-config/package.json | 15 + packages/events/.eslintrc.json | 3 + packages/events/.gitignore | 51 + packages/events/index.ts | 1 + packages/events/package.json | 21 + packages/events/src/EventDispatcher.ts | 97 + packages/events/src/GetEventDispatcher.ts | 5 + packages/events/src/NitroEventType.ts | 16 + packages/events/src/NitroSettingsEvent.ts | 116 + packages/events/src/NitroSoundEvent.ts | 19 + .../src/NitroToolbarAnimateIconEvent.ts | 34 + packages/events/src/NitroToolbarEvent.ts | 35 + .../avatar/AvatarRenderEffectLibraryEvent.ts | 21 + .../src/avatar/AvatarRenderLibraryEvent.ts | 21 + packages/events/src/avatar/index.ts | 2 + .../camera/RoomCameraWidgetManagerEvent.ts | 11 + packages/events/src/camera/index.ts | 1 + .../NitroCommunicationDemoEvent.ts | 27 + packages/events/src/communication/index.ts | 1 + .../events/src/core/ConfigurationEvent.ts | 12 + packages/events/src/core/MessageEvent.ts | 55 + packages/events/src/core/NitroEvent.ts | 16 + .../events/src/core/SocketConnectionEvent.ts | 31 + packages/events/src/core/index.ts | 4 + packages/events/src/index.ts | 14 + .../src/room/RoomBackgroundColorEvent.ts | 34 + .../events/src/room/RoomContentLoadedEvent.ts | 22 + packages/events/src/room/RoomDragEvent.ts | 27 + .../src/room/RoomEngineDimmerStateEvent.ts | 48 + packages/events/src/room/RoomEngineEvent.ts | 26 + .../events/src/room/RoomEngineObjectEvent.ts | 39 + .../src/room/RoomEngineObjectPlacedEvent.ts | 74 + .../room/RoomEngineObjectPlacedOnUserEvent.ts | 25 + .../room/RoomEngineObjectPlaySoundEvent.ts | 28 + .../events/src/room/RoomEngineRoomAdEvent.ts | 9 + .../src/room/RoomEngineSamplePlaybackEvent.ts | 30 + .../src/room/RoomEngineTriggerWidgetEvent.ts | 58 + .../src/room/RoomEngineUseProductEvent.ts | 28 + .../src/room/RoomObjectBadgeAssetEvent.ts | 28 + .../src/room/RoomObjectDataRequestEvent.ts | 13 + .../room/RoomObjectDimmerStateUpdateEvent.ts | 49 + packages/events/src/room/RoomObjectEvent.ts | 33 + .../src/room/RoomObjectFloorHoleEvent.ts | 13 + .../room/RoomObjectFurnitureActionEvent.ts | 20 + .../src/room/RoomObjectHSLColorEnableEvent.ts | 42 + .../room/RoomObjectHSLColorEnabledEvent.ts | 41 + .../events/src/room/RoomObjectMouseEvent.ts | 100 + .../events/src/room/RoomObjectMoveEvent.ts | 13 + .../src/room/RoomObjectPlaySoundIdEvent.ts | 29 + .../events/src/room/RoomObjectRoomAdEvent.ts | 32 + .../src/room/RoomObjectSamplePlaybackEvent.ts | 31 + .../src/room/RoomObjectSoundMachineEvent.ts | 13 + .../src/room/RoomObjectStateChangedEvent.ts | 22 + .../src/room/RoomObjectTileMouseEvent.ts | 48 + .../src/room/RoomObjectWallMouseEvent.ts | 60 + .../src/room/RoomObjectWidgetRequestEvent.ts | 48 + .../events/src/room/RoomSpriteMouseEvent.ts | 117 + packages/events/src/room/RoomToObjectEvent.ts | 9 + .../room/RoomToObjectOwnAvatarMoveEvent.ts | 21 + packages/events/src/room/RoomZoomEvent.ts | 34 + packages/events/src/room/index.ts | 35 + .../src/session/BadgeImageReadyEvent.ts | 28 + .../src/session/MysteryBoxKeysUpdateEvent.ts | 27 + .../events/src/session/PerksUpdatedEvent.ts | 11 + .../src/session/RoomSessionChatEvent.ts | 69 + .../RoomSessionConfirmPetBreedingEvent.ts | 49 + ...oomSessionConfirmPetBreedingResultEvent.ts | 28 + .../src/session/RoomSessionDanceEvent.ts | 28 + .../session/RoomSessionDimmerPresetsEvent.ts | 45 + ...RoomSessionDimmerPresetsEventPresetItem.ts | 35 + .../src/session/RoomSessionDoorbellEvent.ts | 23 + .../session/RoomSessionErrorMessageEvent.ts | 32 + .../events/src/session/RoomSessionEvent.ts | 31 + .../RoomSessionFavoriteGroupUpdateEvent.ts | 42 + .../session/RoomSessionFriendRequestEvent.ts | 35 + .../RoomSessionNestBreedingSuccessEvent.ts | 28 + .../session/RoomSessionPetBreedingEvent.ts | 35 + .../RoomSessionPetBreedingResultEvent.ts | 28 + .../RoomSessionPetCommandsUpdateEvent.ts | 35 + .../RoomSessionPetFigureUpdateEvent.ts | 28 + .../session/RoomSessionPetInfoUpdateEvent.ts | 21 + .../session/RoomSessionPetLevelUpdateEvent.ts | 28 + .../src/session/RoomSessionPetPackageEvent.ts | 43 + .../RoomSessionPetStatusUpdateEvent.ts | 49 + .../src/session/RoomSessionPollEvent.ts | 100 + .../src/session/RoomSessionPresentEvent.ts | 64 + .../session/RoomSessionPropertyUpdateEvent.ts | 12 + .../src/session/RoomSessionQueueEvent.ts | 57 + .../session/RoomSessionSpectatorModeEvent.ts | 12 + .../src/session/RoomSessionUserBadgesEvent.ts | 29 + .../session/RoomSessionUserDataUpdateEvent.ts | 21 + .../RoomSessionUserFigureUpdateEvent.ts | 49 + .../src/session/RoomSessionUserTagsEvent.ts | 27 + .../src/session/RoomSessionVoteEvent.ts | 50 + .../src/session/RoomSessionWordQuizEvent.ts | 111 + .../session/SessionDataPreferencesEvent.ts | 20 + .../events/src/session/UserNameUpdateEvent.ts | 20 + packages/events/src/session/index.ts | 36 + .../events/src/sound/NotifyPlayedSongEvent.ts | 27 + packages/events/src/sound/NowPlayingEvent.ts | 35 + .../events/src/sound/PlayListStatusEvent.ts | 12 + .../sound/SongDiskInventoryReceivedEvent.ts | 11 + .../events/src/sound/SongInfoReceivedEvent.ts | 19 + .../events/src/sound/SoundManagerEvent.ts | 19 + packages/events/src/sound/index.ts | 6 + packages/events/tsconfig.json | 31 + packages/localization/.eslintrc.json | 3 + packages/localization/.gitignore | 51 + packages/localization/index.ts | 1 + packages/localization/package.json | 23 + .../localization/src/BadgeBaseAndLevel.ts | 53 + packages/localization/src/GetLocalization.ts | 5 + .../localization/src/LocalizationManager.ts | 304 ++ packages/localization/src/index.ts | 3 + packages/localization/tsconfig.json | 31 + packages/room/.eslintrc.json | 3 + packages/room/.gitignore | 51 + packages/room/index.ts | 1 + packages/room/package.json | 26 + packages/room/src/GetRoomContentLoader.ts | 5 + packages/room/src/GetRoomEngine.ts | 5 + packages/room/src/GetRoomManager.ts | 5 + packages/room/src/GetRoomMessageHandler.ts | 5 + .../room/src/GetRoomObjectLogicFactory.ts | 5 + .../src/GetRoomObjectVisualizationFactory.ts | 5 + packages/room/src/ImageResult.ts | 19 + packages/room/src/PetColorResult.ts | 61 + packages/room/src/RoomContentLoader.ts | 512 +++ packages/room/src/RoomEngine.ts | 3266 +++++++++++++++++ packages/room/src/RoomInstance.ts | 287 ++ packages/room/src/RoomManager.ts | 308 ++ packages/room/src/RoomMessageHandler.ts | 960 +++++ packages/room/src/RoomObjectEventHandler.ts | 2190 +++++++++++ packages/room/src/RoomObjectLogicFactory.ts | 315 ++ packages/room/src/RoomObjectManager.ts | 130 + .../src/RoomObjectVisualizationFactory.ts | 225 ++ packages/room/src/RoomPreviewer.ts | 858 +++++ packages/room/src/RoomVariableEnum.ts | 11 + packages/room/src/index.ts | 36 + .../src/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 + .../src/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 + .../src/messages/ObjectAvatarUpdateMessage.ts | 33 + .../ObjectAvatarUseObjectUpdateMessage.ts | 18 + .../src/messages/ObjectDataUpdateMessage.ts | 33 + .../messages/ObjectGroupBadgeUpdateMessage.ts | 27 + .../src/messages/ObjectHeightUpdateMessage.ts | 19 + .../messages/ObjectItemDataUpdateMessage.ts | 18 + .../messages/ObjectModelDataUpdateMessage.ts | 25 + .../src/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 + .../src/messages/ObjectRoomUpdateMessage.ts | 29 + .../src/messages/ObjectSelectedMessage.ts | 18 + .../src/messages/ObjectStateUpdateMessage.ts | 9 + .../messages/ObjectTileCursorUpdateMessage.ts | 40 + .../messages/ObjectVisibilityUpdateMessage.ts | 21 + .../src/messages/RoomObjectUpdateMessage.ts | 23 + packages/room/src/messages/index.ts | 41 + packages/room/src/object/RoomFloorHole.ts | 35 + packages/room/src/object/RoomMapData.ts | 90 + packages/room/src/object/RoomMapMaskData.ts | 16 + packages/room/src/object/RoomObject.ts | 229 ++ packages/room/src/object/RoomObjectModel.ts | 47 + .../src/object/RoomPlaneBitmapMaskData.ts | 56 + .../src/object/RoomPlaneBitmapMaskParser.ts | 147 + packages/room/src/object/RoomPlaneData.ts | 202 + packages/room/src/object/RoomPlaneMaskData.ts | 35 + packages/room/src/object/RoomPlaneParser.ts | 1661 +++++++++ packages/room/src/object/RoomWallData.ts | 182 + packages/room/src/object/index.ts | 22 + packages/room/src/object/logic/AvatarLogic.ts | 504 +++ .../src/object/logic/MovingObjectLogic.ts | 148 + packages/room/src/object/logic/PetLogic.ts | 238 ++ packages/room/src/object/logic/RoomLogic.ts | 453 +++ .../src/object/logic/RoomObjectLogicBase.ts | 120 + .../src/object/logic/SelectionArrowLogic.ts | 35 + .../room/src/object/logic/TileCursorLogic.ts | 64 + .../FurnitureAchievementResolutionLogic.ts | 71 + .../furniture/FurnitureBadgeDisplayLogic.ts | 63 + .../FurnitureChangeStateWhenStepOnLogic.ts | 53 + .../furniture/FurnitureClothingChangeLogic.ts | 47 + .../furniture/FurnitureCounterClockLogic.ts | 51 + .../furniture/FurnitureCrackableLogic.ts | 18 + .../furniture/FurnitureCraftingGizmoLogic.ts | 10 + .../logic/furniture/FurnitureCreditLogic.ts | 38 + .../furniture/FurnitureCuckooClockLogic.ts | 37 + .../FurnitureCustomStackHeightLogic.ts | 31 + .../logic/furniture/FurnitureDiceLogic.ts | 69 + .../furniture/FurnitureEcotronBoxLogic.ts | 21 + .../FurnitureEditableInternalLinkLogic.ts | 82 + .../FurnitureEditableRoomLinkLogic.ts | 76 + .../furniture/FurnitureEffectBoxLogic.ts | 27 + .../furniture/FurnitureExternalImageLogic.ts | 44 + .../furniture/FurnitureFireworksLogic.ts | 64 + .../furniture/FurnitureFloorHoleLogic.ts | 109 + .../furniture/FurnitureFriendFurniLogic.ts | 70 + .../FurnitureGroupForumTerminalLogic.ts | 31 + .../FurnitureGuildCustomizedLogic.ts | 93 + .../furniture/FurnitureHabboWheelLogic.ts | 19 + .../furniture/FurnitureHighScoreLogic.ts | 47 + .../furniture/FurnitureHockeyScoreLogic.ts | 59 + .../furniture/FurnitureHweenLovelockLogic.ts | 10 + .../logic/furniture/FurnitureIceStormLogic.ts | 71 + .../furniture/FurnitureInternalLinkLogic.ts | 78 + .../logic/furniture/FurnitureJukeboxLogic.ts | 97 + .../object/logic/furniture/FurnitureLogic.ts | 424 +++ .../logic/furniture/FurnitureLoveLockLogic.ts | 10 + .../furniture/FurnitureMannequinLogic.ts | 50 + .../FurnitureMonsterplantSeedLogic.ts | 25 + .../furniture/FurnitureMultiHeightLogic.ts | 12 + .../furniture/FurnitureMultiStateLogic.ts | 30 + .../furniture/FurnitureMysteryBoxLogic.ts | 25 + .../furniture/FurnitureMysteryTrophyLogic.ts | 25 + .../furniture/FurnitureOneWayDoorLogic.ts | 19 + .../FurniturePetCustomizationLogic.ts | 33 + .../furniture/FurniturePlaceholderLogic.ts | 21 + .../furniture/FurniturePlanetSystemLogic.ts | 18 + .../logic/furniture/FurniturePresentLogic.ts | 111 + .../FurniturePurchaseableClothingLogic.ts | 28 + .../logic/furniture/FurniturePushableLogic.ts | 113 + .../furniture/FurnitureRandomStateLogic.ts | 21 + .../furniture/FurnitureRandomTeleportLogic.ts | 10 + .../furniture/FurnitureRentableSpaceLogic.ts | 46 + .../FurnitureRoomBackgroundColorLogic.ts | 105 + .../furniture/FurnitureRoomBackgroundLogic.ts | 10 + .../furniture/FurnitureRoomBillboardLogic.ts | 31 + .../furniture/FurnitureRoomBrandingLogic.ts | 162 + .../furniture/FurnitureRoomDimmerLogic.ts | 140 + .../logic/furniture/FurnitureScoreLogic.ts | 70 + .../logic/furniture/FurnitureSongDiskLogic.ts | 19 + .../furniture/FurnitureSoundBlockLogic.ts | 119 + .../furniture/FurnitureSoundMachineLogic.ts | 88 + .../logic/furniture/FurnitureStickieLogic.ts | 60 + .../logic/furniture/FurnitureTrophyLogic.ts | 19 + .../furniture/FurnitureVoteCounterLogic.ts | 95 + .../furniture/FurnitureVoteMajorityLogic.ts | 20 + .../furniture/FurnitureWelcomeGiftLogic.ts | 18 + .../logic/furniture/FurnitureWindowLogic.ts | 20 + .../logic/furniture/FurnitureYoutubeLogic.ts | 33 + .../room/src/object/logic/furniture/index.ts | 62 + packages/room/src/object/logic/index.ts | 8 + .../object/visualization/RoomObjectSprite.ts | 355 ++ .../RoomObjectSpriteVisualization.ts | 286 ++ .../avatar/AvatarVisualization.ts | 1130 ++++++ .../avatar/AvatarVisualizationData.ts | 29 + .../avatar/additions/ExpressionAddition.ts | 42 + .../additions/ExpressionAdditionFactory.ts | 22 + .../avatar/additions/FloatingHeartAddition.ts | 157 + .../avatar/additions/FloatingIdleZAddition.ts | 155 + .../additions/GameClickTargetAddition.ts | 51 + .../additions/GuideStatusBubbleAddition.ts | 93 + .../avatar/additions/IAvatarAddition.ts | 9 + .../avatar/additions/IExpressionAddition.ts | 6 + .../avatar/additions/MutedBubbleAddition.ts | 77 + .../avatar/additions/NumberBubbleAddition.ts | 175 + .../avatar/additions/TypingBubbleAddition.ts | 95 + .../visualization/avatar/additions/index.ts | 11 + .../src/object/visualization/avatar/index.ts | 3 + .../visualization/data/AnimationData.ts | 191 + .../visualization/data/AnimationFrame.ts | 117 + .../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 | 197 + .../data/DirectionalOffsetData.ts | 35 + .../object/visualization/data/LayerData.ts | 105 + .../data/ParticleSystemParticle.ts | 9 + .../object/visualization/data/PetSizeData.ts | 130 + .../src/object/visualization/data/SizeData.ts | 285 ++ .../src/object/visualization/data/index.ts | 15 + .../FurnitureAnimatedVisualization.ts | 398 ++ .../FurnitureAnimatedVisualizationData.ts | 90 + .../furniture/FurnitureBBVisualization.ts | 19 + .../FurnitureBadgeDisplayVisualization.ts | 89 + .../furniture/FurnitureBottleVisualization.ts | 62 + .../FurnitureBrandedImageVisualization.ts | 210 ++ ...urnitureBuilderPlaceholderVisualization.ts | 6 + .../FurnitureCounterClockVisualization.ts | 29 + .../furniture/FurnitureCuboidVisualization.ts | 6 + .../FurnitureDynamicThumbnailVisualization.ts | 56 + .../FurnitureExternalImageVisualization.ts | 51 + .../FurnitureFireworksVisualization.ts | 110 + ...nitureGiftWrappedFireworksVisualization.ts | 78 + .../FurnitureGiftWrappedVisualization.ts | 60 + .../FurnitureGuildCustomizedVisualization.ts | 89 + ...rnitureGuildIsometricBadgeVisualization.ts | 144 + .../FurnitureHabboWheelVisualization.ts | 64 + .../FurnitureIsometricBBVisualization.ts | 75 + .../FurnitureMannequinVisualization.ts | 143 + .../FurnitureMannequinVisualizationData.ts | 32 + .../furniture/FurnitureParticleSystem.ts | 313 ++ .../FurnitureParticleSystemEmitter.ts | 277 ++ .../FurnitureParticleSystemParticle.ts | 196 + .../FurniturePartyBeamerVisualization.ts | 160 + .../FurniturePlanetSystemVisualization.ts | 134 + ...rePlanetSystemVisualizationPlanetObject.ts | 92 + .../furniture/FurniturePosterVisualization.ts | 6 + .../FurnitureQueueTileVisualization.ts | 50 + ...FurnitureResettingAnimatedVisualization.ts | 9 + .../FurnitureRoomBackgroundVisualization.ts | 64 + .../FurnitureScoreBoardVisualization.ts | 24 + .../FurnitureSoundBlockVisualization.ts | 16 + .../FurnitureStickieVisualization.ts | 12 + .../FurnitureValRandomizerVisualization.ts | 76 + .../furniture/FurnitureVisualization.ts | 594 +++ .../furniture/FurnitureVisualizationData.ts | 281 ++ .../FurnitureVoteCounterVisualization.ts | 51 + .../FurnitureVoteMajorityVisualization.ts | 45 + .../FurnitureWaterAreaVisualization.ts | 6 + .../FurnitureYoutubeVisualization.ts | 18 + .../IsometricImageFurniVisualization.ts | 172 + .../object/visualization/furniture/index.ts | 41 + .../room/src/object/visualization/index.ts | 10 + .../visualization/pet/ExperienceData.ts | 75 + .../visualization/pet/PetVisualization.ts | 594 +++ .../visualization/pet/PetVisualizationData.ts | 125 + .../src/object/visualization/pet/index.ts | 3 + .../visualization/room/PlaneDrawingData.ts | 103 + .../object/visualization/room/RoomPlane.ts | 636 ++++ .../visualization/room/RoomPlaneBitmapMask.ts | 28 + .../room/RoomPlaneRectangleMask.ts | 35 + .../visualization/room/RoomVisualization.ts | 812 ++++ .../room/RoomVisualizationData.ts | 47 + .../room/TileCursorVisualization.ts | 26 + .../src/object/visualization/room/index.ts | 9 + .../visualization/room/mask/PlaneMask.ts | 119 + .../room/mask/PlaneMaskBitmap.ts | 52 + .../room/mask/PlaneMaskManager.ts | 257 ++ .../room/mask/PlaneMaskVisualization.ts | 49 + .../object/visualization/room/mask/index.ts | 4 + .../room/utils/PlaneBitmapData.ts | 28 + .../visualization/room/utils/Randomizer.ts | 128 + .../object/visualization/room/utils/index.ts | 2 + packages/room/src/renderer/RoomRenderer.ts | 160 + .../room/src/renderer/RoomSpriteCanvas.ts | 1180 ++++++ .../src/renderer/cache/RoomObjectCache.ts | 142 + .../src/renderer/cache/RoomObjectCacheItem.ts | 52 + .../cache/RoomObjectLocationCacheItem.ts | 96 + .../RoomObjectSortableSpriteCacheItem.ts | 68 + packages/room/src/renderer/cache/index.ts | 4 + packages/room/src/renderer/index.ts | 4 + .../room/src/renderer/utils/ExtendedSprite.ts | 170 + .../src/renderer/utils/ObjectMouseData.ts | 31 + .../room/src/renderer/utils/SortableSprite.ts | 79 + packages/room/src/renderer/utils/index.ts | 3 + .../src/utils/FurnitureStackingHeightMap.ts | 121 + packages/room/src/utils/LegacyWallGeometry.ts | 322 ++ packages/room/src/utils/RoomCamera.ts | 288 ++ packages/room/src/utils/RoomData.ts | 59 + packages/room/src/utils/RoomEnterEffect.ts | 78 + packages/room/src/utils/RoomFurnitureData.ts | 119 + packages/room/src/utils/RoomGeometry.ts | 432 +++ packages/room/src/utils/RoomInstanceData.ts | 234 ++ .../RoomObjectBadgeImageAssetListener.ts | 23 + packages/room/src/utils/RoomRotatingEffect.ts | 75 + packages/room/src/utils/RoomShakingEffect.ts | 75 + .../room/src/utils/SelectedRoomObjectData.ts | 95 + .../room/src/utils/SpriteDataCollector.ts | 453 +++ packages/room/src/utils/TileObjectMap.ts | 122 + packages/room/src/utils/index.ts | 14 + packages/room/tsconfig.json | 31 + packages/session/.eslintrc.json | 3 + packages/session/.gitignore | 51 + packages/session/index.ts | 1 + packages/session/package.json | 25 + packages/session/src/GetRoomSessionManager.ts | 5 + packages/session/src/GetSessionDataManager.ts | 5 + .../session/src/GroupInformationManager.ts | 30 + packages/session/src/HabboClubLevelEnum.ts | 6 + packages/session/src/IgnoredUsersManager.ts | 88 + packages/session/src/RoomPetData.ts | 297 ++ packages/session/src/RoomSession.ts | 413 +++ packages/session/src/RoomSessionManager.ts | 173 + packages/session/src/RoomUserData.ts | 258 ++ packages/session/src/SessionDataManager.ts | 532 +++ packages/session/src/UserDataManager.ts | 184 + .../session/src/badge/BadgeImageManager.ts | 194 + packages/session/src/badge/BadgeInfo.ts | 23 + packages/session/src/badge/GroupBadge.ts | 23 + packages/session/src/badge/GroupBadgePart.ts | 66 + packages/session/src/badge/index.ts | 4 + .../session/src/furniture/FurnitureData.ts | 222 ++ .../src/furniture/FurnitureDataLoader.ts | 106 + packages/session/src/furniture/index.ts | 2 + packages/session/src/handler/BaseHandler.ts | 41 + .../src/handler/GenericErrorHandler.ts | 42 + .../session/src/handler/PetPackageHandler.ts | 45 + packages/session/src/handler/PollHandler.ts | 114 + .../session/src/handler/RoomChatHandler.ts | 173 + .../session/src/handler/RoomDataHandler.ts | 40 + .../src/handler/RoomDimmerPresetsHandler.ts | 44 + .../src/handler/RoomPermissionsHandler.ts | 48 + .../session/src/handler/RoomPresentHandler.ts | 33 + .../session/src/handler/RoomSessionHandler.ts | 113 + .../session/src/handler/RoomUsersHandler.ts | 475 +++ .../session/src/handler/WordQuizHandler.ts | 79 + packages/session/src/handler/index.ts | 12 + packages/session/src/index.ts | 15 + packages/session/src/product/ProductData.ts | 30 + .../session/src/product/ProductDataLoader.ts | 35 + packages/session/src/product/index.ts | 2 + packages/session/tsconfig.json | 31 + packages/sound/.eslintrc.json | 3 + packages/sound/.gitignore | 51 + packages/sound/index.ts | 1 + packages/sound/package.json | 21 + packages/sound/src/GetSoundManager.ts | 5 + packages/sound/src/SoundManager.ts | 194 + packages/sound/src/common/SongDataEntry.ts | 24 + .../sound/src/common/SongStartRequestData.ts | 51 + packages/sound/src/common/index.ts | 2 + packages/sound/src/index.ts | 5 + .../src/music/JukeboxPlaylistController.ts | 190 + packages/sound/src/music/MusicController.ts | 560 +++ packages/sound/src/music/MusicPlayer.ts | 240 ++ packages/sound/src/music/MusicPriorities.ts | 8 + packages/sound/src/music/index.ts | 3 + packages/sound/src/trax/TraxChannel.ts | 23 + packages/sound/src/trax/TraxChannelItem.ts | 21 + packages/sound/src/trax/TraxData.ts | 97 + packages/sound/src/trax/index.ts | 3 + packages/sound/tsconfig.json | 31 + packages/utils/.eslintrc.json | 3 + packages/utils/.gitignore | 51 + packages/utils/index.ts | 1 + packages/utils/package.json | 22 + packages/utils/src/AdvancedMap.ts | 159 + packages/utils/src/ArrayBufferToBase64.ts | 11 + packages/utils/src/BinaryReader.ts | 82 + packages/utils/src/BinaryWriter.ts | 109 + packages/utils/src/ColorConverter.ts | 354 ++ packages/utils/src/FurniId.ts | 9 + packages/utils/src/GetPixi.ts | 5 + packages/utils/src/GetRenderer.ts | 12 + packages/utils/src/GetStage.ts | 5 + packages/utils/src/GetTexturePool.ts | 5 + packages/utils/src/GetTicker.ts | 3 + packages/utils/src/GetTickerFPS.ts | 3 + packages/utils/src/GetTickerTime.ts | 3 + packages/utils/src/HabboWebTools.ts | 338 ++ packages/utils/src/Int32.ts | 13 + packages/utils/src/LegacyExternalInterface.ts | 118 + packages/utils/src/LinkTracker.ts | 40 + packages/utils/src/Matrix4x4.ts | 134 + packages/utils/src/NitroBundle.ts | 58 + packages/utils/src/NitroConfig.ts | 9 + packages/utils/src/NitroLogger.ts | 48 + packages/utils/src/NitroVersion.ts | 31 + packages/utils/src/Node3D.ts | 32 + packages/utils/src/NumberBank.ts | 54 + packages/utils/src/PointMath.ts | 19 + packages/utils/src/RoomId.ts | 14 + packages/utils/src/TexturePool.ts | 105 + packages/utils/src/TextureUtils.ts | 135 + packages/utils/src/Vector3d.ts | 215 ++ .../utils/src/filters/PaletteMapFilter.ts | 147 + packages/utils/src/filters/PlaneMaskFilter.ts | 90 + packages/utils/src/filters/WiredFilter.ts | 143 + packages/utils/src/filters/index.ts | 3 + packages/utils/src/index.ts | 31 + packages/utils/src/motion/Callback.ts | 30 + packages/utils/src/motion/Combo.ts | 61 + packages/utils/src/motion/Dispose.ts | 21 + packages/utils/src/motion/DropBounce.ts | 60 + packages/utils/src/motion/Ease.ts | 34 + packages/utils/src/motion/EaseOut.ts | 15 + packages/utils/src/motion/EaseRate.ts | 14 + packages/utils/src/motion/Interval.ts | 47 + packages/utils/src/motion/JumpBy.ts | 37 + packages/utils/src/motion/Motion.ts | 61 + packages/utils/src/motion/Motions.ts | 194 + packages/utils/src/motion/MoveBy.ts | 17 + packages/utils/src/motion/MoveTo.ts | 35 + packages/utils/src/motion/Queue.ts | 71 + packages/utils/src/motion/ResizeTo.ts | 35 + packages/utils/src/motion/Wait.ts | 37 + packages/utils/src/motion/index.ts | 16 + packages/utils/tsconfig.json | 31 + public/android-chrome-192x192.png | Bin 9604 -> 0 bytes public/android-chrome-512x512.png | Bin 29298 -> 0 bytes public/apple-touch-icon.png | Bin 8241 -> 0 bytes public/browserconfig.xml | 9 - public/favicon-16x16.png | Bin 1017 -> 0 bytes public/favicon-32x32.png | Bin 1778 -> 0 bytes public/favicon.ico | Bin 15086 -> 0 bytes public/mstile-150x150.png | Bin 6600 -> 0 bytes public/robots.txt | 3 - public/safari-pinned-tab.svg | 154 - public/site.webmanifest | 20 - src/App.scss | 102 - src/App.tsx | 102 - src/DevTools.ts | 25 + src/api/GetRendererVersion.ts | 3 - src/api/GetUIVersion.ts | 1 - src/api/achievements/AchievementCategory.ts | 40 - src/api/achievements/AchievementUtilities.ts | 97 - src/api/achievements/IAchievementCategory.ts | 7 - src/api/achievements/index.ts | 3 - src/api/avatar/AvatarEditorAction.ts | 7 - src/api/avatar/AvatarEditorGridColorItem.ts | 65 - src/api/avatar/AvatarEditorGridPartItem.ts | 336 -- .../avatar/AvatarEditorThumbnailsHelper.ts | 189 - src/api/avatar/AvatarEditorUtilities.ts | 277 -- src/api/avatar/BodyModel.ts | 75 - src/api/avatar/CategoryBaseModel.ts | 246 -- src/api/avatar/CategoryData.ts | 487 --- src/api/avatar/FigureData.ts | 287 -- src/api/avatar/FigureGenerator.ts | 89 - src/api/avatar/HeadModel.ts | 24 - src/api/avatar/IAvatarEditorCategory.ts | 9 - src/api/avatar/IAvatarEditorCategoryModel.ts | 19 - .../avatar/IAvatarEditorCategoryPartItem.ts | 10 - src/api/avatar/LegModel.ts | 22 - src/api/avatar/TorsoModel.ts | 23 - src/api/avatar/index.ts | 16 - src/api/camera/CameraEditorTabs.ts | 5 - src/api/camera/CameraPicture.ts | 9 - src/api/camera/CameraPictureThumbnail.ts | 7 - src/api/camera/index.ts | 3 - src/api/campaign/CalendarItem.ts | 30 - src/api/campaign/CalendarItemState.ts | 7 - src/api/campaign/ICalendarItem.ts | 6 - src/api/campaign/index.ts | 3 - .../catalog/BuilderFurniPlaceableStatus.ts | 10 - src/api/catalog/CatalogNode.ts | 124 - src/api/catalog/CatalogPage.ts | 59 - src/api/catalog/CatalogPageName.ts | 26 - src/api/catalog/CatalogPetPalette.ts | 10 - src/api/catalog/CatalogPurchaseState.ts | 10 - src/api/catalog/CatalogType.ts | 5 - src/api/catalog/CatalogUtilities.ts | 124 - src/api/catalog/FurnitureOffer.ts | 120 - src/api/catalog/GetImageIconUrlForProduct.ts | 19 - src/api/catalog/GiftWrappingConfiguration.ts | 51 - src/api/catalog/ICatalogNode.ts | 21 - src/api/catalog/ICatalogOptions.ts | 13 - src/api/catalog/ICatalogPage.ts | 12 - src/api/catalog/IMarketplaceSearchOptions.ts | 7 - src/api/catalog/IPageLocalization.ts | 5 - src/api/catalog/IProduct.ts | 16 - src/api/catalog/IPurchasableOffer.ts | 25 - src/api/catalog/IPurchaseOptions.ts | 9 - src/api/catalog/MarketplaceOfferState.ts | 7 - src/api/catalog/MarketplaceSearchType.ts | 6 - src/api/catalog/Offer.ts | 245 -- src/api/catalog/PageLocalization.ts | 36 - src/api/catalog/PlacedObjectPurchaseData.ts | 41 - src/api/catalog/Product.ts | 143 - src/api/catalog/ProductTypeEnum.ts | 11 - src/api/catalog/RequestedPage.ts | 63 - src/api/catalog/SearchResult.ts | 11 - src/api/catalog/index.ts | 29 - src/api/chat-history/ChatEntryType.ts | 6 - .../chat-history/ChatHistoryCurrentDate.ts | 6 - src/api/chat-history/IChatEntry.ts | 17 - src/api/chat-history/IRoomHistoryEntry.ts | 5 - .../MessengerHistoryCurrentDate.ts | 6 - src/api/chat-history/index.ts | 5 - src/api/events/DispatchEvent.ts | 3 - src/api/events/DispatchMainEvent.ts | 4 - src/api/events/DispatchUiEvent.ts | 5 - src/api/events/UI_EVENT_DISPATCHER.ts | 3 - src/api/events/index.ts | 4 - src/api/friends/GetGroupChatData.ts | 13 - src/api/friends/IGroupChatData.ts | 6 - src/api/friends/MessengerFriend.ts | 43 - src/api/friends/MessengerGroupType.ts | 5 - src/api/friends/MessengerIconState.ts | 6 - src/api/friends/MessengerRequest.ts | 41 - src/api/friends/MessengerSettings.ts | 11 - src/api/friends/MessengerThread.ts | 96 - src/api/friends/MessengerThreadChat.ts | 54 - src/api/friends/MessengerThreadChatGroup.ts | 41 - src/api/friends/OpenMessengerChat.ts | 7 - src/api/friends/index.ts | 11 - src/api/groups/GetGroupInformation.ts | 7 - src/api/groups/GetGroupManager.ts | 6 - src/api/groups/GetGroupMembers.ts | 7 - src/api/groups/GroupBadgePart.ts | 30 - src/api/groups/GroupMembershipType.ts | 6 - src/api/groups/GroupType.ts | 6 - src/api/groups/IGroupCustomize.ts | 8 - src/api/groups/IGroupData.ts | 13 - src/api/groups/ToggleFavoriteGroup.ts | 7 - src/api/groups/TryJoinGroup.ts | 4 - src/api/groups/index.ts | 10 - src/api/guide-tool/GuideSessionState.ts | 23 - src/api/guide-tool/GuideToolMessage.ts | 21 - src/api/guide-tool/GuideToolMessageGroup.ts | 28 - src/api/guide-tool/index.ts | 3 - src/api/hc-center/ClubStatus.ts | 6 - src/api/hc-center/GetClubBadge.ts | 11 - src/api/hc-center/index.ts | 2 - src/api/help/CallForHelpResult.ts | 5 - src/api/help/GetCloseReasonKey.ts | 8 - src/api/help/IHelpReport.ts | 19 - src/api/help/IReportedUser.ts | 5 - src/api/help/ReportState.ts | 8 - src/api/help/ReportType.ts | 11 - src/api/help/index.ts | 6 - src/api/index.ts | 28 - src/api/inventory/FurniCategory.ts | 26 - src/api/inventory/FurnitureItem.ts | 245 -- src/api/inventory/FurnitureUtilities.ts | 171 - src/api/inventory/GroupItem.ts | 461 --- src/api/inventory/IBotItem.ts | 6 - src/api/inventory/IFurnitureItem.ts | 17 - src/api/inventory/IPetItem.ts | 6 - src/api/inventory/IUnseenItemTracker.ts | 12 - src/api/inventory/InventoryUtilities.ts | 117 - src/api/inventory/PetUtilities.ts | 103 - src/api/inventory/TradeState.ts | 10 - src/api/inventory/TradeUserData.ts | 15 - src/api/inventory/TradingNotificationType.ts | 12 - src/api/inventory/TradingUtilities.ts | 70 - src/api/inventory/UnseenItemCategory.ts | 9 - src/api/inventory/index.ts | 15 - src/api/mod-tools/GetIssueCategoryName.ts | 35 - src/api/mod-tools/ISelectedUser.ts | 5 - src/api/mod-tools/IUserInfo.ts | 6 - src/api/mod-tools/ModActionDefinition.ts | 49 - src/api/mod-tools/index.ts | 4 - src/api/navigator/DoorStateType.ts | 12 - src/api/navigator/INavigatorData.ts | 17 - src/api/navigator/INavigatorSearchFilter.ts | 5 - src/api/navigator/IRoomChatSettings.ts | 8 - src/api/navigator/IRoomData.ts | 23 - src/api/navigator/IRoomModel.ts | 6 - src/api/navigator/IRoomModerationSettings.ts | 6 - .../NavigatorSearchResultViewDisplayMode.ts | 6 - src/api/navigator/RoomInfoData.ts | 60 - src/api/navigator/RoomSettingsUtils.ts | 10 - src/api/navigator/SearchFilterOptions.ts | 24 - src/api/navigator/TryVisitRoom.ts | 7 - src/api/navigator/index.ts | 12 - src/api/nitro/GetConfigurationValue.ts | 6 - src/api/nitro/OpenUrl.ts | 15 - src/api/nitro/SendMessageComposer.ts | 3 - src/api/nitro/index.ts | 5 - src/api/nitro/room/DispatchMouseEvent.ts | 54 - src/api/nitro/room/DispatchTouchEvent.ts | 81 - src/api/nitro/room/GetOwnRoomObject.ts | 31 - src/api/nitro/room/GetRoomObjectBounds.ts | 13 - .../nitro/room/GetRoomObjectScreenLocation.ts | 13 - .../InitializeRoomInstanceRenderingCanvas.ts | 9 - .../room/IsFurnitureSelectionDisabled.ts | 22 - .../nitro/room/ProcessRoomObjectOperation.ts | 6 - src/api/nitro/room/SetActiveRoomId.ts | 6 - src/api/nitro/room/index.ts | 9 - .../nitro/session/CanManipulateFurniture.ts | 9 - src/api/nitro/session/CreateRoomSession.ts | 6 - src/api/nitro/session/GetCanStandUp.ts | 13 - src/api/nitro/session/GetCanUseExpression.ts | 14 - src/api/nitro/session/GetClubMemberLevel.ts | 9 - src/api/nitro/session/GetFurnitureData.ts | 19 - .../GetFurnitureDataForProductOffer.ts | 20 - .../session/GetFurnitureDataForRoomObject.ts | 20 - src/api/nitro/session/GetOwnPosture.ts | 13 - .../session/GetProductDataForLocalization.ts | 8 - src/api/nitro/session/GetRoomSession.ts | 3 - src/api/nitro/session/GoToDesktop.ts | 7 - src/api/nitro/session/HasHabboClub.ts | 6 - src/api/nitro/session/HasHabboVip.ts | 6 - .../nitro/session/IsOwnerOfFloorFurniture.ts | 14 - src/api/nitro/session/IsOwnerOfFurniture.ts | 11 - src/api/nitro/session/IsRidingHorse.ts | 14 - src/api/nitro/session/StartRoomSession.ts | 6 - src/api/nitro/session/VisitDesktop.ts | 11 - src/api/nitro/session/index.ts | 19 - src/api/notification/NotificationAlertItem.ts | 67 - src/api/notification/NotificationAlertType.ts | 10 - .../notification/NotificationBubbleItem.ts | 48 - .../notification/NotificationBubbleType.ts | 19 - .../notification/NotificationConfirmItem.ts | 67 - .../notification/NotificationConfirmType.ts | 4 - src/api/notification/index.ts | 6 - src/api/purse/IPurse.ts | 15 - src/api/purse/Purse.ts | 165 - src/api/purse/index.ts | 2 - .../room/events/RoomWidgetPollUpdateEvent.ts | 110 - ...WidgetUpdateBackgroundColorPreviewEvent.ts | 35 - .../RoomWidgetUpdateChatInputContentEvent.ts | 29 - src/api/room/events/RoomWidgetUpdateEvent.ts | 4 - .../RoomWidgetUpdateRentableBotChatEvent.ts | 62 - .../events/RoomWidgetUpdateRoomObjectEvent.ts | 43 - src/api/room/events/index.ts | 6 - src/api/room/index.ts | 2 - src/api/room/widgets/AvatarInfoFurni.ts | 37 - src/api/room/widgets/AvatarInfoName.ts | 11 - src/api/room/widgets/AvatarInfoPet.ts | 46 - src/api/room/widgets/AvatarInfoRentableBot.ts | 23 - src/api/room/widgets/AvatarInfoUser.ts | 49 - src/api/room/widgets/AvatarInfoUtilities.ts | 439 --- src/api/room/widgets/BotSkillsEnum.ts | 18 - src/api/room/widgets/ChatBubbleMessage.ts | 54 - src/api/room/widgets/ChatBubbleUtilities.ts | 69 - src/api/room/widgets/ChatMessageTypeEnum.ts | 6 - .../DimmerFurnitureWidgetPresetItem.ts | 9 - src/api/room/widgets/DoChatsOverlap.ts | 7 - .../room/widgets/FurnitureDimmerUtilities.ts | 30 - src/api/room/widgets/GetDiskColor.ts | 37 - src/api/room/widgets/IAvatarInfo.ts | 4 - src/api/room/widgets/ICraftingIngredient.ts | 6 - src/api/room/widgets/ICraftingRecipe.ts | 6 - src/api/room/widgets/IPhotoData.ts | 42 - src/api/room/widgets/MannequinUtilities.ts | 38 - src/api/room/widgets/PetSupplementEnum.ts | 5 - src/api/room/widgets/PostureTypeEnum.ts | 5 - src/api/room/widgets/RoomDimmerPreset.ts | 35 - src/api/room/widgets/RoomObjectItem.ts | 28 - src/api/room/widgets/UseProductItem.ts | 12 - src/api/room/widgets/VoteValue.ts | 8 - .../widgets/YoutubeVideoPlaybackStateEnum.ts | 9 - src/api/room/widgets/index.ts | 26 - src/api/user/GetUserProfile.ts | 7 - src/api/user/index.ts | 1 - src/api/utils/CloneObject.ts | 14 - src/api/utils/ColorUtils.ts | 65 - src/api/utils/ConvertSeconds.ts | 9 - src/api/utils/FixedSizeStack.ts | 65 - src/api/utils/FriendlyTime.ts | 47 - src/api/utils/GetLocalStorage.ts | 11 - src/api/utils/LocalStorageKeys.ts | 5 - src/api/utils/LocalizeBadgeDescription.ts | 10 - src/api/utils/LocalizeBageName.ts | 10 - src/api/utils/LocalizeFormattedNumber.ts | 6 - src/api/utils/LocalizeShortNumber.ts | 36 - src/api/utils/LocalizeText.ts | 6 - src/api/utils/PlaySound.ts | 24 - src/api/utils/ProductImageUtility.ts | 58 - src/api/utils/Randomizer.ts | 28 - src/api/utils/RoomChatFormatter.ts | 75 - src/api/utils/SetLocalStorage.ts | 1 - src/api/utils/SoundNames.ts | 9 - src/api/utils/WindowSaveOptions.ts | 5 - src/api/utils/index.ts | 19 - src/api/wired/GetWiredTimeLocale.ts | 8 - src/api/wired/WiredActionLayoutCode.ts | 29 - src/api/wired/WiredConditionLayoutCode.ts | 29 - src/api/wired/WiredDateToString.ts | 1 - src/api/wired/WiredFurniType.ts | 7 - src/api/wired/WiredSelectionVisualizer.ts | 85 - src/api/wired/WiredStringDelimeter.ts | 1 - src/api/wired/WiredTriggerLayoutCode.ts | 17 - src/api/wired/index.ts | 8 - src/assets/images/achievements/back-arrow.png | Bin 331 -> 0 bytes .../images/avatareditor/arrow-left-icon.png | Bin 198 -> 0 bytes .../images/avatareditor/arrow-right-icon.png | Bin 192 -> 0 bytes .../avatar-editor-spritesheet.png | Bin 23260 -> 0 bytes src/assets/images/avatareditor/ca-icon.png | Bin 259 -> 0 bytes .../images/avatareditor/ca-selected-icon.png | Bin 335 -> 0 bytes src/assets/images/avatareditor/cc-icon.png | Bin 282 -> 0 bytes .../images/avatareditor/cc-selected-icon.png | Bin 338 -> 0 bytes src/assets/images/avatareditor/ch-icon.png | Bin 228 -> 0 bytes .../images/avatareditor/ch-selected-icon.png | Bin 260 -> 0 bytes src/assets/images/avatareditor/clear-icon.png | Bin 272 -> 0 bytes src/assets/images/avatareditor/cp-icon.png | Bin 252 -> 0 bytes .../images/avatareditor/cp-selected-icon.png | Bin 280 -> 0 bytes src/assets/images/avatareditor/ea-icon.png | Bin 251 -> 0 bytes .../images/avatareditor/ea-selected-icon.png | Bin 298 -> 0 bytes src/assets/images/avatareditor/fa-icon.png | Bin 234 -> 0 bytes .../images/avatareditor/fa-selected-icon.png | Bin 286 -> 0 bytes .../images/avatareditor/female-icon.png | Bin 236 -> 0 bytes .../avatareditor/female-selected-icon.png | Bin 270 -> 0 bytes src/assets/images/avatareditor/ha-icon.png | Bin 241 -> 0 bytes .../images/avatareditor/ha-selected-icon.png | Bin 285 -> 0 bytes src/assets/images/avatareditor/he-icon.png | Bin 267 -> 0 bytes .../images/avatareditor/he-selected-icon.png | Bin 338 -> 0 bytes src/assets/images/avatareditor/hr-icon.png | Bin 257 -> 0 bytes .../images/avatareditor/hr-selected-icon.png | Bin 348 -> 0 bytes src/assets/images/avatareditor/lg-icon.png | Bin 196 -> 0 bytes .../images/avatareditor/lg-selected-icon.png | Bin 236 -> 0 bytes .../images/avatareditor/loading-icon.png | Bin 181 -> 0 bytes src/assets/images/avatareditor/male-icon.png | Bin 228 -> 0 bytes .../avatareditor/male-selected-icon.png | Bin 256 -> 0 bytes .../images/avatareditor/sellable-icon.png | Bin 229 -> 0 bytes src/assets/images/avatareditor/sh-icon.png | Bin 208 -> 0 bytes .../images/avatareditor/sh-selected-icon.png | Bin 266 -> 0 bytes .../images/avatareditor/spotlight-icon.png | Bin 11373 -> 0 bytes src/assets/images/avatareditor/wa-icon.png | Bin 257 -> 0 bytes .../images/avatareditor/wa-selected-icon.png | Bin 308 -> 0 bytes src/assets/images/campaign/available.png | Bin 1118 -> 0 bytes .../campaign/campaign_day_generic_bg.png | Bin 36045 -> 0 bytes .../images/campaign/campaign_opened.png | Bin 744 -> 0 bytes .../images/campaign/campaign_spritesheet.png | Bin 83689 -> 0 bytes src/assets/images/campaign/locked.png | Bin 220 -> 0 bytes src/assets/images/campaign/locked_bg.png | Bin 5414 -> 0 bytes src/assets/images/campaign/next.png | Bin 244 -> 0 bytes src/assets/images/campaign/prev.png | Bin 235 -> 0 bytes src/assets/images/campaign/unavailable.png | Bin 448 -> 0 bytes src/assets/images/campaign/unlocked_bg.png | Bin 8798 -> 0 bytes .../catalog/diamond_info_illustration.gif | Bin 3883 -> 0 bytes src/assets/images/catalog/hc_banner_big.png | Bin 3539 -> 0 bytes src/assets/images/catalog/hc_big.png | Bin 2596 -> 0 bytes src/assets/images/catalog/hc_small.png | Bin 2208 -> 0 bytes src/assets/images/catalog/paint-icon.png | Bin 262 -> 0 bytes src/assets/images/catalog/target-price.png | Bin 3562 -> 0 bytes src/assets/images/catalog/vip.png | Bin 521 -> 0 bytes .../images/chat/chatbubbles/bubble_0.png | Bin 5025 -> 0 bytes .../chatbubbles/bubble_0_1_33_34_pointer.png | Bin 127 -> 0 bytes .../chat/chatbubbles/bubble_0_transparent.png | Bin 256 -> 0 bytes .../images/chat/chatbubbles/bubble_1.png | Bin 449 -> 0 bytes .../images/chat/chatbubbles/bubble_10.png | Bin 778 -> 0 bytes .../chat/chatbubbles/bubble_10_pointer.png | Bin 138 -> 0 bytes .../images/chat/chatbubbles/bubble_11.png | Bin 242 -> 0 bytes .../chat/chatbubbles/bubble_11_pointer.png | Bin 104 -> 0 bytes .../images/chat/chatbubbles/bubble_12.png | Bin 242 -> 0 bytes .../chat/chatbubbles/bubble_12_pointer.png | Bin 104 -> 0 bytes .../images/chat/chatbubbles/bubble_13.png | Bin 397 -> 0 bytes .../chat/chatbubbles/bubble_13_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_14.png | Bin 234 -> 0 bytes .../chat/chatbubbles/bubble_14_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_15.png | Bin 247 -> 0 bytes .../chat/chatbubbles/bubble_15_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_16.png | Bin 716 -> 0 bytes .../chat/chatbubbles/bubble_16_pointer.png | Bin 149 -> 0 bytes .../images/chat/chatbubbles/bubble_17.png | Bin 806 -> 0 bytes .../chat/chatbubbles/bubble_17_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_18.png | Bin 247 -> 0 bytes .../chat/chatbubbles/bubble_18_pointer.png | Bin 119 -> 0 bytes .../images/chat/chatbubbles/bubble_19.png | Bin 688 -> 0 bytes .../chat/chatbubbles/bubble_19_20_pointer.png | Bin 110 -> 0 bytes .../images/chat/chatbubbles/bubble_2.png | Bin 436 -> 0 bytes .../images/chat/chatbubbles/bubble_20.png | Bin 417 -> 0 bytes .../images/chat/chatbubbles/bubble_21.png | Bin 584 -> 0 bytes .../chat/chatbubbles/bubble_21_pointer.png | Bin 109 -> 0 bytes .../images/chat/chatbubbles/bubble_22.png | Bin 650 -> 0 bytes .../chat/chatbubbles/bubble_22_pointer.png | Bin 109 -> 0 bytes .../images/chat/chatbubbles/bubble_23.png | Bin 332 -> 0 bytes .../chat/chatbubbles/bubble_23_37_pointer.png | Bin 104 -> 0 bytes .../images/chat/chatbubbles/bubble_24.png | Bin 380 -> 0 bytes .../chat/chatbubbles/bubble_24_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_25.png | Bin 280 -> 0 bytes .../chat/chatbubbles/bubble_25_pointer.png | Bin 131 -> 0 bytes .../images/chat/chatbubbles/bubble_26.png | Bin 557 -> 0 bytes .../chat/chatbubbles/bubble_26_pointer.png | Bin 149 -> 0 bytes .../images/chat/chatbubbles/bubble_27.png | Bin 632 -> 0 bytes .../chat/chatbubbles/bubble_27_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_28.png | Bin 758 -> 0 bytes .../chat/chatbubbles/bubble_28_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_29.png | Bin 476 -> 0 bytes .../chat/chatbubbles/bubble_29_pointer.png | Bin 102 -> 0 bytes .../chat/chatbubbles/bubble_2_31_pointer.png | Bin 178 -> 0 bytes .../images/chat/chatbubbles/bubble_3.png | Bin 236 -> 0 bytes .../images/chat/chatbubbles/bubble_30.png | Bin 427 -> 0 bytes .../chat/chatbubbles/bubble_30_pointer.png | Bin 143 -> 0 bytes .../images/chat/chatbubbles/bubble_32.png | Bin 399 -> 0 bytes .../chat/chatbubbles/bubble_32_pointer.png | Bin 144 -> 0 bytes .../images/chat/chatbubbles/bubble_33_34.png | Bin 344 -> 0 bytes .../chat/chatbubbles/bubble_33_extra.png | Bin 542 -> 0 bytes .../chat/chatbubbles/bubble_34_extra.png | Bin 310 -> 0 bytes .../images/chat/chatbubbles/bubble_35.png | Bin 869 -> 0 bytes .../chat/chatbubbles/bubble_35_pointer.png | Bin 126 -> 0 bytes .../images/chat/chatbubbles/bubble_36.png | Bin 266 -> 0 bytes .../chat/chatbubbles/bubble_36_extra.png | Bin 239 -> 0 bytes .../chat/chatbubbles/bubble_36_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_37.png | Bin 376 -> 0 bytes .../images/chat/chatbubbles/bubble_38.png | Bin 276 -> 0 bytes .../chat/chatbubbles/bubble_38_extra.png | Bin 228 -> 0 bytes .../chat/chatbubbles/bubble_38_pointer.png | Bin 105 -> 0 bytes .../chat/chatbubbles/bubble_3_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_4.png | Bin 242 -> 0 bytes .../chat/chatbubbles/bubble_4_pointer.png | Bin 104 -> 0 bytes .../images/chat/chatbubbles/bubble_5.png | Bin 372 -> 0 bytes .../chat/chatbubbles/bubble_5_pointer.png | Bin 104 -> 0 bytes .../images/chat/chatbubbles/bubble_6.png | Bin 402 -> 0 bytes .../chat/chatbubbles/bubble_6_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_7.png | Bin 231 -> 0 bytes .../chat/chatbubbles/bubble_7_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_8.png | Bin 1206 -> 0 bytes .../chat/chatbubbles/bubble_8_pointer.png | Bin 105 -> 0 bytes .../images/chat/chatbubbles/bubble_9.png | Bin 499 -> 0 bytes .../chat/chatbubbles/bubble_9_pointer.png | Bin 146 -> 0 bytes src/assets/images/chat/styles-icon.png | Bin 314 -> 0 bytes .../floorplaneditor/door-direction-0.png | Bin 742 -> 0 bytes .../floorplaneditor/door-direction-1.png | Bin 738 -> 0 bytes .../floorplaneditor/door-direction-2.png | Bin 750 -> 0 bytes .../floorplaneditor/door-direction-3.png | Bin 697 -> 0 bytes .../floorplaneditor/door-direction-4.png | Bin 756 -> 0 bytes .../floorplaneditor/door-direction-5.png | Bin 754 -> 0 bytes .../floorplaneditor/door-direction-6.png | Bin 747 -> 0 bytes .../floorplaneditor/door-direction-7.png | Bin 698 -> 0 bytes .../images/floorplaneditor/icon-door.png | Bin 806 -> 0 bytes .../images/floorplaneditor/icon-tile-down.png | Bin 609 -> 0 bytes .../images/floorplaneditor/icon-tile-set.png | Bin 525 -> 0 bytes .../floorplaneditor/icon-tile-unset.png | Bin 544 -> 0 bytes .../images/floorplaneditor/icon-tile-up.png | Bin 555 -> 0 bytes .../images/floorplaneditor/preview_tile.png | Bin 146 -> 0 bytes .../floorplaneditor/selected_height_icon.png | Bin 175 -> 0 bytes .../images/friends/friends-spritesheet.png | Bin 3494 -> 0 bytes src/assets/images/friends/icon-accept.png | Bin 174 -> 0 bytes src/assets/images/friends/icon-add.png | Bin 205 -> 0 bytes src/assets/images/friends/icon-bobba.png | Bin 169 -> 0 bytes src/assets/images/friends/icon-chat.png | Bin 199 -> 0 bytes src/assets/images/friends/icon-deny.png | Bin 173 -> 0 bytes src/assets/images/friends/icon-follow.png | Bin 162 -> 0 bytes .../images/friends/icon-friendbar-chat.png | Bin 1740 -> 0 bytes .../images/friends/icon-friendbar-visit.png | Bin 2150 -> 0 bytes src/assets/images/friends/icon-heart.png | Bin 201 -> 0 bytes .../images/friends/icon-new-message.png | Bin 219 -> 0 bytes src/assets/images/friends/icon-none.png | Bin 177 -> 0 bytes .../images/friends/icon-profile-sm-hover.png | Bin 264 -> 0 bytes src/assets/images/friends/icon-profile-sm.png | Bin 257 -> 0 bytes src/assets/images/friends/icon-profile.png | Bin 1819 -> 0 bytes src/assets/images/friends/icon-smile.png | Bin 205 -> 0 bytes src/assets/images/friends/icon-warning.png | Bin 225 -> 0 bytes .../friends/messenger_notification_icon.png | Bin 164 -> 0 bytes src/assets/images/gamecenter/selectedIcon.png | Bin 248 -> 0 bytes src/assets/images/gift/gift_tag.png | Bin 795 -> 0 bytes src/assets/images/gift/incognito.png | Bin 1057 -> 0 bytes src/assets/images/groups/creator_images.png | Bin 7966 -> 0 bytes src/assets/images/groups/creator_tabs.png | Bin 1215 -> 0 bytes .../groups/icons/group_decorate_icon.png | Bin 311 -> 0 bytes .../images/groups/icons/group_favorite.png | Bin 198 -> 0 bytes .../images/groups/icons/group_icon_admin.png | Bin 203 -> 0 bytes .../groups/icons/group_icon_big_admin.png | Bin 429 -> 0 bytes .../groups/icons/group_icon_big_member.png | Bin 447 -> 0 bytes .../groups/icons/group_icon_big_owner.png | Bin 460 -> 0 bytes .../groups/icons/group_icon_not_admin.png | Bin 198 -> 0 bytes .../groups/icons/group_icon_small_owner.png | Bin 215 -> 0 bytes .../images/groups/icons/group_notfavorite.png | Bin 175 -> 0 bytes .../images/groups/icons/grouptype_icon_0.png | Bin 542 -> 0 bytes .../images/groups/icons/grouptype_icon_1.png | Bin 349 -> 0 bytes .../images/groups/icons/grouptype_icon_2.png | Bin 373 -> 0 bytes src/assets/images/groups/no-group-1.png | Bin 5007 -> 0 bytes src/assets/images/groups/no-group-2.png | Bin 4401 -> 0 bytes src/assets/images/groups/no-group-3.png | Bin 4566 -> 0 bytes .../images/groups/no-group-spritesheet.png | Bin 29386 -> 0 bytes .../guide-tool/guide_tool_duty_switch.png | Bin 537 -> 0 bytes .../guide-tool/guide_tool_info_icon.png | Bin 184 -> 0 bytes src/assets/images/hc-center/benefits.png | Bin 14475 -> 0 bytes src/assets/images/hc-center/clock.png | Bin 267 -> 0 bytes src/assets/images/hc-center/hc_logo.gif | Bin 1251 -> 0 bytes src/assets/images/hc-center/payday.png | Bin 721 -> 0 bytes src/assets/images/help/help_index.png | Bin 2569 -> 0 bytes src/assets/images/icons/arrows.png | Bin 222 -> 0 bytes .../images/icons/camera-colormatrix.png | Bin 249 -> 0 bytes src/assets/images/icons/camera-composite.png | Bin 204 -> 0 bytes src/assets/images/icons/camera-small.png | Bin 296 -> 0 bytes src/assets/images/icons/chat-history.png | Bin 574 -> 0 bytes src/assets/images/icons/close.png | Bin 1163 -> 0 bytes src/assets/images/icons/cog.png | Bin 448 -> 0 bytes src/assets/images/icons/help.png | Bin 233 -> 0 bytes src/assets/images/icons/house-small.png | Bin 361 -> 0 bytes src/assets/images/icons/icon_cog.png | Bin 218 -> 0 bytes src/assets/images/icons/like-room.png | Bin 481 -> 0 bytes src/assets/images/icons/loading-icon.png | Bin 222 -> 0 bytes src/assets/images/icons/room-link.png | Bin 322 -> 0 bytes src/assets/images/icons/sign-exclamation.png | Bin 236 -> 0 bytes src/assets/images/icons/sign-heart.png | Bin 256 -> 0 bytes src/assets/images/icons/sign-red.png | Bin 324 -> 0 bytes src/assets/images/icons/sign-skull.png | Bin 199 -> 0 bytes src/assets/images/icons/sign-smile.png | Bin 288 -> 0 bytes src/assets/images/icons/sign-soccer.png | Bin 641 -> 0 bytes src/assets/images/icons/sign-yellow.png | Bin 304 -> 0 bytes src/assets/images/icons/small-room.png | Bin 413 -> 0 bytes src/assets/images/icons/tickets.png | Bin 143 -> 0 bytes src/assets/images/icons/user.png | Bin 881 -> 0 bytes src/assets/images/icons/zoom-less.png | Bin 252 -> 0 bytes src/assets/images/icons/zoom-more.png | Bin 475 -> 0 bytes .../images/infostand/bot_background.png | Bin 811 -> 0 bytes .../images/infostand/countown-timer.png | Bin 219 -> 0 bytes src/assets/images/infostand/disk-creator.png | Bin 189 -> 0 bytes src/assets/images/infostand/disk-icon.png | Bin 240 -> 0 bytes src/assets/images/infostand/pencil-icon.png | Bin 288 -> 0 bytes src/assets/images/infostand/rarity-level.png | Bin 273 -> 0 bytes src/assets/images/inventory/empty.png | Bin 6377 -> 0 bytes src/assets/images/inventory/rarity-level.png | Bin 131 -> 0 bytes .../images/inventory/trading/locked-icon.png | Bin 309 -> 0 bytes .../inventory/trading/unlocked-icon.png | Bin 332 -> 0 bytes .../loading/connecting-duck-spritesheet.png | Bin 34720 -> 0 bytes .../images/loading/connecting_duck_01.png | Bin 3985 -> 0 bytes .../images/loading/connecting_duck_02.png | Bin 4923 -> 0 bytes .../images/loading/connecting_duck_03.png | Bin 5842 -> 0 bytes .../images/loading/connecting_duck_04.png | Bin 3270 -> 0 bytes .../images/loading/connecting_duck_05.png | Bin 4558 -> 0 bytes .../images/loading/connecting_duck_06.png | Bin 5290 -> 0 bytes .../images/loading/connecting_duck_07.png | Bin 2731 -> 0 bytes src/assets/images/loading/progress_habbos.gif | Bin 11805 -> 0 bytes src/assets/images/modtool/chatlog.gif | Bin 109 -> 0 bytes src/assets/images/modtool/key.gif | Bin 214 -> 0 bytes src/assets/images/modtool/m_icon.png | Bin 299 -> 0 bytes src/assets/images/modtool/reports.png | Bin 3551 -> 0 bytes src/assets/images/modtool/room.gif | Bin 169 -> 0 bytes src/assets/images/modtool/room.png | Bin 3102 -> 0 bytes src/assets/images/modtool/user.gif | Bin 1130 -> 0 bytes src/assets/images/modtool/wrench.gif | Bin 117 -> 0 bytes .../chain_mysterybox_box_overlay.png | Bin 369 -> 0 bytes src/assets/images/mysterybox/key_overlay.png | Bin 260 -> 0 bytes src/assets/images/mysterybox/mystery_box.png | Bin 514 -> 0 bytes .../images/mysterybox/mystery_box_key.png | Bin 487 -> 0 bytes .../mysterytrophy/frank_mystery_trophy.png | Bin 1653 -> 0 bytes src/assets/images/navigator/icons/info.png | Bin 256 -> 0 bytes .../images/navigator/icons/room_group.png | Bin 191 -> 0 bytes .../images/navigator/icons/room_invisible.png | Bin 173 -> 0 bytes .../images/navigator/icons/room_locked.png | Bin 221 -> 0 bytes .../images/navigator/icons/room_password.png | Bin 188 -> 0 bytes .../images/navigator/models/model_0.png | Bin 4027 -> 0 bytes .../images/navigator/models/model_1.png | Bin 956 -> 0 bytes .../images/navigator/models/model_2.png | Bin 920 -> 0 bytes .../images/navigator/models/model_3.png | Bin 581 -> 0 bytes .../images/navigator/models/model_4.png | Bin 709 -> 0 bytes .../images/navigator/models/model_5.png | Bin 1730 -> 0 bytes .../images/navigator/models/model_6.png | Bin 2147 -> 0 bytes .../images/navigator/models/model_7.png | Bin 2368 -> 0 bytes .../images/navigator/models/model_8.png | Bin 2123 -> 0 bytes .../images/navigator/models/model_9.png | Bin 1739 -> 0 bytes .../images/navigator/models/model_a.png | Bin 3279 -> 0 bytes .../images/navigator/models/model_b.png | Bin 3254 -> 0 bytes .../images/navigator/models/model_c.png | Bin 3102 -> 0 bytes .../images/navigator/models/model_d.png | Bin 3293 -> 0 bytes .../images/navigator/models/model_e.png | Bin 3267 -> 0 bytes .../images/navigator/models/model_f.png | Bin 3294 -> 0 bytes .../images/navigator/models/model_g.png | Bin 3395 -> 0 bytes .../images/navigator/models/model_h.png | Bin 3354 -> 0 bytes .../images/navigator/models/model_i.png | Bin 3690 -> 0 bytes .../images/navigator/models/model_j.png | Bin 3603 -> 0 bytes .../images/navigator/models/model_k.png | Bin 3785 -> 0 bytes .../images/navigator/models/model_l.png | Bin 3717 -> 0 bytes .../images/navigator/models/model_m.png | Bin 3559 -> 0 bytes .../images/navigator/models/model_n.png | Bin 3778 -> 0 bytes .../images/navigator/models/model_o.png | Bin 3598 -> 0 bytes .../images/navigator/models/model_p.png | Bin 3751 -> 0 bytes .../images/navigator/models/model_q.png | Bin 3874 -> 0 bytes .../images/navigator/models/model_r.png | Bin 4231 -> 0 bytes .../navigator/models/model_snowwar1.png | Bin 19090 -> 0 bytes .../navigator/models/model_snowwar2.png | Bin 19090 -> 0 bytes .../images/navigator/models/model_t.png | Bin 4329 -> 0 bytes .../images/navigator/models/model_u.png | Bin 4126 -> 0 bytes .../images/navigator/models/model_v.png | Bin 4416 -> 0 bytes .../images/navigator/models/model_w.png | Bin 4331 -> 0 bytes .../images/navigator/models/model_x.png | Bin 4103 -> 0 bytes .../images/navigator/models/model_y.png | Bin 4245 -> 0 bytes .../images/navigator/models/model_z.png | Bin 4087 -> 0 bytes .../navigator/thumbnail_placeholder.png | Bin 1801 -> 0 bytes src/assets/images/nitro/nitro-dark.svg | 43 - src/assets/images/nitro/nitro-light.svg | 43 - src/assets/images/nitro/nitro-n-dark.svg | 28 - src/assets/images/nitro/nitro-n-light.svg | 29 - src/assets/images/notifications/frank.gif | Bin 1204 -> 0 bytes src/assets/images/pets/pet-package/gnome.png | Bin 1600 -> 0 bytes .../pets/pet-package/leprechaun_box.png | Bin 1520 -> 0 bytes .../images/pets/pet-package/petbox_epic.png | Bin 2180 -> 0 bytes .../images/pets/pet-package/pterosaur_egg.png | Bin 1631 -> 0 bytes .../images/pets/pet-package/val11_present.png | Bin 2720 -> 0 bytes .../pets/pet-package/velociraptor_egg.png | Bin 1511 -> 0 bytes src/assets/images/prize/prize_background.png | Bin 5861 -> 0 bytes src/assets/images/profile/icons/offline.png | Bin 306 -> 0 bytes src/assets/images/profile/icons/online.gif | Bin 666 -> 0 bytes src/assets/images/profile/icons/tick.png | Bin 129 -> 0 bytes .../room_spectator_bottom_left.png | Bin 461 -> 0 bytes .../room_spectator_bottom_right.png | Bin 456 -> 0 bytes .../room_spectator_middle_bottom.png | Bin 98 -> 0 bytes .../room_spectator_middle_left.png | Bin 94 -> 0 bytes .../room_spectator_middle_right.png | Bin 94 -> 0 bytes .../room_spectator_middle_top.png | Bin 95 -> 0 bytes .../room_spectator_top_left.png | Bin 408 -> 0 bytes .../room_spectator_top_right.png | Bin 412 -> 0 bytes .../avatar-info/preview-background.png | Bin 7756 -> 0 bytes .../images/room-widgets/camera-widget/btn.png | Bin 830 -> 0 bytes .../room-widgets/camera-widget/btn_down.png | Bin 1000 -> 0 bytes .../room-widgets/camera-widget/btn_hi.png | Bin 935 -> 0 bytes .../room-widgets/camera-widget/cam_bg.png | Bin 2166 -> 0 bytes .../camera-widget/camera-spritesheet.png | Bin 15640 -> 0 bytes .../room-widgets/camera-widget/viewfinder.png | Bin 959 -> 0 bytes .../dimmer-widget/dimmer_banner.png | Bin 1041 -> 0 bytes .../engraving-lock-spritesheet.png | Bin 41062 -> 0 bytes .../exchange-credit/exchange-credit-image.png | Bin 9507 -> 0 bytes .../monsterplant-preview.png | Bin 2048 -> 0 bytes .../mannequin-spritesheet.png | Bin 5719 -> 0 bytes .../room-widgets/playlist-editor/disk_2.png | Bin 680 -> 0 bytes .../playlist-editor/disk_image.png | Bin 1441 -> 0 bytes .../room-widgets/playlist-editor/move.png | Bin 164 -> 0 bytes .../playlist-editor/pause-btn.png | Bin 111 -> 0 bytes .../room-widgets/playlist-editor/pause.png | Bin 114 -> 0 bytes .../room-widgets/playlist-editor/playing.png | Bin 309 -> 0 bytes .../room-widgets/playlist-editor/preview.png | Bin 147 -> 0 bytes .../stickie-widget/stickie-blue.png | Bin 401 -> 0 bytes .../stickie-widget/stickie-christmas.png | Bin 1272 -> 0 bytes .../stickie-widget/stickie-close.png | Bin 189 -> 0 bytes .../stickie-widget/stickie-dreams.png | Bin 26556 -> 0 bytes .../stickie-widget/stickie-green.png | Bin 401 -> 0 bytes .../stickie-widget/stickie-heart.png | Bin 945 -> 0 bytes .../stickie-widget/stickie-juninas.png | Bin 28162 -> 0 bytes .../stickie-widget/stickie-pink.png | Bin 758 -> 0 bytes .../stickie-widget/stickie-shakesp.png | Bin 5036 -> 0 bytes .../stickie-widget/stickie-spritesheet.png | Bin 5828 -> 0 bytes .../stickie-widget/stickie-trash.png | Bin 170 -> 0 bytes .../stickie-widget/stickie-yellow.png | Bin 401 -> 0 bytes .../thumbnail-camera-spritesheet.png | Bin 883 -> 0 bytes .../trophy-widget/trophy-spritesheet.png | Bin 6595 -> 0 bytes .../wordquiz-widget/thumbs-down-small.png | Bin 145 -> 0 bytes .../wordquiz-widget/thumbs-down.png | Bin 182 -> 0 bytes .../wordquiz-widget/thumbs-up-small.png | Bin 135 -> 0 bytes .../wordquiz-widget/thumbs-up.png | Bin 174 -> 0 bytes .../room-widgets/youtube-widget/next.png | Bin 164 -> 0 bytes .../room-widgets/youtube-widget/prev.png | Bin 249 -> 0 bytes .../images/stackhelper/slider-background.png | Bin 695 -> 0 bytes .../images/stackhelper/slider-pointer.png | Bin 373 -> 0 bytes src/assets/images/toolbar/arrow.png | Bin 14533 -> 0 bytes src/assets/images/toolbar/friend-search.png | Bin 2213 -> 0 bytes .../images/toolbar/icons/buildersclub.png | Bin 576 -> 0 bytes src/assets/images/toolbar/icons/camera.png | Bin 1732 -> 0 bytes src/assets/images/toolbar/icons/catalog.png | Bin 1202 -> 0 bytes .../images/toolbar/icons/friend_all.png | Bin 648 -> 0 bytes .../images/toolbar/icons/friend_head.png | Bin 680 -> 0 bytes .../images/toolbar/icons/friend_search.png | Bin 15241 -> 0 bytes src/assets/images/toolbar/icons/game.png | Bin 740 -> 0 bytes src/assets/images/toolbar/icons/habbo.png | Bin 1304 -> 0 bytes src/assets/images/toolbar/icons/house.png | Bin 399 -> 0 bytes src/assets/images/toolbar/icons/inventory.png | Bin 1973 -> 0 bytes src/assets/images/toolbar/icons/joinroom.png | Bin 1084 -> 0 bytes .../toolbar/icons/me-menu/achievements.png | Bin 2306 -> 0 bytes .../images/toolbar/icons/me-menu/clothing.png | Bin 2255 -> 0 bytes .../images/toolbar/icons/me-menu/cog.png | Bin 657 -> 0 bytes .../images/toolbar/icons/me-menu/forums.png | Bin 416 -> 0 bytes .../toolbar/icons/me-menu/helper-tool.png | Bin 309 -> 0 bytes .../images/toolbar/icons/me-menu/my-rooms.png | Bin 2299 -> 0 bytes .../images/toolbar/icons/me-menu/profile.png | Bin 468 -> 0 bytes .../images/toolbar/icons/me-menu/rooms.png | Bin 1465 -> 0 bytes .../images/toolbar/icons/me-menu/talents.png | Bin 397 -> 0 bytes src/assets/images/toolbar/icons/message.png | Bin 1099 -> 0 bytes .../images/toolbar/icons/message_unsee.gif | Bin 1511 -> 0 bytes src/assets/images/toolbar/icons/modtools.png | Bin 404 -> 0 bytes src/assets/images/toolbar/icons/rooms.png | Bin 1465 -> 0 bytes .../images/toolbar/icons/sendmessage.png | Bin 15647 -> 0 bytes .../images/unique/catalog-info-amount-bg.png | Bin 757 -> 0 bytes .../images/unique/catalog-info-sold-out.png | Bin 1100 -> 0 bytes src/assets/images/unique/grid-bg-glass.png | Bin 213 -> 0 bytes src/assets/images/unique/grid-bg-sold-out.png | Bin 332 -> 0 bytes src/assets/images/unique/grid-bg.png | Bin 201 -> 0 bytes src/assets/images/unique/grid-count-bg.png | Bin 155 -> 0 bytes .../unique/inventory-info-amount-bg.png | Bin 521 -> 0 bytes src/assets/images/unique/numbers.png | Bin 146 -> 0 bytes .../images/wired/card-action-corners.png | Bin 1827 -> 0 bytes src/assets/images/wired/icon_action.png | Bin 171 -> 0 bytes src/assets/images/wired/icon_condition.png | Bin 173 -> 0 bytes src/assets/images/wired/icon_trigger.png | Bin 169 -> 0 bytes src/assets/images/wired/icon_wired_around.png | Bin 197 -> 0 bytes .../images/wired/icon_wired_left_right.png | Bin 172 -> 0 bytes .../images/wired/icon_wired_north_east.png | Bin 157 -> 0 bytes .../images/wired/icon_wired_north_west.png | Bin 166 -> 0 bytes .../wired/icon_wired_rotate_clockwise.png | Bin 146 -> 0 bytes .../icon_wired_rotate_counter_clockwise.png | Bin 148 -> 0 bytes .../images/wired/icon_wired_south_east.png | Bin 171 -> 0 bytes .../images/wired/icon_wired_south_west.png | Bin 169 -> 0 bytes .../images/wired/icon_wired_up_down.png | Bin 153 -> 0 bytes src/assets/styles/bootstrap/_accordion.scss | 118 - src/assets/styles/bootstrap/_alert.scss | 58 - src/assets/styles/bootstrap/_badge.scss | 29 - src/assets/styles/bootstrap/_breadcrumb.scss | 28 - .../styles/bootstrap/_button-group.scss | 139 - src/assets/styles/bootstrap/_buttons.scss | 116 - src/assets/styles/bootstrap/_card.scss | 216 -- src/assets/styles/bootstrap/_carousel.scss | 229 -- src/assets/styles/bootstrap/_close.scss | 40 - src/assets/styles/bootstrap/_containers.scss | 41 - src/assets/styles/bootstrap/_dropdown.scss | 240 -- src/assets/styles/bootstrap/_forms.scss | 9 - src/assets/styles/bootstrap/_functions.scss | 298 -- src/assets/styles/bootstrap/_grid.scss | 33 - src/assets/styles/bootstrap/_helpers.scss | 9 - src/assets/styles/bootstrap/_images.scss | 42 - src/assets/styles/bootstrap/_list-group.scss | 176 - src/assets/styles/bootstrap/_mixins.scss | 43 - src/assets/styles/bootstrap/_modal.scss | 209 -- src/assets/styles/bootstrap/_nav.scss | 160 - src/assets/styles/bootstrap/_navbar.scss | 335 -- src/assets/styles/bootstrap/_offcanvas.scss | 83 - src/assets/styles/bootstrap/_pagination.scss | 64 - .../styles/bootstrap/_placeholders.scss | 51 - src/assets/styles/bootstrap/_popover.scss | 158 - src/assets/styles/bootstrap/_progress.scss | 48 - src/assets/styles/bootstrap/_reboot.scss | 609 --- src/assets/styles/bootstrap/_root.scss | 53 - src/assets/styles/bootstrap/_spinners.scss | 69 - src/assets/styles/bootstrap/_tables.scss | 151 - src/assets/styles/bootstrap/_toasts.scss | 51 - src/assets/styles/bootstrap/_tooltip.scss | 115 - src/assets/styles/bootstrap/_transitions.scss | 27 - src/assets/styles/bootstrap/_type.scss | 104 - src/assets/styles/bootstrap/_utilities.scss | 638 ---- src/assets/styles/bootstrap/_variables.scss | 1683 --------- .../styles/bootstrap/bootstrap-grid.scss | 65 - .../styles/bootstrap/bootstrap-reboot.scss | 15 - .../styles/bootstrap/bootstrap-utilities.scss | 18 - src/assets/styles/bootstrap/bootstrap.scss | 53 - .../bootstrap/forms/_floating-labels.scss | 63 - .../styles/bootstrap/forms/_form-check.scss | 152 - .../styles/bootstrap/forms/_form-control.scss | 219 -- .../styles/bootstrap/forms/_form-range.scss | 91 - .../styles/bootstrap/forms/_form-select.scss | 70 - .../styles/bootstrap/forms/_form-text.scss | 11 - .../styles/bootstrap/forms/_input-group.scss | 121 - .../styles/bootstrap/forms/_labels.scss | 36 - .../styles/bootstrap/forms/_validation.scss | 12 - .../styles/bootstrap/helpers/_clearfix.scss | 3 - .../bootstrap/helpers/_colored-links.scss | 12 - .../styles/bootstrap/helpers/_position.scss | 30 - .../styles/bootstrap/helpers/_ratio.scss | 26 - .../styles/bootstrap/helpers/_stacks.scss | 15 - .../bootstrap/helpers/_stretched-link.scss | 15 - .../bootstrap/helpers/_text-truncation.scss | 7 - .../bootstrap/helpers/_visually-hidden.scss | 8 - src/assets/styles/bootstrap/helpers/_vr.scss | 8 - .../styles/bootstrap/mixins/_alert.scss | 11 - .../styles/bootstrap/mixins/_backdrop.scss | 14 - .../bootstrap/mixins/_border-radius.scss | 78 - .../styles/bootstrap/mixins/_box-shadow.scss | 18 - .../styles/bootstrap/mixins/_breakpoints.scss | 127 - .../styles/bootstrap/mixins/_buttons.scss | 133 - .../styles/bootstrap/mixins/_caret.scss | 64 - .../styles/bootstrap/mixins/_clearfix.scss | 9 - .../bootstrap/mixins/_color-scheme.scss | 7 - .../styles/bootstrap/mixins/_container.scss | 9 - .../styles/bootstrap/mixins/_deprecate.scss | 10 - .../styles/bootstrap/mixins/_forms.scss | 144 - .../styles/bootstrap/mixins/_gradients.scss | 47 - src/assets/styles/bootstrap/mixins/_grid.scss | 150 - .../styles/bootstrap/mixins/_image.scss | 16 - .../styles/bootstrap/mixins/_list-group.scss | 24 - .../styles/bootstrap/mixins/_lists.scss | 7 - .../styles/bootstrap/mixins/_pagination.scss | 31 - .../styles/bootstrap/mixins/_reset-text.scss | 17 - .../styles/bootstrap/mixins/_resize.scss | 6 - .../bootstrap/mixins/_table-variants.scss | 21 - .../bootstrap/mixins/_text-truncate.scss | 8 - .../styles/bootstrap/mixins/_transition.scss | 26 - .../styles/bootstrap/mixins/_utilities.scss | 89 - .../bootstrap/mixins/_visually-hidden.scss | 29 - .../styles/bootstrap/utilities/_api.scss | 47 - src/assets/styles/bootstrap/vendor/_rfs.scss | 355 -- src/assets/styles/fonts.scss | 4 - src/assets/styles/icons.scss | 629 ---- src/assets/styles/index.scss | 26 - src/assets/styles/scrollbars.scss | 53 - src/assets/styles/slider.scss | 54 - src/assets/styles/utils.scss | 134 - src/assets/webfonts/Ubuntu-C.ttf | Bin 369840 -> 0 bytes src/assets/webfonts/Ubuntu-b.ttf | Bin 152496 -> 0 bytes src/assets/webfonts/Ubuntu-i.ttf | Bin 160792 -> 0 bytes src/assets/webfonts/Ubuntu-ib.ttf | Bin 148524 -> 0 bytes src/assets/webfonts/Ubuntu-m.ttf | Bin 140976 -> 0 bytes src/assets/webfonts/Ubuntu.ttf | Bin 155908 -> 0 bytes src/common/AutoGrid.tsx | 28 - src/common/Base.tsx | 84 - src/common/Button.tsx | 35 - src/common/ButtonGroup.tsx | 22 - src/common/Column.tsx | 46 - src/common/Flex.tsx | 50 - src/common/FormGroup.tsx | 22 - src/common/Grid.tsx | 63 - src/common/GridContext.tsx | 17 - src/common/HorizontalRule.tsx | 38 - src/common/InfiniteGrid.tsx | 79 - src/common/InfiniteScroll.tsx | 55 - src/common/Text.tsx | 63 - src/common/card/NitroCardContentView.tsx | 18 - src/common/card/NitroCardContext.tsx | 17 - src/common/card/NitroCardHeaderView.tsx | 48 - src/common/card/NitroCardSubHeaderView.tsx | 23 - src/common/card/NitroCardView.scss | 248 -- src/common/card/NitroCardView.tsx | 34 - .../accordion/NitroCardAccordionContext.tsx | 21 - .../accordion/NitroCardAccordionItemView.tsx | 18 - .../accordion/NitroCardAccordionSetView.tsx | 84 - .../card/accordion/NitroCardAccordionView.tsx | 25 - src/common/card/accordion/index.ts | 4 - src/common/card/index.ts | 7 - .../card/tabs/NitroCardTabsItemView.tsx | 35 - src/common/card/tabs/NitroCardTabsView.tsx | 22 - src/common/card/tabs/index.ts | 2 - src/common/classNames.ts | 1 - .../draggable-window/DraggableWindow.tsx | 270 -- .../DraggableWindowPosition.ts | 7 - src/common/draggable-window/index.ts | 2 - src/common/index.scss | 562 --- src/common/index.ts | 23 - src/common/layout/LayoutAvatarImageView.tsx | 103 - src/common/layout/LayoutBackgroundImage.tsx | 23 - src/common/layout/LayoutBadgeImageView.tsx | 106 - src/common/layout/LayoutCounterTimeView.tsx | 43 - src/common/layout/LayoutCurrencyIcon.tsx | 44 - .../layout/LayoutFurniIconImageView.tsx | 17 - src/common/layout/LayoutFurniImageView.tsx | 70 - src/common/layout/LayoutGiftTagView.tsx | 41 - src/common/layout/LayoutGridItem.tsx | 75 - src/common/layout/LayoutImage.tsx | 13 - src/common/layout/LayoutItemCountView.tsx | 28 - .../layout/LayoutLoadingSpinnerView.tsx | 15 - src/common/layout/LayoutMiniCameraView.tsx | 44 - .../layout/LayoutNotificationAlertView.tsx | 35 - .../layout/LayoutNotificationBubbleView.tsx | 52 - src/common/layout/LayoutPetImageView.tsx | 123 - .../layout/LayoutPrizeProductImageView.tsx | 30 - src/common/layout/LayoutProgressBar.tsx | 34 - src/common/layout/LayoutRarityLevelView.tsx | 28 - .../layout/LayoutRoomObjectImageView.tsx | 59 - src/common/layout/LayoutRoomPreviewerView.tsx | 88 - src/common/layout/LayoutRoomThumbnailView.tsx | 37 - src/common/layout/LayoutTrophyView.tsx | 42 - src/common/layout/UserProfileIconView.tsx | 29 - src/common/layout/index.ts | 24 - .../LayoutLimitedEditionCompactPlateView.tsx | 35 - .../LayoutLimitedEditionCompletePlateView.tsx | 41 - .../LayoutLimitedEditionStyledNumberView.tsx | 18 - src/common/layout/limited-edition/index.ts | 3 - .../transitions/TransitionAnimation.tsx | 52 - .../transitions/TransitionAnimationStyles.ts | 136 - .../transitions/TransitionAnimationTypes.ts | 11 - src/common/transitions/index.ts | 3 - src/common/types/AlignItemType.ts | 1 - src/common/types/AlignSelfType.ts | 1 - src/common/types/ButtonSizeType.ts | 1 - src/common/types/ColorVariantType.ts | 1 - src/common/types/ColumnSizesType.ts | 1 - src/common/types/DisplayType.ts | 1 - src/common/types/FloatType.ts | 1 - src/common/types/FontSizeType.ts | 1 - src/common/types/FontWeightType.ts | 1 - src/common/types/JustifyContentType.ts | 1 - src/common/types/OverflowType.ts | 1 - src/common/types/PositionType.ts | 1 - src/common/types/SpacingType.ts | 1 - src/common/types/TextAlignType.ts | 1 - src/common/types/index.ts | 14 - src/common/utils/CreateTransitionToIcon.ts | 13 - src/common/utils/FriendlyTimeView.tsx | 28 - src/common/utils/index.ts | 2 - .../achievements/AchievementsView.scss | 15 - .../achievements/AchievementsView.tsx | 72 - .../views/AchievementBadgeView.tsx | 19 - .../views/AchievementCategoryView.tsx | 37 - .../views/AchievementDetailsView.tsx | 53 - .../AchievementListItemView.tsx | 24 - .../achievement-list/AchievementListView.tsx | 20 - .../views/achievement-list/index.ts | 2 - .../AchievementsCategoryListItemView.tsx | 31 - .../AchievementsCategoryListView.tsx | 22 - .../achievements/views/category-list/index.ts | 2 - src/components/achievements/views/index.ts | 5 - .../avatar-editor-new/AvatarEditorView.scss | 336 -- .../avatar-editor-new/AvatarEditorView.tsx | 114 - .../views/AvatarEditorIcon.tsx | 30 - .../views/AvatarEditorModelView.tsx | 85 - .../AvatarEditorFigureSetItemView.tsx | 53 - .../figure-set/AvatarEditorFigureSetView.tsx | 36 - .../views/figure-set/index.ts | 2 - .../AvatarEditorPaletteSetItemView.tsx | 27 - .../AvatarEditorPaletteSetView.tsx | 33 - .../views/palette-set/index.ts | 2 - .../avatar-editor/AvatarEditorView.scss | 336 -- .../avatar-editor/AvatarEditorView.tsx | 316 -- .../views/AvatarEditorFigurePreviewView.tsx | 55 - .../avatar-editor/views/AvatarEditorIcon.tsx | 30 - .../views/AvatarEditorModelView.tsx | 88 - .../views/AvatarEditorWardrobeView.tsx | 79 - .../AvatarEditorFigureSetItemView.tsx | 35 - .../figure-set/AvatarEditorFigureSetView.tsx | 44 - .../avatar-editor/views/figure-set/index.ts | 2 - src/components/avatar-editor/views/index.ts | 6 - .../AvatarEditorPaletteSetItemView.tsx | 32 - .../AvatarEditorPaletteSetView.tsx | 41 - .../avatar-editor/views/palette-set/index.ts | 2 - src/components/camera/CameraWidgetView.scss | 133 - src/components/camera/CameraWidgetView.tsx | 96 - src/components/camera/index.ts | 4 - .../camera/views/CameraWidgetCaptureView.tsx | 90 - .../camera/views/CameraWidgetCheckoutView.tsx | 159 - .../views/CameraWidgetShowPhotoView.tsx | 71 - .../views/editor/CameraWidgetEditorView.tsx | 243 -- .../CameraWidgetEffectListItemView.tsx | 40 - .../CameraWidgetEffectListView.tsx | 31 - .../camera/views/editor/effect-list/index.ts | 2 - src/components/camera/views/editor/index.ts | 2 - src/components/camera/views/index.ts | 5 - src/components/campaign/CalendarItemView.tsx | 53 - src/components/campaign/CalendarView.tsx | 144 - src/components/campaign/CampaignView.scss | 71 - src/components/campaign/CampaignView.tsx | 101 - src/components/catalog/CatalogView.scss | 158 - src/components/catalog/CatalogView.tsx | 111 - .../views/CatalogPurchaseConfirmView.tsx | 10 - .../catalog-header/CatalogHeaderView.tsx | 26 - .../views/catalog-icon/CatalogIconView.tsx | 20 - .../CatalogRoomPreviewerView.tsx | 44 - .../catalog/views/gift/CatalogGiftView.tsx | 289 -- .../navigation/CatalogNavigationItemView.tsx | 35 - .../navigation/CatalogNavigationSetView.tsx | 25 - .../navigation/CatalogNavigationView.tsx | 34 - .../page/common/CatalogGridOfferView.tsx | 59 - .../page/common/CatalogRedeemVoucherView.tsx | 60 - .../views/page/common/CatalogSearchView.tsx | 94 - .../views/page/layout/CatalogLayout.types.ts | 7 - .../layout/CatalogLayoutBadgeDisplayView.tsx | 54 - .../layout/CatalogLayoutColorGroupingView.tsx | 176 - .../page/layout/CatalogLayoutDefaultView.tsx | 61 - .../CatalogLayoutGuildCustomFurniView.tsx | 48 - .../layout/CatalogLayoutGuildForumView.tsx | 49 - .../CatalogLayoutGuildFrontpageView.tsx | 30 - .../layout/CatalogLayoutInfoLoyaltyView.tsx | 15 - .../page/layout/CatalogLayoutPets2View.tsx | 8 - .../page/layout/CatalogLayoutPets3View.tsx | 25 - .../page/layout/CatalogLayoutRoomAdsView.tsx | 113 - .../layout/CatalogLayoutRoomBundleView.tsx | 41 - .../layout/CatalogLayoutSingleBundleView.tsx | 41 - .../layout/CatalogLayoutSoundMachineView.tsx | 113 - .../page/layout/CatalogLayoutSpacesView.tsx | 47 - .../page/layout/CatalogLayoutTrophiesView.tsx | 56 - .../page/layout/CatalogLayoutVipBuyView.tsx | 191 - .../views/page/layout/GetCatalogLayout.tsx | 80 - .../CatalogLayoutFrontPageItemView.tsx | 37 - .../CatalogLayoutFrontpage4View.tsx | 49 - .../CatalogLayoutMarketplaceItemView.tsx | 83 - .../CatalogLayoutMarketplaceOwnItemsView.tsx | 102 - ...atalogLayoutMarketplacePublicItemsView.tsx | 161 - ...CatalogLayoutMarketplaceSearchFormView.tsx | 71 - .../marketplace/MarketplacePostOfferView.tsx | 121 - .../page/layout/pets/CatalogLayoutPetView.tsx | 243 -- .../vip-gifts/CatalogLayoutVipGiftsView.tsx | 62 - .../page/layout/vip-gifts/VipGiftItemView.tsx | 63 - .../widgets/CatalogAddOnBadgeWidgetView.tsx | 18 - .../CatalogBadgeSelectorWidgetView.tsx | 76 - .../widgets/CatalogBundleGridWidgetView.tsx | 29 - .../CatalogFirstProductSelectorWidgetView.tsx | 16 - .../widgets/CatalogGuildBadgeWidgetView.tsx | 31 - .../CatalogGuildSelectorWidgetView.tsx | 75 - .../widgets/CatalogItemGridWidgetView.tsx | 52 - .../widgets/CatalogLimitedItemWidgetView.tsx | 19 - .../widgets/CatalogPriceDisplayWidgetView.tsx | 37 - .../widgets/CatalogPurchaseWidgetView.tsx | 164 - .../widgets/CatalogSimplePriceWidgetView.tsx | 21 - .../widgets/CatalogSingleViewWidgetView.tsx | 7 - .../page/widgets/CatalogSpacesWidgetView.tsx | 115 - .../page/widgets/CatalogSpinnerWidgetView.tsx | 46 - .../page/widgets/CatalogTotalPriceWidget.tsx | 20 - .../widgets/CatalogViewProductWidgetView.tsx | 99 - .../catalog/views/targeted-offer/Offer.scss | 27 - .../views/targeted-offer/OfferBubbleView.tsx | 16 - .../views/targeted-offer/OfferView.tsx | 32 - .../views/targeted-offer/OfferWindowView.tsx | 82 - .../chat-history/ChatHistoryView.scss | 4 - .../chat-history/ChatHistoryView.tsx | 96 - .../FloorplanEditorContext.tsx | 22 - .../floorplan-editor/FloorplanEditorView.scss | 9 - .../floorplan-editor/FloorplanEditorView.tsx | 160 - .../floorplan-editor/common/ActionSettings.ts | 39 - .../floorplan-editor/common/Constants.ts | 44 - .../common/ConvertMapToString.ts | 1 - .../common/FloorplanEditor.ts | 375 -- .../common/FloorplanResource.ts | 227 -- .../common/IFloorplanSettings.ts | 8 - .../common/IVisualizationSettings.ts | 7 - .../floorplan-editor/common/Tile.ts | 31 - .../floorplan-editor/common/Utils.ts | 53 - .../views/FloorplanCanvasView.tsx | 199 - .../views/FloorplanImportExportView.tsx | 55 - .../views/FloorplanOptionsView.tsx | 189 - src/components/friends/FriendsView.scss | 244 -- src/components/friends/FriendsView.tsx | 21 - .../views/friends-bar/FriendBarItemView.tsx | 59 - .../views/friends-bar/FriendsBarView.tsx | 26 - .../FriendsListRemoveConfirmationView.tsx | 29 - .../FriendsListRoomInviteView.tsx | 31 - .../friends-list/FriendsListSearchView.tsx | 103 - .../views/friends-list/FriendsListView.tsx | 150 - .../FriendsListGroupItemView.tsx | 85 - .../FriendsListGroupView.tsx | 23 - .../FriendsListRequestItemView.tsx | 25 - .../FriendsListRequestView.tsx | 29 - .../views/messenger/FriendsMessengerView.tsx | 177 - .../FriendsMessengerThreadGroup.tsx | 73 - .../FriendsMessengerThreadView.tsx | 16 - .../game-center/GameCenterView.scss | 44 - src/components/game-center/GameCenterView.tsx | 49 - .../game-center/views/GameListView.tsx | 32 - .../game-center/views/GameStageView.tsx | 47 - src/components/game-center/views/GameView.tsx | 58 - src/components/groups/GroupView.scss | 190 - src/components/groups/GroupsView.tsx | 63 - .../groups/views/GroupBadgeCreatorView.tsx | 83 - .../groups/views/GroupCreatorView.tsx | 164 - .../views/GroupInformationStandaloneView.tsx | 29 - .../groups/views/GroupInformationView.tsx | 146 - .../groups/views/GroupManagerView.tsx | 119 - .../groups/views/GroupMembersView.tsx | 210 -- .../groups/views/GroupRoomInformationView.tsx | 132 - .../groups/views/tabs/GroupTabBadgeView.tsx | 120 - .../groups/views/tabs/GroupTabColorsView.tsx | 127 - .../tabs/GroupTabCreatorConfirmationView.tsx | 67 - .../views/tabs/GroupTabIdentityView.tsx | 116 - .../views/tabs/GroupTabSettingsView.tsx | 89 - src/components/guide-tool/GuideToolView.scss | 87 - src/components/guide-tool/GuideToolView.tsx | 356 -- .../guide-tool/views/GuideToolAcceptView.tsx | 35 - .../guide-tool/views/GuideToolMenuView.tsx | 76 - .../guide-tool/views/GuideToolOngoingView.tsx | 130 - .../views/GuideToolUserCreateRequestView.tsx | 32 - .../views/GuideToolUserFeedbackView.tsx | 43 - .../views/GuideToolUserNoHelpersView.tsx | 13 - .../views/GuideToolUserPendingView.tsx | 33 - .../views/GuideToolUserSomethingWrogView.tsx | 12 - .../views/GuideToolUserThanksView.tsx | 13 - src/components/hc-center/HcCenterView.scss | 44 - src/components/hc-center/HcCenterView.tsx | 204 - src/components/help/HelpView.scss | 18 - src/components/help/HelpView.tsx | 116 - .../help/views/DescribeReportView.tsx | 48 - src/components/help/views/HelpIndexView.tsx | 37 - .../help/views/ReportSummaryView.tsx | 57 - .../help/views/SanctionStatusView.tsx | 75 - .../help/views/SelectReportedChatsView.tsx | 90 - .../help/views/SelectReportedUserView.tsx | 85 - src/components/help/views/SelectTopicView.tsx | 53 - .../NameChangeConfirmationView.tsx | 44 - .../views/name-change/NameChangeInitView.tsx | 20 - .../views/name-change/NameChangeInputView.tsx | 97 - .../help/views/name-change/NameChangeView.tsx | 66 - .../views/name-change/NameChangeView.types.ts | 5 - src/components/hotel-view/HotelView.scss | 97 - src/components/hotel-view/HotelView.tsx | 106 - .../views/widgets/GetWidgetLayout.tsx | 29 - .../views/widgets/HotelViewWidgets.scss | 4 - .../views/widgets/WidgetSlotView.tsx | 20 - .../bonus-rare/BonusRareWidgetView.scss | 10 - .../bonus-rare/BonusRareWidgetView.tsx | 42 - .../hall-of-fame-item/HallOfFameItemView.tsx | 27 - .../hall-of-fame/HallOfFameWidgetView.scss | 70 - .../hall-of-fame/HallOfFameWidgetView.tsx | 37 - .../HallOfFameWidgetView.types.ts | 5 - .../promo-article/PromoArticleWidgetView.scss | 27 - .../promo-article/PromoArticleWidgetView.tsx | 46 - .../widget-container/WidgetContainerView.scss | 9 - .../widget-container/WidgetContainerView.tsx | 39 - src/components/index.scss | 26 - src/components/inventory/InventoryView.scss | 17 - src/components/inventory/InventoryView.tsx | 152 - .../views/InventoryCategoryEmptyView.tsx | 26 - .../views/badge/InventoryBadgeItemView.tsx | 19 - .../views/badge/InventoryBadgeView.tsx | 66 - .../views/bot/InventoryBotItemView.tsx | 43 - .../inventory/views/bot/InventoryBotView.tsx | 91 - .../furniture/InventoryFurnitureItemView.tsx | 38 - .../InventoryFurnitureSearchView.tsx | 47 - .../furniture/InventoryFurnitureView.tsx | 146 - .../views/furniture/InventoryTradeView.tsx | 279 -- .../views/pet/InventoryPetItemView.tsx | 43 - .../inventory/views/pet/InventoryPetView.tsx | 90 - src/components/loading/LoadingView.scss | 70 - src/components/loading/LoadingView.tsx | 21 - src/components/main/MainView.tsx | 113 - src/components/mod-tools/ModToolsView.scss | 70 - src/components/mod-tools/ModToolsView.tsx | 147 - .../mod-tools/views/chatlog/ChatlogRecord.ts | 11 - .../mod-tools/views/chatlog/ChatlogView.tsx | 91 - .../views/room/ModToolsChatlogView.tsx | 44 - .../mod-tools/views/room/ModToolsRoomView.tsx | 117 - .../views/tickets/CfhChatlogView.tsx | 41 - .../views/tickets/ModToolsIssueInfoView.tsx | 86 - .../views/tickets/ModToolsMyIssuesTabView.tsx | 47 - .../tickets/ModToolsOpenIssuesTabView.tsx | 42 - .../tickets/ModToolsPickedIssuesTabView.tsx | 39 - .../views/tickets/ModToolsTicketsView.tsx | 90 - .../views/user/ModToolsUserChatlogView.tsx | 44 - .../views/user/ModToolsUserModActionView.tsx | 176 - .../views/user/ModToolsUserRoomVisitsView.tsx | 60 - .../user/ModToolsUserSendMessageView.tsx | 45 - .../mod-tools/views/user/ModToolsUserView.tsx | 156 - src/components/navigator/NavigatorView.scss | 65 - src/components/navigator/NavigatorView.tsx | 233 -- .../views/NavigatorDoorStateView.tsx | 110 - .../views/NavigatorRoomCreatorView.tsx | 122 - .../navigator/views/NavigatorRoomInfoView.tsx | 180 - .../navigator/views/NavigatorRoomLinkView.tsx | 33 - .../NavigatorRoomSettingsAccessTabView.tsx | 88 - .../NavigatorRoomSettingsBasicTabView.tsx | 171 - .../NavigatorRoomSettingsModTabView.tsx | 118 - .../NavigatorRoomSettingsRightsTabView.tsx | 91 - .../NavigatorRoomSettingsView.tsx | 206 -- .../NavigatorRoomSettingsVipChatTabView.tsx | 76 - .../NavigatorSearchResultItemInfoView.tsx | 81 - .../search/NavigatorSearchResultItemView.tsx | 121 - .../search/NavigatorSearchResultView.tsx | 118 - .../views/search/NavigatorSearchView.tsx | 84 - src/components/nitropedia/NitropediaView.scss | 47 - src/components/nitropedia/NitropediaView.tsx | 105 - .../NotificationCenterView.scss | 59 - .../NotificationCenterView.tsx | 77 - .../views/alert-layouts/GetAlertLayout.tsx | 21 - .../alert-layouts/NitroSystemAlertView.tsx | 39 - .../NotificationDefaultAlertView.tsx | 56 - .../NotificationSearchAlertView.tsx | 61 - .../views/bubble-layouts/GetBubbleLayout.tsx | 18 - .../NotificationClubGiftBubbleView.tsx | 26 - .../NotificationDefaultBubbleView.tsx | 25 - .../confirm-layouts/GetConfirmLayout.tsx | 15 - .../NotificationDefaultConfirmView.tsx | 40 - src/components/purse/PurseView.scss | 26 - src/components/purse/PurseView.tsx | 90 - src/components/purse/views/CurrencyView.tsx | 39 - src/components/purse/views/SeasonalView.tsx | 24 - src/components/right-side/RightSideView.scss | 10 - src/components/right-side/RightSideView.tsx | 24 - src/components/room/RoomView.scss | 2 - src/components/room/RoomView.tsx | 46 - .../room/spectator/RoomSpectatorView.scss | 26 - .../room/spectator/RoomSpectatorView.tsx | 8 - src/components/room/widgets/RoomWidgets.scss | 110 - .../room/widgets/RoomWidgetsView.tsx | 172 - .../AvatarInfoPetTrainingPanelView.tsx | 59 - .../AvatarInfoRentableBotChatView.tsx | 68 - .../AvatarInfoUseProductConfirmView.tsx | 281 -- .../avatar-info/AvatarInfoUseProductView.tsx | 135 - .../avatar-info/AvatarInfoWidgetView.scss | 134 - .../avatar-info/AvatarInfoWidgetView.tsx | 139 - .../infostand/InfoStandWidgetBotView.tsx | 55 - .../infostand/InfoStandWidgetFurniView.tsx | 474 --- .../infostand/InfoStandWidgetPetView.tsx | 209 -- .../InfoStandWidgetRentableBotView.tsx | 84 - ...nfoStandWidgetUserRelationshipItemView.tsx | 31 - .../InfoStandWidgetUserRelationshipsView.tsx | 23 - .../infostand/InfoStandWidgetUserTagsView.tsx | 31 - .../infostand/InfoStandWidgetUserView.tsx | 215 -- .../menu/AvatarInfoWidgetAvatarView.tsx | 372 -- .../menu/AvatarInfoWidgetDecorateView.tsx | 29 - .../menu/AvatarInfoWidgetFurniView.tsx | 67 - .../menu/AvatarInfoWidgetNameView.tsx | 32 - .../menu/AvatarInfoWidgetOwnAvatarView.tsx | 292 -- .../menu/AvatarInfoWidgetOwnPetView.tsx | 220 -- .../menu/AvatarInfoWidgetPetView.tsx | 138 - .../menu/AvatarInfoWidgetRentableBotView.tsx | 197 - .../chat-input/ChatInputStyleSelectorView.tsx | 68 - .../widgets/chat-input/ChatInputView.scss | 84 - .../room/widgets/chat-input/ChatInputView.tsx | 248 -- .../widgets/chat/ChatWidgetMessageView.tsx | 95 - .../room/widgets/chat/ChatWidgetView.scss | 919 ----- .../room/widgets/chat/ChatWidgetView.tsx | 162 - .../widgets/choosers/ChooserWidgetView.scss | 4 - .../widgets/choosers/ChooserWidgetView.tsx | 51 - .../choosers/FurniChooserWidgetView.tsx | 31 - .../choosers/UserChooserWidgetView.tsx | 31 - .../widgets/context-menu/ContextMenu.scss | 129 - .../context-menu/ContextMenuCaretView.tsx | 26 - .../context-menu/ContextMenuHeaderView.tsx | 18 - .../context-menu/ContextMenuListItemView.tsx | 32 - .../context-menu/ContextMenuListView.tsx | 18 - .../widgets/context-menu/ContextMenuView.tsx | 170 - .../widgets/doorbell/DoorbellWidgetView.tsx | 51 - .../FriendRequestDialogView.scss | 4 - .../FriendRequestDialogView.tsx | 28 - .../FriendRequestWidgetView.tsx | 17 - .../FurnitureBackgroundColorView.tsx | 30 - .../furniture/FurnitureBadgeDisplayView.tsx | 12 - .../furniture/FurnitureCraftingView.tsx | 115 - .../widgets/furniture/FurnitureDimmerView.tsx | 86 - .../furniture/FurnitureExchangeCreditView.tsx | 33 - .../furniture/FurnitureExternalImageView.tsx | 23 - .../furniture/FurnitureFriendFurniView.tsx | 66 - .../furniture/FurnitureGiftOpeningView.tsx | 73 - .../furniture/FurnitureHighScoreView.tsx | 60 - .../furniture/FurnitureInternalLinkView.tsx | 9 - .../furniture/FurnitureMannequinView.tsx | 144 - .../FurnitureMysteryBoxOpenDialogView.tsx | 81 - .../FurnitureMysteryTrophyOpenDialogView.tsx | 50 - .../furniture/FurnitureRoomLinkView.tsx | 9 - .../furniture/FurnitureSpamWallPostItView.tsx | 46 - .../furniture/FurnitureStackHeightView.tsx | 58 - .../furniture/FurnitureStickieView.tsx | 66 - .../widgets/furniture/FurnitureTrophyView.tsx | 12 - .../widgets/furniture/FurnitureWidgets.scss | 526 --- .../furniture/FurnitureWidgetsView.tsx | 48 - .../furniture/FurnitureYoutubeDisplayView.tsx | 109 - .../context-menu/EffectBoxConfirmView.tsx | 40 - .../context-menu/FurnitureContextMenuView.tsx | 130 - .../MonsterPlantSeedConfirmView.tsx | 85 - .../PurchasableClothingConfirmView.tsx | 104 - .../playlist-editor/DiskInventoryView.tsx | 94 - .../FurniturePlaylistEditorWidgetView.tsx | 29 - .../playlist-editor/SongPlaylistView.tsx | 79 - .../mysterybox/MysteryBoxExtensionView.scss | 52 - .../mysterybox/MysteryBoxExtensionView.tsx | 67 - .../object-location/ObjectLocationView.tsx | 61 - .../pet-package/PetPackageWidgetView.scss | 106 - .../pet-package/PetPackageWidgetView.tsx | 42 - .../RoomFilterWordsWidgetView.tsx | 74 - .../room-promotes/RoomPromotesWidgetView.tsx | 55 - .../views/RoomPromoteEditWidgetView.tsx | 44 - .../views/RoomPromoteMyOwnEventWidgetView.tsx | 36 - .../views/RoomPromoteOtherEventWidgetView.tsx | 30 - .../room/widgets/room-promotes/views/index.ts | 3 - .../RoomThumbnailWidgetView.tsx | 41 - .../room-tools/RoomToolsWidgetView.tsx | 100 - .../user-location/UserLocationView.tsx | 24 - .../word-quiz/WordQuizQuestionView.tsx | 44 - .../widgets/word-quiz/WordQuizVoteView.tsx | 24 - .../widgets/word-quiz/WordQuizWidgetView.tsx | 19 - src/components/toolbar/ToolbarMeView.tsx | 52 - src/components/toolbar/ToolbarView.scss | 81 - src/components/toolbar/ToolbarView.tsx | 111 - .../user-profile/UserProfileVew.scss | 67 - .../user-profile/UserProfileView.tsx | 122 - .../views/BadgesContainerView.tsx | 25 - .../views/FriendsContainerView.tsx | 28 - .../views/GroupsContainerView.tsx | 90 - .../views/RelationshipsContainerView.tsx | 62 - .../user-profile/views/UserContainerView.tsx | 74 - .../user-settings/UserSettingsView.tsx | 187 - src/components/wired/WiredView.scss | 175 - src/components/wired/WiredView.tsx | 21 - src/components/wired/views/WiredBaseView.tsx | 114 - .../wired/views/WiredFurniSelectorView.tsx | 16 - .../views/actions/WiredActionBaseView.tsx | 41 - .../WiredActionBotChangeFigureView.tsx | 38 - .../WiredActionBotFollowAvatarView.tsx | 43 - .../WiredActionBotGiveHandItemView.tsx | 42 - .../views/actions/WiredActionBotMoveView.tsx | 27 - .../WiredActionBotTalkToAvatarView.tsx | 52 - .../views/actions/WiredActionBotTalkView.tsx | 52 - .../actions/WiredActionBotTeleportView.tsx | 27 - .../WiredActionCallAnotherStackView.tsx | 8 - .../views/actions/WiredActionChaseView.tsx | 8 - .../views/actions/WiredActionChatView.tsx | 27 - .../views/actions/WiredActionFleeView.tsx | 8 - .../actions/WiredActionGiveRewardView.tsx | 160 - ...redActionGiveScoreToPredefinedTeamView.tsx | 67 - .../actions/WiredActionGiveScoreView.tsx | 52 - .../views/actions/WiredActionJoinTeamView.tsx | 35 - .../actions/WiredActionKickFromRoomView.tsx | 27 - .../views/actions/WiredActionLayoutView.tsx | 85 - .../actions/WiredActionLeaveTeamView.tsx | 8 - .../WiredActionMoveAndRotateFurniView.tsx | 82 - .../actions/WiredActionMoveFurniToView.tsx | 76 - .../actions/WiredActionMoveFurniView.tsx | 100 - .../views/actions/WiredActionMuteUserView.tsx | 43 - .../views/actions/WiredActionResetView.tsx | 8 - .../WiredActionSetFurniStateToView.tsx | 42 - .../views/actions/WiredActionTeleportView.tsx | 8 - .../WiredActionToggleFurniStateView.tsx | 8 - .../WiredConditionActorHasHandItem.tsx | 34 - .../WiredConditionActorIsGroupMemberView.tsx | 8 - .../WiredConditionActorIsOnFurniView.tsx | 8 - .../WiredConditionActorIsTeamMemberView.tsx | 37 - .../WiredConditionActorIsWearingBadgeView.tsx | 27 - ...WiredConditionActorIsWearingEffectView.tsx | 27 - .../conditions/WiredConditionBaseView.tsx | 23 - .../WiredConditionDateRangeView.tsx | 58 - .../WiredConditionFurniHasAvatarOnView.tsx | 8 - .../WiredConditionFurniHasFurniOnView.tsx | 35 - .../WiredConditionFurniHasNotFurniOnView.tsx | 35 - .../WiredConditionFurniIsOfTypeView.tsx | 8 - ...WiredConditionFurniMatchesSnapshotView.tsx | 42 - .../conditions/WiredConditionLayoutView.tsx | 64 - .../WiredConditionTimeElapsedLessView.tsx | 33 - .../WiredConditionTimeElapsedMoreView.tsx | 33 - .../WiredConditionUserCountInRoomView.tsx | 52 - .../WiredTriggerAvatarEnterRoomView.tsx | 38 - .../WiredTriggerAvatarSaysSomethingView.tsx | 45 - .../WiredTriggerAvatarWalksOffFurniView.tsx | 8 - .../WiredTriggerAvatarWalksOnFurni.tsx | 8 - .../views/triggers/WiredTriggerBaseView.tsx | 23 - .../WiredTriggerBotReachedAvatarView.tsx | 27 - .../WiredTriggerBotReachedStuffView.tsx | 27 - .../triggers/WiredTriggerCollisionView.tsx | 8 - .../triggers/WiredTriggerExecuteOnceView.tsx | 33 - ...iredTriggerExecutePeriodicallyLongView.tsx | 33 - .../WiredTriggerExecutePeriodicallyView.tsx | 33 - .../triggers/WiredTriggerGameEndsView.tsx | 8 - .../triggers/WiredTriggerGameStartsView.tsx | 8 - .../views/triggers/WiredTriggerLayoutView.tsx | 52 - .../WiredTriggerScoreAchievedView.tsx | 33 - .../triggers/WiredTriggerToggleFurniView.tsx | 8 - src/events/catalog/CatalogEvent.ts | 14 - src/events/catalog/CatalogInitGiftEvent.ts | 32 - .../CatalogPostMarketplaceOfferEvent.ts | 20 - .../catalog/CatalogPurchaseFailureEvent.ts | 20 - .../catalog/CatalogPurchaseNotAllowedEvent.ts | 20 - .../catalog/CatalogPurchaseOverrideEvent.ts | 19 - .../catalog/CatalogPurchaseSoldOutEvent.ts | 11 - src/events/catalog/CatalogPurchasedEvent.ts | 20 - .../CatalogSetRoomPreviewerStuffDataEvent.ts | 19 - src/events/catalog/CatalogWidgetEvent.ts | 26 - .../catalog/SetRoomPreviewerStuffDataEvent.ts | 28 - src/events/catalog/index.ts | 11 - src/events/guide-tool/GuideToolEvent.ts | 10 - src/events/guide-tool/index.ts | 1 - src/events/help/HelpNameChangeEvent.ts | 6 - src/events/help/index.ts | 1 - src/events/index.ts | 6 - .../inventory/InventoryFurniAddedEvent.ts | 14 - src/events/inventory/index.ts | 1 - src/events/room-widgets/index.ts | 1 - .../thumbnail/RoomWidgetThumbnailEvent.ts | 8 - src/events/room-widgets/thumbnail/index.ts | 1 - src/hooks/UseMountEffect.tsx | 7 - src/hooks/achievements/index.ts | 1 - src/hooks/achievements/useAchievements.ts | 185 - src/hooks/avatar-editor/index.ts | 2 - src/hooks/avatar-editor/useAvatarEditor.ts | 244 -- src/hooks/avatar-editor/useFigureData.ts | 114 - src/hooks/camera/index.ts | 1 - src/hooks/camera/useCamera.ts | 42 - src/hooks/catalog/index.ts | 3 - src/hooks/catalog/useCatalog.ts | 913 ----- .../catalog/useCatalogPlaceMultipleItems.ts | 7 - .../useCatalogSkipPurchaseConfirmation.ts | 7 - src/hooks/chat-history/index.ts | 1 - src/hooks/chat-history/useChatHistory.ts | 104 - src/hooks/events/index.ts | 4 - src/hooks/events/useEventDispatcher.tsx | 31 - src/hooks/events/useMessageEvent.tsx | 15 - src/hooks/events/useNitroEvent.tsx | 4 - src/hooks/events/useUiEvent.tsx | 5 - src/hooks/friends/index.ts | 2 - src/hooks/friends/useFriends.ts | 252 -- src/hooks/friends/useMessenger.ts | 187 - src/hooks/game-center/index.ts | 1 - src/hooks/game-center/useGameCenter.ts | 83 - src/hooks/groups/index.ts | 1 - src/hooks/groups/useGroup.ts | 55 - src/hooks/help/index.ts | 1 - src/hooks/help/useHelp.ts | 149 - src/hooks/index.ts | 25 - src/hooks/inventory/index.ts | 6 - src/hooks/inventory/useInventoryBadges.ts | 152 - src/hooks/inventory/useInventoryBots.ts | 158 - src/hooks/inventory/useInventoryFurni.ts | 298 -- src/hooks/inventory/useInventoryPets.ts | 107 - src/hooks/inventory/useInventoryTrade.ts | 288 -- .../inventory/useInventoryUnseenTracker.ts | 132 - src/hooks/mod-tools/index.ts | 1 - src/hooks/mod-tools/useModTools.ts | 207 -- src/hooks/navigator/index.ts | 1 - src/hooks/navigator/useNavigator.ts | 442 --- src/hooks/notification/index.ts | 1 - src/hooks/notification/useNotification.ts | 433 --- src/hooks/purse/index.ts | 1 - src/hooks/purse/usePurse.ts | 126 - src/hooks/rooms/engine/index.ts | 9 - src/hooks/rooms/engine/useFurniAddedEvent.ts | 19 - .../rooms/engine/useFurniRemovedEvent.ts | 19 - .../rooms/engine/useObjectDeselectedEvent.ts | 7 - .../engine/useObjectDoubleClickedEvent.ts | 7 - .../rooms/engine/useObjectRollOutEvent.ts | 7 - .../rooms/engine/useObjectRollOverEvent.ts | 7 - .../rooms/engine/useObjectSelectedEvent.ts | 7 - src/hooks/rooms/engine/useUserAddedEvent.ts | 19 - src/hooks/rooms/engine/useUserRemovedEvent.ts | 19 - src/hooks/rooms/index.ts | 4 - src/hooks/rooms/promotes/index.ts | 1 - src/hooks/rooms/promotes/useRoomPromote.ts | 23 - src/hooks/rooms/useRoom.ts | 283 -- src/hooks/rooms/widgets/furniture/index.ts | 19 - .../useFurnitureBackgroundColorWidget.ts | 71 - .../useFurnitureBadgeDisplayWidget.ts | 75 - .../useFurnitureContextMenuWidget.ts | 179 - .../furniture/useFurnitureCraftingWidget.ts | 166 - .../furniture/useFurnitureDimmerWidget.ts | 110 - .../furniture/useFurnitureExchangeWidget.ts | 48 - .../useFurnitureExternalImageWidget.ts | 74 - .../useFurnitureFriendFurniWidget.ts | 75 - .../furniture/useFurnitureHighScoreWidget.ts | 55 - .../useFurnitureInternalLinkWidget.ts | 26 - .../furniture/useFurnitureMannequinWidget.ts | 80 - .../useFurniturePlaylistEditorWidget.ts | 108 - .../furniture/useFurniturePresentWidget.ts | 235 -- .../furniture/useFurnitureRoomLinkWidget.ts | 49 - .../useFurnitureSpamWallPostItWidget.ts | 59 - .../useFurnitureStackHeightWidget.ts | 79 - .../furniture/useFurnitureStickieWidget.ts | 85 - .../furniture/useFurnitureTrophyWidget.ts | 62 - .../furniture/useFurnitureYoutubeWidget.ts | 127 - src/hooks/rooms/widgets/index.ts | 12 - .../rooms/widgets/useAvatarInfoWidget.ts | 355 -- src/hooks/rooms/widgets/useChatInputWidget.ts | 282 -- src/hooks/rooms/widgets/useChatWidget.ts | 191 - src/hooks/rooms/widgets/useDoorbellWidget.ts | 44 - .../rooms/widgets/useFilterWordsWidget.ts | 23 - .../rooms/widgets/useFriendRequestWidget.ts | 81 - .../rooms/widgets/useFurniChooserWidget.ts | 132 - .../rooms/widgets/usePetPackageWidget.ts | 75 - src/hooks/rooms/widgets/usePollWidget.ts | 52 - .../rooms/widgets/useUserChooserWidget.ts | 80 - src/hooks/rooms/widgets/useWordQuizWidget.ts | 149 - src/hooks/session/index.ts | 1 - src/hooks/session/useSessionInfo.ts | 63 - src/hooks/useLocalStorage.ts | 44 - src/hooks/useSharedVisibility.ts | 44 - src/hooks/wired/index.ts | 1 - src/hooks/wired/useWired.ts | 140 - src/index.scss | 26 - src/index.ts | 21 + src/index.tsx | 5 - src/pixi-proxy/NitroAdjustmentFilter.ts | 4 + src/pixi-proxy/NitroAlphaFilter.ts | 4 + src/pixi-proxy/NitroContainer.ts | 4 + src/pixi-proxy/NitroFilter.ts | 4 + src/pixi-proxy/NitroRectangle.ts | 4 + src/pixi-proxy/NitroRenderTexture.ts | 4 + src/pixi-proxy/NitroSprite.ts | 5 + src/pixi-proxy/NitroTexture.ts | 4 + src/pixi-proxy/NitroTicker.ts | 3 + src/pixi-proxy/index.ts | 9 + src/react-app-env.d.ts | 1 - src/workers/IntervalWebWorker.ts | 26 - src/workers/WorkerBuilder.ts | 10 - tsconfig.json | 42 +- vite.config.js | 28 + vite.config.mjs | 32 - yarn.lock | 2483 ++----------- 4080 files changed, 115593 insertions(+), 66375 deletions(-) create mode 100644 .editorconfig delete mode 100644 .eslintrc.json create mode 100644 LICENSE delete mode 100644 index.html create mode 100644 index.ts create mode 100644 packages/api/.gitignore create mode 100644 packages/api/index.ts create mode 100644 packages/api/package.json create mode 100644 packages/api/src/asset/IAsset.ts create mode 100644 packages/api/src/asset/IAssetAlias.ts create mode 100644 packages/api/src/asset/IAssetData.ts create mode 100644 packages/api/src/asset/IAssetManager.ts create mode 100644 packages/api/src/asset/IAssetPalette.ts create mode 100644 packages/api/src/asset/IGraphicAsset.ts create mode 100644 packages/api/src/asset/IGraphicAssetCollection.ts create mode 100644 packages/api/src/asset/IGraphicAssetPalette.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimation.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationAdd.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationAvatar.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationDirection.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationFrame.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationFramePart.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationFramePartItem.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationOverride.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationRemove.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationShadow.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationSprite.ts create mode 100644 packages/api/src/asset/animation/IAssetAnimationSpriteDirection.ts create mode 100644 packages/api/src/asset/animation/index.ts create mode 100644 packages/api/src/asset/index.ts create mode 100644 packages/api/src/asset/logic/IAssetLogicCustomVars.ts create mode 100644 packages/api/src/asset/logic/IAssetLogicData.ts create mode 100644 packages/api/src/asset/logic/IAssetLogicPlanetSystem.ts create mode 100644 packages/api/src/asset/logic/ISoundSample.ts create mode 100644 packages/api/src/asset/logic/index.ts create mode 100644 packages/api/src/asset/logic/model/IAssetDimension.ts create mode 100644 packages/api/src/asset/logic/model/IAssetLogicModel.ts create mode 100644 packages/api/src/asset/logic/model/index.ts create mode 100644 packages/api/src/asset/logic/particlesystem/IParticleSystem.ts create mode 100644 packages/api/src/asset/logic/particlesystem/IParticleSystemEmitter.ts create mode 100644 packages/api/src/asset/logic/particlesystem/IParticleSystemParticle.ts create mode 100644 packages/api/src/asset/logic/particlesystem/IParticleSystemSimulation.ts create mode 100644 packages/api/src/asset/logic/particlesystem/index.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlane.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneMask.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneMaskData.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneMaskVisualization.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneMaterial.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneMaterialCell.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellColumn.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellExtraItemData.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellMatrix.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneTexture.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneTextureBitmap.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneVisualization.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneVisualizationAnimatedLayer.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneVisualizationAnimatedLayerItem.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneVisualizationData.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetPlaneVisualizationLayer.ts create mode 100644 packages/api/src/asset/room-visualization/IAssetRoomVisualizationData.ts create mode 100644 packages/api/src/asset/room-visualization/index.ts create mode 100644 packages/api/src/asset/spritesheet/ISpritesheetData.ts create mode 100644 packages/api/src/asset/spritesheet/ISpritesheetFrame.ts create mode 100644 packages/api/src/asset/spritesheet/ISpritesheetMeta.ts create mode 100644 packages/api/src/asset/spritesheet/index.ts create mode 100644 packages/api/src/asset/visualization/IAssetVisualizationData.ts create mode 100644 packages/api/src/asset/visualization/IAssetVisualizationDirection.ts create mode 100644 packages/api/src/asset/visualization/IAssetVisualizationLayer.ts create mode 100644 packages/api/src/asset/visualization/animation/IAssetVisualAnimation.ts create mode 100644 packages/api/src/asset/visualization/animation/IAssetVisualAnimationLayer.ts create mode 100644 packages/api/src/asset/visualization/animation/IAssetVisualAnimationSequence.ts create mode 100644 packages/api/src/asset/visualization/animation/IAssetVisualAnimationSequenceFrame.ts create mode 100644 packages/api/src/asset/visualization/animation/IAssetVisualAnimationSequenceFrameOffset.ts create mode 100644 packages/api/src/asset/visualization/animation/index.ts create mode 100644 packages/api/src/asset/visualization/color/IAssetColor.ts create mode 100644 packages/api/src/asset/visualization/color/IAssetColorLayer.ts create mode 100644 packages/api/src/asset/visualization/color/index.ts create mode 100644 packages/api/src/asset/visualization/gestures/IAssetGesture.ts create mode 100644 packages/api/src/asset/visualization/gestures/index.ts create mode 100644 packages/api/src/asset/visualization/index.ts create mode 100644 packages/api/src/asset/visualization/postures/IAssetPosture.ts create mode 100644 packages/api/src/asset/visualization/postures/index.ts create mode 100644 packages/api/src/common/IDisposable.ts create mode 100644 packages/api/src/common/IEventDispatcher.ts create mode 100644 packages/api/src/common/ILinkEventTracker.ts create mode 100644 packages/api/src/common/INitroEvent.ts create mode 100644 packages/api/src/common/INitroManager.ts create mode 100644 packages/api/src/common/IUpdateReceiver.ts create mode 100644 packages/api/src/common/index.ts create mode 100644 packages/api/src/communication/ICodec.ts create mode 100644 packages/api/src/communication/ICommunicationManager.ts create mode 100644 packages/api/src/communication/IConnection.ts create mode 100644 packages/api/src/communication/IConnectionStateListener.ts create mode 100644 packages/api/src/communication/IMessageComposer.ts create mode 100644 packages/api/src/communication/IMessageConfiguration.ts create mode 100644 packages/api/src/communication/IMessageDataWrapper.ts create mode 100644 packages/api/src/communication/IMessageEvent.ts create mode 100644 packages/api/src/communication/IMessageParser.ts create mode 100644 packages/api/src/communication/enums/ClientDeviceCategoryEnum.ts create mode 100644 packages/api/src/communication/enums/ClientPlatformEnum.ts create mode 100644 packages/api/src/communication/enums/WebSocketEventEnum.ts create mode 100644 packages/api/src/communication/enums/index.ts create mode 100644 packages/api/src/communication/index.ts create mode 100644 packages/api/src/index.ts create mode 100644 packages/api/src/nitro/avatar/IAvatarAssetDownloadLibrary.ts create mode 100644 packages/api/src/nitro/avatar/IAvatarEffectListener.ts create mode 100644 packages/api/src/nitro/avatar/IAvatarFigureContainer.ts create mode 100644 packages/api/src/nitro/avatar/IAvatarImage.ts create mode 100644 packages/api/src/nitro/avatar/IAvatarImageListener.ts create mode 100644 packages/api/src/nitro/avatar/IAvatarRenderManager.ts create mode 100644 packages/api/src/nitro/avatar/IEffectAssetDownloadLibrary.ts create mode 100644 packages/api/src/nitro/avatar/IOutfit.ts create mode 100644 packages/api/src/nitro/avatar/actions/IActionDefinition.ts create mode 100644 packages/api/src/nitro/avatar/actions/IActiveActionData.ts create mode 100644 packages/api/src/nitro/avatar/actions/index.ts create mode 100644 packages/api/src/nitro/avatar/animation/IAnimation.ts create mode 100644 packages/api/src/nitro/avatar/animation/IAnimationLayerData.ts create mode 100644 packages/api/src/nitro/avatar/animation/IAnimationManager.ts create mode 100644 packages/api/src/nitro/avatar/animation/IAvatarDataContainer.ts create mode 100644 packages/api/src/nitro/avatar/animation/ISpriteDataContainer.ts create mode 100644 packages/api/src/nitro/avatar/animation/index.ts create mode 100644 packages/api/src/nitro/avatar/enum/AvatarAction.ts create mode 100644 packages/api/src/nitro/avatar/enum/AvatarDirectionAngle.ts create mode 100644 packages/api/src/nitro/avatar/enum/AvatarEditorFigureCategory.ts create mode 100644 packages/api/src/nitro/avatar/enum/AvatarEditorInstanceId.ts create mode 100644 packages/api/src/nitro/avatar/enum/AvatarEditorSideCategory.ts create mode 100644 packages/api/src/nitro/avatar/enum/AvatarFigurePartType.ts create mode 100644 packages/api/src/nitro/avatar/enum/AvatarGuideStatus.ts create mode 100644 packages/api/src/nitro/avatar/enum/AvatarScaleType.ts create mode 100644 packages/api/src/nitro/avatar/enum/AvatarSetType.ts create mode 100644 packages/api/src/nitro/avatar/enum/GeometryType.ts create mode 100644 packages/api/src/nitro/avatar/enum/RenderMode.ts create mode 100644 packages/api/src/nitro/avatar/enum/index.ts create mode 100644 packages/api/src/nitro/avatar/figuredata/IFigureData.ts create mode 100644 packages/api/src/nitro/avatar/figuredata/IFigureDataColor.ts create mode 100644 packages/api/src/nitro/avatar/figuredata/IFigureDataHiddenLayer.ts create mode 100644 packages/api/src/nitro/avatar/figuredata/IFigureDataPalette.ts create mode 100644 packages/api/src/nitro/avatar/figuredata/IFigureDataPart.ts create mode 100644 packages/api/src/nitro/avatar/figuredata/IFigureDataSet.ts create mode 100644 packages/api/src/nitro/avatar/figuredata/IFigureDataSetType.ts create mode 100644 packages/api/src/nitro/avatar/figuredata/index.ts create mode 100644 packages/api/src/nitro/avatar/index.ts create mode 100644 packages/api/src/nitro/avatar/structure/IFigurePart.ts create mode 100644 packages/api/src/nitro/avatar/structure/IFigurePartSet.ts create mode 100644 packages/api/src/nitro/avatar/structure/IFigureSetData.ts create mode 100644 packages/api/src/nitro/avatar/structure/IPalette.ts create mode 100644 packages/api/src/nitro/avatar/structure/IPartColor.ts create mode 100644 packages/api/src/nitro/avatar/structure/ISetType.ts create mode 100644 packages/api/src/nitro/avatar/structure/IStructureData.ts create mode 100644 packages/api/src/nitro/avatar/structure/index.ts create mode 100644 packages/api/src/nitro/camera/IRoomCameraWidgetEffect.ts create mode 100644 packages/api/src/nitro/camera/IRoomCameraWidgetManager.ts create mode 100644 packages/api/src/nitro/camera/IRoomCameraWidgetSelectedEffect.ts create mode 100644 packages/api/src/nitro/camera/index.ts create mode 100644 packages/api/src/nitro/enums/RelationshipStatusEnum.ts create mode 100644 packages/api/src/nitro/enums/ToolbarIconEnum.ts create mode 100644 packages/api/src/nitro/enums/index.ts create mode 100644 packages/api/src/nitro/index.ts create mode 100644 packages/api/src/nitro/localization/ILocalizationManager.ts create mode 100644 packages/api/src/nitro/localization/index.ts create mode 100644 packages/api/src/nitro/room/IGetImageListener.ts create mode 100644 packages/api/src/nitro/room/IImageResult.ts create mode 100644 packages/api/src/nitro/room/IPetColorResult.ts create mode 100644 packages/api/src/nitro/room/IRoomContentListener.ts create mode 100644 packages/api/src/nitro/room/IRoomContentLoader.ts create mode 100644 packages/api/src/nitro/room/IRoomCreator.ts create mode 100644 packages/api/src/nitro/room/IRoomEngine.ts create mode 100644 packages/api/src/nitro/room/IRoomEngineServices.ts create mode 100644 packages/api/src/nitro/room/IRoomObjectEventManager.ts create mode 100644 packages/api/src/nitro/room/ISelectedRoomObjectData.ts create mode 100644 packages/api/src/nitro/room/enums/FriendFurniEngravingWidgetType.ts create mode 100644 packages/api/src/nitro/room/enums/RoomObjectPlacementSource.ts create mode 100644 packages/api/src/nitro/room/enums/index.ts create mode 100644 packages/api/src/nitro/room/index.ts create mode 100644 packages/api/src/nitro/room/object/IPetFigureData.ts create mode 100644 packages/api/src/nitro/room/object/IRoomMapData.ts create mode 100644 packages/api/src/nitro/room/object/RoomObjectCategory.ts create mode 100644 packages/api/src/nitro/room/object/RoomObjectLogicType.ts create mode 100644 packages/api/src/nitro/room/object/RoomObjectOperationType.ts create mode 100644 packages/api/src/nitro/room/object/RoomObjectType.ts create mode 100644 packages/api/src/nitro/room/object/RoomObjectUserType.ts create mode 100644 packages/api/src/nitro/room/object/RoomObjectVariable.ts create mode 100644 packages/api/src/nitro/room/object/RoomObjectVisualizationType.ts create mode 100644 packages/api/src/nitro/room/object/data/IObjectData.ts create mode 100644 packages/api/src/nitro/room/object/data/ObjectDataBase.ts create mode 100644 packages/api/src/nitro/room/object/data/ObjectDataFactory.ts create mode 100644 packages/api/src/nitro/room/object/data/ObjectDataFlags.ts create mode 100644 packages/api/src/nitro/room/object/data/ObjectDataKey.ts create mode 100644 packages/api/src/nitro/room/object/data/index.ts create mode 100644 packages/api/src/nitro/room/object/data/type/CrackableDataType.ts create mode 100644 packages/api/src/nitro/room/object/data/type/EmptyDataType.ts create mode 100644 packages/api/src/nitro/room/object/data/type/HighScoreData.ts create mode 100644 packages/api/src/nitro/room/object/data/type/HighScoreDataType.ts create mode 100644 packages/api/src/nitro/room/object/data/type/LegacyDataType.ts create mode 100644 packages/api/src/nitro/room/object/data/type/MapDataType.ts create mode 100644 packages/api/src/nitro/room/object/data/type/NumberDataType.ts create mode 100644 packages/api/src/nitro/room/object/data/type/StringDataType.ts create mode 100644 packages/api/src/nitro/room/object/data/type/VoteDataType.ts create mode 100644 packages/api/src/nitro/room/object/data/type/index.ts create mode 100644 packages/api/src/nitro/room/object/index.ts create mode 100644 packages/api/src/nitro/room/utils/IFurnitureStackingHeightMap.ts create mode 100644 packages/api/src/nitro/room/utils/ILegacyWallGeometry.ts create mode 100644 packages/api/src/nitro/room/utils/ITileObjectMap.ts create mode 100644 packages/api/src/nitro/room/utils/ObjectRolling.ts create mode 100644 packages/api/src/nitro/room/utils/index.ts create mode 100644 packages/api/src/nitro/session/BreedingPetInfo.ts create mode 100644 packages/api/src/nitro/session/FurnitureType.ts create mode 100644 packages/api/src/nitro/session/IFurnitureData.ts create mode 100644 packages/api/src/nitro/session/IFurnitureDataListener.ts create mode 100644 packages/api/src/nitro/session/IGroupInformationManager.ts create mode 100644 packages/api/src/nitro/session/IIgnoredUsersManager.ts create mode 100644 packages/api/src/nitro/session/IPetCustomPart.ts create mode 100644 packages/api/src/nitro/session/IPollChoice.ts create mode 100644 packages/api/src/nitro/session/IPollQuestion.ts create mode 100644 packages/api/src/nitro/session/IProductData.ts create mode 100644 packages/api/src/nitro/session/IProductDataListener.ts create mode 100644 packages/api/src/nitro/session/IQuestion.ts create mode 100644 packages/api/src/nitro/session/IRoomHandlerListener.ts create mode 100644 packages/api/src/nitro/session/IRoomModerationSettings.ts create mode 100644 packages/api/src/nitro/session/IRoomPetData.ts create mode 100644 packages/api/src/nitro/session/IRoomSession.ts create mode 100644 packages/api/src/nitro/session/IRoomSessionManager.ts create mode 100644 packages/api/src/nitro/session/IRoomUserData.ts create mode 100644 packages/api/src/nitro/session/ISessionDataManager.ts create mode 100644 packages/api/src/nitro/session/IUserDataManager.ts create mode 100644 packages/api/src/nitro/session/PetBreedingResultData.ts create mode 100644 packages/api/src/nitro/session/PetCustomPart.ts create mode 100644 packages/api/src/nitro/session/PetFigureData.ts create mode 100644 packages/api/src/nitro/session/RarityCategoryData.ts create mode 100644 packages/api/src/nitro/session/enum/GenericErrorEnum.ts create mode 100644 packages/api/src/nitro/session/enum/NoobnessLevelEnum.ts create mode 100644 packages/api/src/nitro/session/enum/PetType.ts create mode 100644 packages/api/src/nitro/session/enum/RoomControllerLevel.ts create mode 100644 packages/api/src/nitro/session/enum/RoomTradingLevelEnum.ts create mode 100644 packages/api/src/nitro/session/enum/SecurityLevel.ts create mode 100644 packages/api/src/nitro/session/enum/index.ts create mode 100644 packages/api/src/nitro/session/index.ts create mode 100644 packages/api/src/nitro/sound/IMusicController.ts create mode 100644 packages/api/src/nitro/sound/IPlaylistController.ts create mode 100644 packages/api/src/nitro/sound/ISongInfo.ts create mode 100644 packages/api/src/nitro/sound/ISoundManager.ts create mode 100644 packages/api/src/nitro/sound/index.ts create mode 100644 packages/api/src/room/IPetBreedingResultData.ts create mode 100644 packages/api/src/room/IRoomGeometry.ts create mode 100644 packages/api/src/room/IRoomInstance.ts create mode 100644 packages/api/src/room/IRoomInstanceContainer.ts create mode 100644 packages/api/src/room/IRoomManager.ts create mode 100644 packages/api/src/room/IRoomManagerListener.ts create mode 100644 packages/api/src/room/IRoomObjectManager.ts create mode 100644 packages/api/src/room/IRoomObjectUpdateMessage.ts create mode 100644 packages/api/src/room/IRoomSpriteMouseEvent.ts create mode 100644 packages/api/src/room/RoomObjectSpriteData.ts create mode 100644 packages/api/src/room/index.ts create mode 100644 packages/api/src/room/object/IRoomObject.ts create mode 100644 packages/api/src/room/object/IRoomObjectController.ts create mode 100644 packages/api/src/room/object/IRoomObjectModel.ts create mode 100644 packages/api/src/room/object/IRoomObjectModelController.ts create mode 100644 packages/api/src/room/object/enum/AlphaTolerance.ts create mode 100644 packages/api/src/room/object/enum/RoomObjectSpriteType.ts create mode 100644 packages/api/src/room/object/enum/index.ts create mode 100644 packages/api/src/room/object/index.ts create mode 100644 packages/api/src/room/object/logic/IRoomObjectEventHandler.ts create mode 100644 packages/api/src/room/object/logic/IRoomObjectLogicFactory.ts create mode 100644 packages/api/src/room/object/logic/IRoomObjectMouseHandler.ts create mode 100644 packages/api/src/room/object/logic/index.ts create mode 100644 packages/api/src/room/object/visualization/IPlaneDrawingData.ts create mode 100644 packages/api/src/room/object/visualization/IPlaneVisualization.ts create mode 100644 packages/api/src/room/object/visualization/IRoomObjectGraphicVisualization.ts create mode 100644 packages/api/src/room/object/visualization/IRoomObjectSprite.ts create mode 100644 packages/api/src/room/object/visualization/IRoomObjectSpriteVisualization.ts create mode 100644 packages/api/src/room/object/visualization/IRoomObjectVisualization.ts create mode 100644 packages/api/src/room/object/visualization/IRoomObjectVisualizationData.ts create mode 100644 packages/api/src/room/object/visualization/IRoomObjectVisualizationFactory.ts create mode 100644 packages/api/src/room/object/visualization/IRoomPlane.ts create mode 100644 packages/api/src/room/object/visualization/ISortableSprite.ts create mode 100644 packages/api/src/room/object/visualization/index.ts create mode 100644 packages/api/src/room/renderer/IRoomCanvasMouseListener.ts create mode 100644 packages/api/src/room/renderer/IRoomRenderer.ts create mode 100644 packages/api/src/room/renderer/IRoomRendererBase.ts create mode 100644 packages/api/src/room/renderer/IRoomRenderingCanvas.ts create mode 100644 packages/api/src/room/renderer/IRoomSpriteCanvasContainer.ts create mode 100644 packages/api/src/room/renderer/index.ts create mode 100644 packages/api/src/ui/MouseEventType.ts create mode 100644 packages/api/src/ui/TouchEventType.ts create mode 100644 packages/api/src/ui/enums/AvatarExpressionEnum.ts create mode 100644 packages/api/src/ui/enums/ContextMenuEnum.ts create mode 100644 packages/api/src/ui/enums/FriendWidgetEngravingWidgetTypeEnum.ts create mode 100644 packages/api/src/ui/enums/RoomWidgetEnum.ts create mode 100644 packages/api/src/ui/enums/RoomWidgetEnumItemExtradataParameter.ts create mode 100644 packages/api/src/ui/enums/RoomWidgetFurniInfoUsagePolicyEnum.ts create mode 100644 packages/api/src/ui/enums/SystemChatStyleEnum.ts create mode 100644 packages/api/src/ui/enums/index.ts create mode 100644 packages/api/src/ui/index.ts create mode 100644 packages/api/src/utils/IAdvancedMap.ts create mode 100644 packages/api/src/utils/IBinaryReader.ts create mode 100644 packages/api/src/utils/IBinaryWriter.ts create mode 100644 packages/api/src/utils/IVector3D.ts create mode 100644 packages/api/src/utils/index.ts create mode 100644 packages/api/tsconfig.json create mode 100644 packages/assets/.eslintrc.json create mode 100644 packages/assets/.gitignore create mode 100644 packages/assets/index.ts create mode 100644 packages/assets/package.json create mode 100644 packages/assets/src/AssetManager.ts create mode 100644 packages/assets/src/GetAssetManager.ts create mode 100644 packages/assets/src/GraphicAsset.ts create mode 100644 packages/assets/src/GraphicAssetCollection.ts create mode 100644 packages/assets/src/GraphicAssetPalette.ts create mode 100644 packages/assets/src/index.ts create mode 100644 packages/assets/tsconfig.json create mode 100644 packages/avatar/.eslintrc.json create mode 100644 packages/avatar/.gitignore create mode 100644 packages/avatar/index.ts create mode 100644 packages/avatar/package.json create mode 100644 packages/avatar/src/AvatarAssetDownloadLibrary.ts create mode 100644 packages/avatar/src/AvatarAssetDownloadManager.ts create mode 100644 packages/avatar/src/AvatarFigureContainer.ts create mode 100644 packages/avatar/src/AvatarImage.ts create mode 100644 packages/avatar/src/AvatarImageBodyPartContainer.ts create mode 100644 packages/avatar/src/AvatarImagePartContainer.ts create mode 100644 packages/avatar/src/AvatarRenderManager.ts create mode 100644 packages/avatar/src/AvatarStructure.ts create mode 100644 packages/avatar/src/EffectAssetDownloadLibrary.ts create mode 100644 packages/avatar/src/EffectAssetDownloadManager.ts create mode 100644 packages/avatar/src/FigureDataContainer.ts create mode 100644 packages/avatar/src/GetAvatarRenderManager.ts create mode 100644 packages/avatar/src/PlaceHolderAvatarImage.ts create mode 100644 packages/avatar/src/actions/ActionDefinition.ts create mode 100644 packages/avatar/src/actions/ActionType.ts create mode 100644 packages/avatar/src/actions/ActiveActionData.ts create mode 100644 packages/avatar/src/actions/AvatarActionManager.ts create mode 100644 packages/avatar/src/actions/index.ts create mode 100644 packages/avatar/src/alias/AssetAlias.ts create mode 100644 packages/avatar/src/alias/AssetAliasCollection.ts create mode 100644 packages/avatar/src/alias/index.ts create mode 100644 packages/avatar/src/animation/AddDataContainer.ts create mode 100644 packages/avatar/src/animation/Animation.ts create mode 100644 packages/avatar/src/animation/AnimationManager.ts create mode 100644 packages/avatar/src/animation/AvatarAnimationLayerData.ts create mode 100644 packages/avatar/src/animation/AvatarDataContainer.ts create mode 100644 packages/avatar/src/animation/DirectionDataContainer.ts create mode 100644 packages/avatar/src/animation/SpriteDataContainer.ts create mode 100644 packages/avatar/src/animation/index.ts create mode 100644 packages/avatar/src/cache/AvatarImageActionCache.ts create mode 100644 packages/avatar/src/cache/AvatarImageBodyPartCache.ts create mode 100644 packages/avatar/src/cache/AvatarImageCache.ts create mode 100644 packages/avatar/src/cache/AvatarImageDirectionCache.ts create mode 100644 packages/avatar/src/cache/ImageData.ts create mode 100644 packages/avatar/src/cache/index.ts create mode 100644 packages/avatar/src/data/HabboAvatarAnimations.ts create mode 100644 packages/avatar/src/data/HabboAvatarGeometry.ts create mode 100644 packages/avatar/src/data/HabboAvatarPartSets.ts create mode 100644 packages/avatar/src/geometry/AvatarModelGeometry.ts create mode 100644 packages/avatar/src/geometry/AvatarSet.ts create mode 100644 packages/avatar/src/geometry/GeometryBodyPart.ts create mode 100644 packages/avatar/src/geometry/GeometryItem.ts create mode 100644 packages/avatar/src/geometry/index.ts create mode 100644 packages/avatar/src/index.ts create mode 100644 packages/avatar/src/structure/AvatarAnimationData.ts create mode 100644 packages/avatar/src/structure/AvatarCanvas.ts create mode 100644 packages/avatar/src/structure/FigureSetData.ts create mode 100644 packages/avatar/src/structure/PartSetsData.ts create mode 100644 packages/avatar/src/structure/animation/AnimationAction.ts create mode 100644 packages/avatar/src/structure/animation/AnimationActionPart.ts create mode 100644 packages/avatar/src/structure/animation/AvatarAnimationFrame.ts create mode 100644 packages/avatar/src/structure/animation/index.ts create mode 100644 packages/avatar/src/structure/figure/FigurePart.ts create mode 100644 packages/avatar/src/structure/figure/FigurePartSet.ts create mode 100644 packages/avatar/src/structure/figure/Palette.ts create mode 100644 packages/avatar/src/structure/figure/PartColor.ts create mode 100644 packages/avatar/src/structure/figure/SetType.ts create mode 100644 packages/avatar/src/structure/figure/index.ts create mode 100644 packages/avatar/src/structure/index.ts create mode 100644 packages/avatar/src/structure/parts/ActivePartSet.ts create mode 100644 packages/avatar/src/structure/parts/PartDefinition.ts create mode 100644 packages/avatar/src/structure/parts/index.ts create mode 100644 packages/avatar/tsconfig.json create mode 100644 packages/camera/.eslintrc.json create mode 100644 packages/camera/.gitignore create mode 100644 packages/camera/index.ts create mode 100644 packages/camera/package.json create mode 100644 packages/camera/src/GetRoomCameraWidgetManager.ts create mode 100644 packages/camera/src/RoomCameraWidgetEffect.ts create mode 100644 packages/camera/src/RoomCameraWidgetManager.ts create mode 100644 packages/camera/src/RoomCameraWidgetSelectedEffect.ts create mode 100644 packages/camera/src/index.ts create mode 100644 packages/camera/tsconfig.json create mode 100644 packages/communication/.eslintrc.json create mode 100644 packages/communication/.gitignore create mode 100644 packages/communication/index.ts create mode 100644 packages/communication/package.json create mode 100644 packages/communication/src/CommunicationManager.ts create mode 100644 packages/communication/src/GetCommunication.ts create mode 100644 packages/communication/src/NitroMessages.ts create mode 100644 packages/communication/src/SocketConnection.ts create mode 100644 packages/communication/src/codec/Byte.ts create mode 100644 packages/communication/src/codec/Short.ts create mode 100644 packages/communication/src/codec/evawire/EvaWireDataWrapper.ts create mode 100644 packages/communication/src/codec/evawire/EvaWireFormat.ts create mode 100644 packages/communication/src/codec/evawire/index.ts create mode 100644 packages/communication/src/codec/index.ts create mode 100644 packages/communication/src/index.ts create mode 100644 packages/communication/src/messages/MessageClassManager.ts create mode 100644 packages/communication/src/messages/incoming/IncomingHeader.ts create mode 100644 packages/communication/src/messages/incoming/advertisement/InterstitialMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/advertisement/RoomAdErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/advertisement/index.ts create mode 100644 packages/communication/src/messages/incoming/availability/AvailabilityStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/availability/AvailabilityTimeMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/availability/HotelClosedAndOpensEvent.ts create mode 100644 packages/communication/src/messages/incoming/availability/HotelClosesAndWillOpenAtEvent.ts create mode 100644 packages/communication/src/messages/incoming/availability/HotelWillCloseInMinutesEvent.ts create mode 100644 packages/communication/src/messages/incoming/availability/MaintenanceStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/availability/index.ts create mode 100644 packages/communication/src/messages/incoming/avatar/ChangeUserNameResultMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/avatar/CheckUserNameResultMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/avatar/FigureUpdateEvent.ts create mode 100644 packages/communication/src/messages/incoming/avatar/WardrobeMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/avatar/index.ts create mode 100644 packages/communication/src/messages/incoming/bots/BotAddedToInventoryEvent.ts create mode 100644 packages/communication/src/messages/incoming/bots/BotInventoryMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/bots/BotReceivedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/bots/BotRemovedFromInventoryEvent.ts create mode 100644 packages/communication/src/messages/incoming/bots/index.ts create mode 100644 packages/communication/src/messages/incoming/callforhelp/CfhSanctionMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/callforhelp/CfhTopicsInitEvent.ts create mode 100644 packages/communication/src/messages/incoming/callforhelp/SanctionStatusEvent.ts create mode 100644 packages/communication/src/messages/incoming/callforhelp/index.ts create mode 100644 packages/communication/src/messages/incoming/camera/CameraPublishStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/camera/CameraPurchaseOKMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/camera/CameraSnapshotMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/camera/CameraStorageUrlMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/camera/CompetitionStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/camera/InitCameraMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/camera/ThumbnailStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/camera/index.ts create mode 100644 packages/communication/src/messages/incoming/campaign/CampaignCalendarDataMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/campaign/CampaignCalendarDoorOpenedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/campaign/index.ts create mode 100644 packages/communication/src/messages/incoming/catalog/BonusRareInfoMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/BuildersClubFurniCountMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/BuildersClubSubscriptionStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/BundleDiscountRulesetMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/CatalogPageExpirationEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/CatalogPageMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/CatalogPageWithEarliestExpiryMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/CatalogPagesListEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/CatalogPublishedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/ClubGiftInfoEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/ClubGiftSelectedEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/DirectSMSClubBuyAvailableMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/FireworkChargeDataEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/GiftReceiverNotFoundEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/GiftWrappingConfigurationEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/HabboClubExtendOfferMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/HabboClubOffersMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/IsOfferGiftableMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/LimitedEditionSoldOutEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/LimitedOfferAppearingNextMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/NotEnoughBalanceMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/ProductOfferEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/PurchaseErrorMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/PurchaseNotAllowedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/PurchaseOKMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/RoomAdPurchaseInfoEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/SeasonalCalendarDailyOfferMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/SellablePetPalettesMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/TargetedOfferEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/TargetedOfferNotFoundEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/VoucherRedeemErrorMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/VoucherRedeemOkMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/catalog/index.ts create mode 100644 packages/communication/src/messages/incoming/client/ClientPingEvent.ts create mode 100644 packages/communication/src/messages/incoming/client/index.ts create mode 100644 packages/communication/src/messages/incoming/competition/CompetitionEntrySubmitResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/competition/CompetitionVotingInfoMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/competition/CurrentTimingCodeMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/competition/IsUserPartOfCompetitionMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/competition/NoOwnedRoomsAlertMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/competition/SecondsUntilMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/competition/index.ts create mode 100644 packages/communication/src/messages/incoming/crafting/CraftableProductsEvent.ts create mode 100644 packages/communication/src/messages/incoming/crafting/CraftingRecipeEvent.ts create mode 100644 packages/communication/src/messages/incoming/crafting/CraftingRecipesAvailableEvent.ts create mode 100644 packages/communication/src/messages/incoming/crafting/CraftingResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/crafting/index.ts create mode 100644 packages/communication/src/messages/incoming/desktop/DesktopViewEvent.ts create mode 100644 packages/communication/src/messages/incoming/desktop/index.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/AcceptFriendResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/FindFriendsProcessResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/FollowFriendFailedEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/FriendListFragmentEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/FriendListUpdateEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/FriendNotificationEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/FriendRequestsEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/HabboSearchResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/InstantMessageErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/MessageErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/MessengerInitEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/MiniMailNewMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/MiniMailUnreadCountEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/NewConsoleMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/NewFriendRequestEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/RoomInviteErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/RoomInviteEvent.ts create mode 100644 packages/communication/src/messages/incoming/friendlist/index.ts create mode 100644 packages/communication/src/messages/incoming/game/directory/Game2AccountGameStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/directory/Game2GameDirectoryStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/directory/Game2InArenaQueueMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/directory/Game2JoiningGameFailedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/directory/Game2StartingGameFailedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/directory/Game2StopCounterMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/directory/Game2UserLeftGameMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/directory/index.ts create mode 100644 packages/communication/src/messages/incoming/game/index.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/AchievementResolutionCompletedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/AchievementResolutionProgressMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/AchievementResolutionsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/GameAchievementsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/GameInviteMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/GameListMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/GameStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/JoinedQueueMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/JoiningQueueFailedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/LeftQueueMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/LoadGameMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/LoadGameUrlEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/UnloadGameMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/UserGameAchievementsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/lobby/index.ts create mode 100644 packages/communication/src/messages/incoming/game/score/Game2WeeklyFriendsLeaderboardEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/score/Game2WeeklyLeaderboardEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/score/WeeklyCompetitiveFriendsLeaderboardEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/score/WeeklyCompetitiveLeaderboardEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/score/WeeklyGameRewardEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/score/WeeklyGameRewardWinnersEvent.ts create mode 100644 packages/communication/src/messages/incoming/game/score/index.ts create mode 100644 packages/communication/src/messages/incoming/generic/GenericErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/generic/index.ts create mode 100644 packages/communication/src/messages/incoming/gifts/PhoneCollectionStateMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/gifts/TryPhoneNumberResultMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/gifts/TryVerificationCodeResultMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/gifts/index.ts create mode 100644 packages/communication/src/messages/incoming/group/GroupBadgePartsEvent.ts create mode 100644 packages/communication/src/messages/incoming/group/GroupBuyDataEvent.ts create mode 100644 packages/communication/src/messages/incoming/group/GroupConfirmMemberRemoveEvent.ts create mode 100644 packages/communication/src/messages/incoming/group/GroupInformationEvent.ts create mode 100644 packages/communication/src/messages/incoming/group/GroupMembersEvent.ts create mode 100644 packages/communication/src/messages/incoming/group/GroupPurchasedEvent.ts create mode 100644 packages/communication/src/messages/incoming/group/GroupSettingsEvent.ts create mode 100644 packages/communication/src/messages/incoming/group/HabboGroupDeactivatedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/group/index.ts create mode 100644 packages/communication/src/messages/incoming/groupforums/ForumDataMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/groupforums/ForumsListMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/groupforums/GuildForumThreadsEvent.ts create mode 100644 packages/communication/src/messages/incoming/groupforums/PostMessageMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/groupforums/PostThreadMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/groupforums/ThreadMessagesMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/groupforums/UnreadForumsCountMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/groupforums/UpdateMessageMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/groupforums/UpdateThreadMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/groupforums/index.ts create mode 100644 packages/communication/src/messages/incoming/handshake/CompleteDiffieHandshakeEvent.ts create mode 100644 packages/communication/src/messages/incoming/handshake/DisconnectReasonEnum.ts create mode 100644 packages/communication/src/messages/incoming/handshake/DisconnectReasonEvent.ts create mode 100644 packages/communication/src/messages/incoming/handshake/IdentityAccountsEvent.ts create mode 100644 packages/communication/src/messages/incoming/handshake/InitDiffieHandshakeEvent.ts create mode 100644 packages/communication/src/messages/incoming/handshake/NoobnessLevelMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/handshake/index.ts create mode 100644 packages/communication/src/messages/incoming/help/CallForHelpDisabledNotifyMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/CallForHelpPendingCallsDeletedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/CallForHelpPendingCallsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/CallForHelpReplyMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/CallForHelpResultMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/ChatReviewSessionDetachedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/ChatReviewSessionOfferedToGuideMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/ChatReviewSessionResultsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/ChatReviewSessionStartedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/ChatReviewSessionVotingStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideOnDutyStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideReportingStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideSessionAttachedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideSessionDetachedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideSessionEndedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideSessionErrorMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideSessionInvitedToGuideRoomMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideSessionMessageMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideSessionPartnerIsTypingMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideSessionRequesterRoomMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideSessionStartedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideTicketCreationResultMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/GuideTicketResolutionMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/HotelMergeNameChangeEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/IssueCloseNotificationMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/QuizDataMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/QuizResultsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/help/index.ts create mode 100644 packages/communication/src/messages/incoming/index.ts create mode 100644 packages/communication/src/messages/incoming/inventory/achievements/AchievementEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/achievements/AchievementsEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/achievements/AchievementsScoreEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/achievements/index.ts create mode 100644 packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectActivatedEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectAddedEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectExpiredEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectSelectedEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectsEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/avatareffect/index.ts create mode 100644 packages/communication/src/messages/incoming/inventory/badges/BadgePointLimitsEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/badges/BadgeReceivedEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/badges/BadgesEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/badges/IsBadgeRequestFulfilledEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/badges/index.ts create mode 100644 packages/communication/src/messages/incoming/inventory/clothes/FigureSetIdsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/clothes/_Str_16135.ts create mode 100644 packages/communication/src/messages/incoming/inventory/clothes/_Str_17532.ts create mode 100644 packages/communication/src/messages/incoming/inventory/clothes/index.ts create mode 100644 packages/communication/src/messages/incoming/inventory/furni/FurnitureListAddOrUpdateEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/furni/FurnitureListEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/furni/FurnitureListInvalidateEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/furni/FurnitureListRemovedEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/furni/FurniturePostItPlacedEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/furni/gifts/PresentOpenedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/furni/gifts/index.ts create mode 100644 packages/communication/src/messages/incoming/inventory/furni/index.ts create mode 100644 packages/communication/src/messages/incoming/inventory/index.ts create mode 100644 packages/communication/src/messages/incoming/inventory/pets/ConfirmBreedingRequestEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/pets/ConfirmBreedingResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/pets/GoToBreedingNestFailureEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/pets/NestBreedingSuccessEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/pets/PetAddedToInventoryEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/pets/PetInventoryEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/pets/PetReceivedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/pets/PetRemovedFromInventoryEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/pets/index.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingAcceptEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingCloseEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingCompletedEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingConfirmationEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingListItemEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingNoSuchItemEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingNotOpenEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingOpenEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingOpenFailedEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingOtherNotAllowedEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/TradingYouAreNotAllowedEvent.ts create mode 100644 packages/communication/src/messages/incoming/inventory/trading/index.ts create mode 100644 packages/communication/src/messages/incoming/landingview/PromoArticlesMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/landingview/index.ts create mode 100644 packages/communication/src/messages/incoming/landingview/votes/CommunityGoalVoteMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/landingview/votes/index.ts create mode 100644 packages/communication/src/messages/incoming/marketplace/MarketplaceBuyOfferResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/marketplace/MarketplaceCanMakeOfferResult.ts create mode 100644 packages/communication/src/messages/incoming/marketplace/MarketplaceCancelOfferResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/marketplace/MarketplaceConfigurationEvent.ts create mode 100644 packages/communication/src/messages/incoming/marketplace/MarketplaceItemStatsEvent.ts create mode 100644 packages/communication/src/messages/incoming/marketplace/MarketplaceMakeOfferResult.ts create mode 100644 packages/communication/src/messages/incoming/marketplace/MarketplaceOffersEvent.ts create mode 100644 packages/communication/src/messages/incoming/marketplace/MarketplaceOwnOffersEvent.ts create mode 100644 packages/communication/src/messages/incoming/marketplace/index.ts create mode 100644 packages/communication/src/messages/incoming/moderation/CfhChatlogEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/IssueDeletedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/IssueInfoMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/IssuePickFailedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/ModeratorActionResultMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/ModeratorCautionEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/ModeratorInitMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/ModeratorMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/ModeratorRoomInfoEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/ModeratorToolPreferencesEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/ModeratorUserInfoEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/RoomChatlogEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/RoomVisitsEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/UserBannedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/UserChatlogEvent.ts create mode 100644 packages/communication/src/messages/incoming/moderation/index.ts create mode 100644 packages/communication/src/messages/incoming/mysterybox/CancelMysteryBoxWaitMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/mysterybox/GotMysteryBoxPrizeMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/mysterybox/MysteryBoxKeysEvent.ts create mode 100644 packages/communication/src/messages/incoming/mysterybox/ShowMysteryBoxWaitMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/mysterybox/index.ts create mode 100644 packages/communication/src/messages/incoming/navigator/CanCreateRoomEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/CanCreateRoomEventEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/CategoriesWithVisitorCountEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/CompetitionRoomsDataMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/ConvertedRoomIdEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/DoorbellMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/FavouriteChangedEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/FavouritesEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/FlatAccessDeniedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/FlatCreatedEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/GetGuestRoomResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/GuestRoomSearchResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/NavigatorCollapsedEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/NavigatorHomeRoomEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/NavigatorLiftedEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/NavigatorMetadataEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/NavigatorOpenRoomCreatorEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/NavigatorSearchEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/NavigatorSearchesEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/NavigatorSettingsEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/PopularRoomTagsResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/RoomEventCancelEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/RoomEventEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/RoomFilterSettingsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/RoomSettingsUpdatedEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/RoomThumbnailUpdateResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/UserEventCatsEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/UserFlatCatsEvent.ts create mode 100644 packages/communication/src/messages/incoming/navigator/index.ts create mode 100644 packages/communication/src/messages/incoming/notifications/AchievementNotificationMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/ActivityPointNotificationMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/BotErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/ClubGiftNotificationEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/ConnectionErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/ElementPointerMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/HabboBroadcastMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/HotelWillShutdownEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/InfoFeedEnableMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/MOTDNotificationEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/NotificationDialogMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/OfferRewardDeliveredMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/PetLevelNotificationEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/PetPlacingErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/RestoreClientMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/SimpleAlertMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/UnseenItemsEvent.ts create mode 100644 packages/communication/src/messages/incoming/notifications/index.ts create mode 100644 packages/communication/src/messages/incoming/nux/NewUserExperienceGift.ts create mode 100644 packages/communication/src/messages/incoming/nux/NewUserExperienceGiftOfferMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/nux/NewUserExperienceGiftOptions.ts create mode 100644 packages/communication/src/messages/incoming/nux/NewUserExperienceNotCompleteEvent.ts create mode 100644 packages/communication/src/messages/incoming/nux/ProductOffer.ts create mode 100644 packages/communication/src/messages/incoming/nux/index.ts create mode 100644 packages/communication/src/messages/incoming/perk/PerkAllowancesMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/perk/index.ts create mode 100644 packages/communication/src/messages/incoming/pet/OpenPetPackageRequestedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/pet/OpenPetPackageResultMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/pet/PetLevelUpdateMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/pet/PetScratchFailedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/pet/PetTrainingPanelMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/pet/breeding/PetBreedingMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/pet/breeding/index.ts create mode 100644 packages/communication/src/messages/incoming/pet/index.ts create mode 100644 packages/communication/src/messages/incoming/poll/PollContentsEvent.ts create mode 100644 packages/communication/src/messages/incoming/poll/PollErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/poll/PollOfferEvent.ts create mode 100644 packages/communication/src/messages/incoming/poll/QuestionAnsweredEvent.ts create mode 100644 packages/communication/src/messages/incoming/poll/QuestionEvent.ts create mode 100644 packages/communication/src/messages/incoming/poll/QuestionFinishedEvent.ts create mode 100644 packages/communication/src/messages/incoming/poll/RoomPollResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/poll/StartRoomPollEvent.ts create mode 100644 packages/communication/src/messages/incoming/poll/index.ts create mode 100644 packages/communication/src/messages/incoming/quest/CommunityGoalEarnedPrizesMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/CommunityGoalHallOfFameMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/CommunityGoalProgressMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/ConcurrentUsersGoalProgressMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/EpicPopupMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/QuestCancelledMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/QuestCompletedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/QuestDailyMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/QuestMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/QuestsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/SeasonalQuestsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/quest/index.ts create mode 100644 packages/communication/src/messages/incoming/recycler/RecyclerFinishedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/recycler/RecyclerStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/recycler/index.ts create mode 100644 packages/communication/src/messages/incoming/room/access/RoomEnterErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/access/RoomEnterEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/access/RoomForwardEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/access/doorbell/RoomDoorbellAcceptedEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/access/doorbell/index.ts create mode 100644 packages/communication/src/messages/incoming/room/access/index.ts create mode 100644 packages/communication/src/messages/incoming/room/access/rights/RoomRightsClearEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/access/rights/RoomRightsEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/access/rights/RoomRightsOwnerEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/access/rights/index.ts create mode 100644 packages/communication/src/messages/incoming/room/bots/BotCommandConfigurationEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/bots/BotForceOpenContextMenuEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/bots/BotSkillListUpdateEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/bots/index.ts create mode 100644 packages/communication/src/messages/incoming/room/data/RoomChatSettingsEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/data/RoomEntryInfoMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/data/RoomScoreEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/data/index.ts create mode 100644 packages/communication/src/messages/incoming/room/engine/FavoriteMembershipUpdateMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/engine/ObjectsDataUpdateEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/engine/ObjectsRollingEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/engine/index.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/CustomUserNotificationMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/DiceValueMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/FurniRentOrBuyoutOfferMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/FurnitureAliasesEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/FurnitureDataEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/FurnitureStackHeightEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/GroupFurniContextMenuInfoMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/ItemDataUpdateMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/LoveLockFurniFinishedEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/LoveLockFurniFriendConfirmedEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/LoveLockFurniStartEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/OneWayDoorStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/RentableSpaceRentFailedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/RentableSpaceRentOkMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/RentableSpaceStatusMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/RequestSpamWallPostItMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/RoomDimmerPresetsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/RoomMessageNotificationMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/WelcomeGiftStatusEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorAddEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorRemoveEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorUpdateEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/floor/index.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/index.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallAddEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallRemoveEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallUpdateEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/wall/index.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeControlVideoMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeDisplayPlaylistsEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeDisplayVideoMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/furniture/youtube/index.ts create mode 100644 packages/communication/src/messages/incoming/room/index.ts create mode 100644 packages/communication/src/messages/incoming/room/mapping/FloorHeightMapEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/mapping/RoomEntryTileMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/mapping/RoomHeightMapEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/mapping/RoomHeightMapUpdateEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/mapping/RoomOccupiedTilesMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/mapping/RoomPaintEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/mapping/RoomReadyMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/mapping/RoomVisualizationSettingsEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/mapping/index.ts create mode 100644 packages/communication/src/messages/incoming/room/pet/PetBreedingResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/pet/PetExperienceEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/pet/PetFigureUpdateEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/pet/PetInfoEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/pet/PetStatusUpdateEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/pet/index.ts create mode 100644 packages/communication/src/messages/incoming/room/session/YouArePlayingGameEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/session/YouAreSpectatorMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/session/index.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitDanceEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitEffectEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitExpressionEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitHandItemEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitHandItemReceivedEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitIdleEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitInfoEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitNumberEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitRemoveEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/RoomUnitStatusEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/chat/FloodControlEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/chat/RemainingMuteEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatShoutEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/chat/RoomUnitTypingEvent.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/chat/index.ts create mode 100644 packages/communication/src/messages/incoming/room/unit/index.ts create mode 100644 packages/communication/src/messages/incoming/roomevents/WiredFurniActionEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomevents/WiredFurniConditionEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomevents/WiredFurniTriggerEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomevents/WiredOpenEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomevents/WiredRewardResultMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomevents/WiredSaveSuccessEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomevents/WiredValidationErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomevents/index.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/BannedUsersFromRoomEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/FlatControllerAddedEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/FlatControllerRemovedEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/FlatControllersEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/MuteAllInRoomEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/NoSuchFlatEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/RoomSettingsDataEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/RoomSettingsErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/RoomSettingsSaveErrorEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/RoomSettingsSavedEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/ShowEnforceRoomCategoryDialogEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/UserUnbannedFromRoomEvent.ts create mode 100644 packages/communication/src/messages/incoming/roomsettings/index.ts create mode 100644 packages/communication/src/messages/incoming/security/AuthenticatedEvent.ts create mode 100644 packages/communication/src/messages/incoming/security/index.ts create mode 100644 packages/communication/src/messages/incoming/sound/JukeboxPlayListFullMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/sound/JukeboxSongDisksMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/sound/NowPlayingMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/sound/OfficialSongIdMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/sound/PlayListMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/sound/PlayListSongAddedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/sound/TraxSongInfoMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/sound/UserSongDisksInventoryMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/sound/index.ts create mode 100644 packages/communication/src/messages/incoming/talent/TalentLevelUpEvent.ts create mode 100644 packages/communication/src/messages/incoming/talent/TalentTrackLevelMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/talent/TalentTrackMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/talent/index.ts create mode 100644 packages/communication/src/messages/incoming/user/AccountSafetyLockStatusChangeMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/ApproveNameMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/ChangeEmailResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/EmailStatusResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/ExtendedProfileChangedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/GroupDetailsChangedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/GroupMembershipRequestedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/GuildEditFailedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/GuildMemberMgmtFailedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/GuildMembershipsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/HabboGroupBadgesMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/HabboGroupJoinFailedMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/IgnoreResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/IgnoredUsersEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/InClientLinkEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/MemberData.ts create mode 100644 packages/communication/src/messages/incoming/user/PetRespectNoficationEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/PetSupplementedNotificationEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/RespectReceivedEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/ScrSendKickbackInfoMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/WelcomeGiftChangeEmailResultEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/access/UserPermissionsEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/access/index.ts create mode 100644 packages/communication/src/messages/incoming/user/data/RelationshipStatusInfoEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/data/UserCurrentBadgesEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/data/UserInfoEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/data/UserNameChangeMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/data/UserProfileEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/data/UserSettingsEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/data/UserTagsMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/data/index.ts create mode 100644 packages/communication/src/messages/incoming/user/index.ts create mode 100644 packages/communication/src/messages/incoming/user/inventory/currency/UserCreditsEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/inventory/currency/UserCurrencyEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/inventory/currency/index.ts create mode 100644 packages/communication/src/messages/incoming/user/inventory/index.ts create mode 100644 packages/communication/src/messages/incoming/user/inventory/subscription/UserSubscriptionEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/inventory/subscription/index.ts create mode 100644 packages/communication/src/messages/incoming/user/wardrobe/UserWardrobePageEvent.ts create mode 100644 packages/communication/src/messages/incoming/user/wardrobe/index.ts create mode 100644 packages/communication/src/messages/incoming/userclassification/UserClassificationMessageEvent.ts create mode 100644 packages/communication/src/messages/incoming/userclassification/index.ts create mode 100644 packages/communication/src/messages/index.ts create mode 100644 packages/communication/src/messages/outgoing/OutgoingHeader.ts create mode 100644 packages/communication/src/messages/outgoing/advertisement/GetInterstitialMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/advertisement/InterstitialShownMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/advertisement/RequestAchievementsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/advertisement/index.ts create mode 100644 packages/communication/src/messages/outgoing/avatar/ChangeUserNameMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/avatar/CheckUserNameMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/avatar/GetWardrobeMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/avatar/SaveWardrobeOutfitMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/avatar/index.ts create mode 100644 packages/communication/src/messages/outgoing/camera/PhotoCompetitionMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/camera/PublishPhotoMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/camera/PurchasePhotoMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/camera/RenderRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/camera/RenderRoomThumbnailMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/camera/RequestCameraConfigurationComposer.ts create mode 100644 packages/communication/src/messages/outgoing/camera/index.ts create mode 100644 packages/communication/src/messages/outgoing/campaign/OpenCampaignCalendarDoorAsStaffComposer.ts create mode 100644 packages/communication/src/messages/outgoing/campaign/OpenCampaignCalendarDoorComposer.ts create mode 100644 packages/communication/src/messages/outgoing/campaign/index.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/BuildersClubPlaceRoomItemMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/BuildersClubPlaceWallItemMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/BuildersClubQueryFurniCountMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetBonusRareInfoMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetBundleDiscountRulesetComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetCatalogIndexComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetCatalogPageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetCatalogPageExpirationComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetCatalogPageWithEarliestExpiryComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetClubGiftInfo.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetClubOffersMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetDirectClubBuyAvailableComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetGiftWrappingConfigurationComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetHabboBasicMembershipExtendOfferComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetHabboClubExtendOfferMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetIsOfferGiftableComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetLimitedOfferAppearingNextComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetNextTargetedOfferComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetProductOfferComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetRoomAdPurchaseInfoComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetSeasonalCalendarDailyOfferComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetSellablePetPalettesComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/GetTargetedOfferComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/MarkCatalogNewAdditionsPageOpenedComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/PurchaseBasicMembershipExtensionComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/PurchaseFromCatalogAsGiftComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/PurchaseFromCatalogComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/PurchaseRoomAdMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/PurchaseTargetedOfferComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/PurchaseVipMembershipExtensionComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/RedeemVoucherMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/RoomAdPurchaseInitiatedComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/SelectClubGiftComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/SetTargetedOfferStateComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/ShopTargetedOfferViewedComposer.ts create mode 100644 packages/communication/src/messages/outgoing/catalog/index.ts create mode 100644 packages/communication/src/messages/outgoing/competition/ForwardToACompetitionRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/competition/ForwardToASubmittableRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/competition/ForwardToRandomCompetitionRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/competition/GetCurrentTimingCodeMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/competition/GetIsUserPartOfCompetitionMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/competition/GetSecondsUntilMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/competition/RoomCompetitionInitMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/competition/SubmitRoomToCompetitionMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/competition/VoteForRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/competition/index.ts create mode 100644 packages/communication/src/messages/outgoing/crafting/CraftComposer.ts create mode 100644 packages/communication/src/messages/outgoing/crafting/CraftSecretComposer.ts create mode 100644 packages/communication/src/messages/outgoing/crafting/GetCraftableProductsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/crafting/GetCraftingRecipeComposer.ts create mode 100644 packages/communication/src/messages/outgoing/crafting/GetCraftingRecipesAvailableComposer.ts create mode 100644 packages/communication/src/messages/outgoing/crafting/index.ts create mode 100644 packages/communication/src/messages/outgoing/desktop/DesktopViewComposer.ts create mode 100644 packages/communication/src/messages/outgoing/desktop/index.ts create mode 100644 packages/communication/src/messages/outgoing/friendfurni/FriendFurniConfirmLockMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendfurni/index.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/AcceptFriendMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/DeclineFriendMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/FindNewFriendsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/FollowFriendMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/FriendListUpdateComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/GetFriendRequestsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/HabboSearchComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/MessengerInitComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/RemoveFriendComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/RequestFriendComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/SendMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/SendRoomInviteComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/SetRelationshipStatusComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/VisitUserComposer.ts create mode 100644 packages/communication/src/messages/outgoing/friendlist/index.ts create mode 100644 packages/communication/src/messages/outgoing/game/arena/Game2ExitGameMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/arena/Game2GameChatMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/arena/Game2LoadStageReadyMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/arena/Game2PlayAgainMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/arena/index.ts create mode 100644 packages/communication/src/messages/outgoing/game/directory/Game2CheckGameDirectoryStatusMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/directory/Game2GetAccountGameStatusMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/directory/index.ts create mode 100644 packages/communication/src/messages/outgoing/game/index.ts create mode 100644 packages/communication/src/messages/outgoing/game/ingame/Game2RequestFullStatusUpdateMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/ingame/index.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/AcceptGameInviteMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/GameUnloadedMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/GetGameAchievementsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/GetGameListMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/GetGameStatusMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/GetResolutionAchievementsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/GetUserGameAchievementsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/JoinQueueMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/LeaveQueueMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/ResetResolutionAchievementMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/lobby/index.ts create mode 100644 packages/communication/src/messages/outgoing/game/score/Game2GetWeeklyFriendsLeaderboardComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/score/Game2GetWeeklyLeaderboardComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/score/GetWeeklyGameRewardComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/score/GetWeeklyGameRewardWinnersComposer.ts create mode 100644 packages/communication/src/messages/outgoing/game/score/index.ts create mode 100644 packages/communication/src/messages/outgoing/gifts/GetGiftMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/gifts/ResetPhoneNumberStateMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/gifts/SetPhoneNumberVerificationStatusMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/gifts/TryPhoneNumberMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/gifts/VerifyCodeMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/gifts/index.ts create mode 100644 packages/communication/src/messages/outgoing/group/ApproveAllMembershipRequestsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupAdminGiveComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupAdminTakeComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupBadgePartsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupBuyComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupBuyDataComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupConfirmRemoveMemberComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupDeleteComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupFavoriteComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupInformationComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupJoinComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupMembersComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupMembershipAcceptComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupMembershipDeclineComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupRemoveMemberComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupSaveBadgeComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupSaveColorsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupSaveInformationComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupSavePreferencesComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupSettingsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/GroupUnfavoriteComposer.ts create mode 100644 packages/communication/src/messages/outgoing/group/index.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/GetForumStatsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/GetForumsListMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/GetMessagesMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/GetThreadMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/GetThreadsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/GetUnreadForumsCountMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/ModerateMessageMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/ModerateThreadMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/PostMessageMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/UpdateForumReadMarkerMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/UpdateForumSettingsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/UpdateThreadMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/groupforums/index.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/AuthenticationMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/ClientHelloMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/CompleteDiffieHandshakeMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/DisconnectMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/InfoRetrieveMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/InitDiffieHandshakeMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/PongMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/SSOTicketMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/UniqueIDMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/VersionCheckMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/handshake/index.ts create mode 100644 packages/communication/src/messages/outgoing/help/CallForHelpFromForumMessageMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/CallForHelpFromForumThreadMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/CallForHelpFromIMMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/CallForHelpFromPhotoMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/CallForHelpFromSelfieMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/CallForHelpMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/ChatReviewGuideDecidesOnOfferMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/ChatReviewGuideDetachedMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/ChatReviewGuideVoteMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/ChatReviewSessionCreateMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/DeletePendingCallsForHelpMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GetCfhStatusMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GetFaqCategoryMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GetFaqTextMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GetGuideReportingStatusMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GetPendingCallsForHelpMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GetQuizQuestionsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionCreateMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionFeedbackMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionGetRequesterRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionGuideDecidesMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionInviteRequesterMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionIsTypingMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionMessageMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionOnDutyUpdateMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionReportMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionRequesterCancelsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/GuideSessionResolvedMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/PostQuizAnswersComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/SearchFaqsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/help/index.ts create mode 100644 packages/communication/src/messages/outgoing/index.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/avatareffect/AvatarEffectActivatedComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/avatareffect/AvatarEffectSelectedComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/avatareffect/index.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/badges/GetBadgePointLimitsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/badges/GetIsBadgeRequestFulfilledComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/badges/RequestABadgeComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/badges/RequestBadgesComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/badges/SetActivatedBadgesComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/badges/index.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/bots/GetBotInventoryComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/bots/index.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/furni/FurnitureListComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/furni/RequestFurniInventoryWhenNotInRoomComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/furni/index.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/index.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/pets/CancelPetBreedingComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/pets/ConfirmPetBreedingComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/pets/RequestPetsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/pets/index.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/trading/TradingAcceptComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/trading/TradingCancelComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/trading/TradingCloseComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/trading/TradingConfirmationComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/trading/TradingListAddItemComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/trading/TradingListAddItemsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/trading/TradingListRemoveItemComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/trading/TradingOpenComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/trading/TradingUnacceptComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/trading/index.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/unseen/UnseenResetCategoryComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/unseen/UnseenResetItemsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/inventory/unseen/index.ts create mode 100644 packages/communication/src/messages/outgoing/landingview/GetPromoArticlesComposer.ts create mode 100644 packages/communication/src/messages/outgoing/landingview/index.ts create mode 100644 packages/communication/src/messages/outgoing/landingview/votes/CommunityGoalVoteMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/landingview/votes/index.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/BuyMarketplaceOfferMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/BuyMarketplaceTokensMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/CancelMarketplaceOfferMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/GetMarketplaceCanMakeOfferComposer.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/GetMarketplaceConfigurationMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/GetMarketplaceItemStatsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/GetMarketplaceOffersMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/GetMarketplaceOwnOffersMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/MakeOfferMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/RedeemMarketplaceOfferCreditsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/marketplace/index.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/CloseIssueDefaultActionMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/CloseIssuesMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/DefaultSanctionMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/GetCfhChatlogMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/GetModeratorRoomInfoMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/GetModeratorUserInfoMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/GetRoomChatlogMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/GetRoomVisitsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/GetUserChatlogMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ModAlertMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ModBanMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ModKickMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ModMessageMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ModMuteMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ModToolPreferencesComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ModToolSanctionComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ModTradingLockMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ModerateRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ModeratorActionMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/PickIssuesMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/ReleaseIssuesMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/moderation/index.ts create mode 100644 packages/communication/src/messages/outgoing/mysterybox/MysteryBoxWaitingCanceledMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/mysterybox/index.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/AddFavouriteRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/CanCreateRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/CancelEventMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/CompetitionRoomsSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/ConvertGlobalRoomIdComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/CreateFlatMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/DeleteFavouriteRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/EditEventMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/ForwardToARandomPromotedRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/ForwardToSomeRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/GetCategoriesWithUserCountMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/GetCustomRoomFilterMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/GetGuestRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/GetOfficialRoomsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/GetPopularRoomTagsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/GetUserEventCatsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/GetUserFlatCatsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/GuildBaseSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/MyFavouriteRoomsSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/MyFrequentRoomHistorySearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/MyFriendsRoomsSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/MyGuildBasesSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/MyRecommendedRoomsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/MyRoomHistorySearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/MyRoomRightsSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/MyRoomsSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/NavigatorCategoryListModeComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/NavigatorDeleteSavedSearchComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/NavigatorInitComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/NavigatorSearchCloseComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/NavigatorSearchComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/NavigatorSearchOpenComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/NavigatorSearchSaveComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/NavigatorSettingsSaveComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/PopularRoomsSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/RateFlatMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/RemoveOwnRoomRightsRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/RoomAdEventTabAdClickedComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/RoomAdEventTabViewedComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/RoomAdSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/RoomTextSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/RoomsWhereMyFriendsAreSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/RoomsWithHighestScoreSearchMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/SetRoomSessionTagsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/ToggleStaffPickMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/UpdateHomeRoomMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/UpdateRoomFilterMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/UpdateRoomThumbnailMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/navigator/index.ts create mode 100644 packages/communication/src/messages/outgoing/nux/NewUserExperienceGetGiftsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/nux/NewUserExperienceGetGiftsSelection.ts create mode 100644 packages/communication/src/messages/outgoing/nux/NewUserExperienceScriptProceedComposer.ts create mode 100644 packages/communication/src/messages/outgoing/nux/index.ts create mode 100644 packages/communication/src/messages/outgoing/pet/GetPetCommandsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/pet/PetMountComposer.ts create mode 100644 packages/communication/src/messages/outgoing/pet/PetRespectComposer.ts create mode 100644 packages/communication/src/messages/outgoing/pet/PetSupplementComposer.ts create mode 100644 packages/communication/src/messages/outgoing/pet/RemovePetSaddleComposer.ts create mode 100644 packages/communication/src/messages/outgoing/pet/RequestPetInfoComposer.ts create mode 100644 packages/communication/src/messages/outgoing/pet/TogglePetBreedingComposer.ts create mode 100644 packages/communication/src/messages/outgoing/pet/TogglePetRidingComposer.ts create mode 100644 packages/communication/src/messages/outgoing/pet/UsePetProductComposer.ts create mode 100644 packages/communication/src/messages/outgoing/pet/index.ts create mode 100644 packages/communication/src/messages/outgoing/poll/PollAnswerComposer.ts create mode 100644 packages/communication/src/messages/outgoing/poll/PollRejectComposer.ts create mode 100644 packages/communication/src/messages/outgoing/poll/PollStartComposer.ts create mode 100644 packages/communication/src/messages/outgoing/poll/VotePollCounterMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/poll/index.ts create mode 100644 packages/communication/src/messages/outgoing/quest/AcceptQuestMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/ActivateQuestMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/CancelQuestMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/FriendRequestQuestCompleteMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/GetCommunityGoalEarnedPrizesMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/GetCommunityGoalHallOfFameMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/GetCommunityGoalProgressMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/GetConcurrentUsersGoalProgressMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/GetConcurrentUsersRewardMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/GetDailyQuestMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/GetQuestsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/GetSeasonalQuestsOnlyMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/OpenQuestTrackerMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/RedeemCommunityGoalPrizeMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/RejectQuestMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/StartCampaignMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/quest/index.ts create mode 100644 packages/communication/src/messages/outgoing/recycler/GetRecyclerStatusMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/recycler/RecycleItemsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/recycler/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/RedeemItemClothingComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/access/RoomDoorbellAccessComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/access/RoomEnterComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/access/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/action/RemoveAllRightsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/action/RoomAmbassadorAlertComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/action/RoomBanUserComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/action/RoomDeleteComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/action/RoomGiveRightsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/action/RoomKickUserComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/action/RoomMuteUserComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/action/RoomTakeRightsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/action/RoomUnbanUserComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/action/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/bots/RequestBotConfigurationComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/bots/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/data/RoomBannedUsersComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/data/RoomSettingsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/data/RoomUsersWithRightsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/data/SaveRoomSettingsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/data/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/BotPlaceComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/BotRemoveComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/BotSkillSaveComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/CompostPlantMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/GetItemDataComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/HarvestPetMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/PetMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/PetMoveComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/PetPlaceComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/PetRemoveComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/RemoveWallItemComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/SetClothingChangeDataMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/SetItemDataMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/SetObjectDataMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/engine/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/AddSpamWallPostItMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/ExtendRentOrBuyoutFurniMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/ExtendRentOrBuyoutStripItemMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/FurnitureAliasesComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/FurnitureGroupInfoComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/FurniturePickupComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/FurniturePlaceComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/FurniturePlacePaintComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/FurniturePostItPlaceComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/GetRentOrBuyoutOfferMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/OpenMysteryTrophyMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/OpenPetPackageMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/OpenWelcomeGiftComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/RentableSpaceCancelRentMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/RentableSpaceRentMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/RentableSpaceStatusMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightSettingsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightSettingsSaveComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightTogggleStateComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/dimmer/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/floor/FurnitureFloorUpdateComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/floor/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureColorWheelComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureDiceActivateComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureDiceDeactivateComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureExchangeComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureMultiStateComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureOneWayDoorComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureRandomStateComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureStackHeightComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureWallMultiStateComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/logic/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveLookComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveNameComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/mannequin/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/presents/OpenPresentComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/presents/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/toner/ApplyTonerComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/toner/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/wall/FurnitureWallUpdateComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/wall/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/youtube/ControlYoutubeDisplayPlaybackMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/youtube/GetYoutubeDisplayStatusMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/youtube/SetYoutubeDisplayPlaylistMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/furniture/youtube/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/layout/GetOccupiedTilesMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/layout/GetRoomEntryDataMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/layout/GetRoomEntryTileMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/layout/UpdateFloorPropertiesMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/layout/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/pets/BreedPetsMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/pets/PetSelectedMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/pets/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/session/ChangeQueueMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/session/GoToFlatMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/session/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/RoomUnitActionComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/RoomUnitDanceComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/RoomUnitDropHandItemComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/RoomUnitGiveHandItemComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/RoomUnitGiveHandItemPetComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/RoomUnitLookComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/RoomUnitPostureComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/RoomUnitSignComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/RoomUnitWalkComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatShoutComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatStyleComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatWhisperComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitTypingStartComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitTypingStopComposer.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/chat/index.ts create mode 100644 packages/communication/src/messages/outgoing/room/unit/index.ts create mode 100644 packages/communication/src/messages/outgoing/roomdirectory/RoomNetworkOpenConnectionMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/roomdirectory/index.ts create mode 100644 packages/communication/src/messages/outgoing/roomevents/ApplySnapshotMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/roomevents/OpenMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/roomevents/RoomMuteComposer.ts create mode 100644 packages/communication/src/messages/outgoing/roomevents/UpdateActionMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/roomevents/UpdateConditionMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/roomevents/UpdateTriggerMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/roomevents/index.ts create mode 100644 packages/communication/src/messages/outgoing/roomsettings/SaveableRoomSettingsData.ts create mode 100644 packages/communication/src/messages/outgoing/roomsettings/UpdateRoomCategoryAndTradeSettingsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/roomsettings/index.ts create mode 100644 packages/communication/src/messages/outgoing/sound/AddJukeboxDiskComposer.ts create mode 100644 packages/communication/src/messages/outgoing/sound/GetJukeboxPlayListMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/sound/GetNowPlayingMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/sound/GetOfficialSongIdMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/sound/GetSongInfoMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/sound/GetSoundMachinePlayListMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/sound/GetSoundSettingsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/sound/GetUserSongDisksMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/sound/RemoveJukeboxDiskComposer.ts create mode 100644 packages/communication/src/messages/outgoing/sound/index.ts create mode 100644 packages/communication/src/messages/outgoing/talent/GetTalentTrackLevelMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/talent/TalentTrackComposer.ts create mode 100644 packages/communication/src/messages/outgoing/talent/index.ts create mode 100644 packages/communication/src/messages/outgoing/tracking/LagWarningReportMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/tracking/PerformanceLogMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/tracking/index.ts create mode 100644 packages/communication/src/messages/outgoing/user/ApproveNameMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/CatalogGroupsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/ChangeEmailComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/GetEmailStatusComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/GetHabboGroupBadgesMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/ScrGetKickbackInfoMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/UnblockGroupMemberMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/UserRespectComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/WelcomeGiftChangeEmailComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/GetExtendedProfileByNameMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/GetIgnoredUsersComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/GetUserTagsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/IgnoreUserComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/IgnoreUserIdComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/UnignoreUserComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/UserCurrentBadgesComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/UserFigureComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/UserMottoComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/UserProfileComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/UserRelationshipsComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/data/index.ts create mode 100644 packages/communication/src/messages/outgoing/user/index.ts create mode 100644 packages/communication/src/messages/outgoing/user/inventory/currency/UserCurrencyComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/inventory/currency/index.ts create mode 100644 packages/communication/src/messages/outgoing/user/inventory/index.ts create mode 100644 packages/communication/src/messages/outgoing/user/inventory/subscription/UserSubscriptionComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/inventory/subscription/index.ts create mode 100644 packages/communication/src/messages/outgoing/user/settings/UserSettingsCameraFollowComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/settings/UserSettingsOldChatComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/settings/UserSettingsRoomInvitesComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/settings/UserSettingsSoundComposer.ts create mode 100644 packages/communication/src/messages/outgoing/user/settings/index.ts create mode 100644 packages/communication/src/messages/outgoing/userclassification/PeerUsersClassificationMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/userclassification/RoomUsersClassificationMessageComposer.ts create mode 100644 packages/communication/src/messages/outgoing/userclassification/index.ts create mode 100644 packages/communication/src/messages/parser/advertisement/InterstitialMessageParser.ts create mode 100644 packages/communication/src/messages/parser/advertisement/RoomAdErrorMessageParser.ts create mode 100644 packages/communication/src/messages/parser/advertisement/index.ts create mode 100644 packages/communication/src/messages/parser/availability/AvailabilityStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/availability/AvailabilityTimeMessageParser.ts create mode 100644 packages/communication/src/messages/parser/availability/HotelClosedAndOpensMessageParser.ts create mode 100644 packages/communication/src/messages/parser/availability/HotelClosesAndWillOpenAtMessageParser.ts create mode 100644 packages/communication/src/messages/parser/availability/HotelWillCloseInMinutesMessageParser.ts create mode 100644 packages/communication/src/messages/parser/availability/MaintenanceStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/availability/index.ts create mode 100644 packages/communication/src/messages/parser/avatar/ChangeUserNameResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/avatar/CheckUserNameResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/avatar/FigureUpdateParser.ts create mode 100644 packages/communication/src/messages/parser/avatar/OutfitData.ts create mode 100644 packages/communication/src/messages/parser/avatar/WardrobeMessageParser.ts create mode 100644 packages/communication/src/messages/parser/avatar/index.ts create mode 100644 packages/communication/src/messages/parser/bots/BotAddedToInventoryParser.ts create mode 100644 packages/communication/src/messages/parser/bots/BotData.ts create mode 100644 packages/communication/src/messages/parser/bots/BotInventoryMessageParser.ts create mode 100644 packages/communication/src/messages/parser/bots/BotReceivedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/bots/BotRemovedFromInventoryParser.ts create mode 100644 packages/communication/src/messages/parser/bots/index.ts create mode 100644 packages/communication/src/messages/parser/callforhelp/CallForHelpCategoryData.ts create mode 100644 packages/communication/src/messages/parser/callforhelp/CallForHelpTopicData.ts create mode 100644 packages/communication/src/messages/parser/callforhelp/CfhSanctionMessageParser.ts create mode 100644 packages/communication/src/messages/parser/callforhelp/CfhSanctionTypeData.ts create mode 100644 packages/communication/src/messages/parser/callforhelp/CfhTopicsInitMessageParser.ts create mode 100644 packages/communication/src/messages/parser/callforhelp/SanctionStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/callforhelp/index.ts create mode 100644 packages/communication/src/messages/parser/camera/CameraPublishStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/camera/CameraPurchaseOKMessageParser.ts create mode 100644 packages/communication/src/messages/parser/camera/CameraSnapshotMessageParser.ts create mode 100644 packages/communication/src/messages/parser/camera/CameraStorageUrlMessageParser.ts create mode 100644 packages/communication/src/messages/parser/camera/CompetitionStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/camera/InitCameraMessageParser.ts create mode 100644 packages/communication/src/messages/parser/camera/ThumbnailStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/camera/index.ts create mode 100644 packages/communication/src/messages/parser/campaign/CampaignCalendarData.ts create mode 100644 packages/communication/src/messages/parser/campaign/CampaignCalendarDataMessageParser.ts create mode 100644 packages/communication/src/messages/parser/campaign/CampaignCalendarDoorOpenedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/campaign/index.ts create mode 100644 packages/communication/src/messages/parser/catalog/BonusRareInfoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/BuildersClubFurniCountMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/BuildersClubSubscriptionStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/BundleDiscountRuleset.ts create mode 100644 packages/communication/src/messages/parser/catalog/BundleDiscountRulesetMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/CatalogIndexMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/CatalogLocalizationData.ts create mode 100644 packages/communication/src/messages/parser/catalog/CatalogPageExpirationParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/CatalogPageMessageOfferData.ts create mode 100644 packages/communication/src/messages/parser/catalog/CatalogPageMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/CatalogPageMessageProductData.ts create mode 100644 packages/communication/src/messages/parser/catalog/CatalogPageWithEarliestExpiryMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/CatalogPublishedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/ClubGiftData.ts create mode 100644 packages/communication/src/messages/parser/catalog/ClubGiftInfoParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/ClubGiftSelectedParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/ClubOfferData.ts create mode 100644 packages/communication/src/messages/parser/catalog/ClubOfferExtendData.ts create mode 100644 packages/communication/src/messages/parser/catalog/DirectSMSClubBuyAvailableMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/FireworkChargeData.ts create mode 100644 packages/communication/src/messages/parser/catalog/FireworkChargeDataParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/FrontPageItem.ts create mode 100644 packages/communication/src/messages/parser/catalog/GiftReceiverNotFoundParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/GiftWrappingConfigurationParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/HabboClubExtendOfferMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/HabboClubOffersMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/INodeData.ts create mode 100644 packages/communication/src/messages/parser/catalog/IsOfferGiftableMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/LimitedEditionSoldOutParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/LimitedOfferAppearingNextMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/NodeData.ts create mode 100644 packages/communication/src/messages/parser/catalog/NotEnoughBalanceMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/ProductOfferMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/PurchaseErrorMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/PurchaseNotAllowedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/PurchaseOKMessageOfferData.ts create mode 100644 packages/communication/src/messages/parser/catalog/PurchaseOKMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/RoomAdPurchaseInfoEventParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/SeasonalCalendarDailyOfferMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/SellablePetPaletteData.ts create mode 100644 packages/communication/src/messages/parser/catalog/SellablePetPalettesParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/TargetedOfferData.ts create mode 100644 packages/communication/src/messages/parser/catalog/TargetedOfferNotFoundParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/TargetedOfferParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/VoucherRedeemErrorMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/VoucherRedeemOkMessageParser.ts create mode 100644 packages/communication/src/messages/parser/catalog/index.ts create mode 100644 packages/communication/src/messages/parser/client/ClientPingParser.ts create mode 100644 packages/communication/src/messages/parser/client/index.ts create mode 100644 packages/communication/src/messages/parser/competition/CompetitionEntrySubmitResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/competition/CompetitionVotingInfoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/competition/CompetitionVotingInfoResult.ts create mode 100644 packages/communication/src/messages/parser/competition/CurrentTimingCodeMessageParser.ts create mode 100644 packages/communication/src/messages/parser/competition/IsUserPartOfCompetitionMessageParser.ts create mode 100644 packages/communication/src/messages/parser/competition/NoOwnedRoomsAlertMessageParser.ts create mode 100644 packages/communication/src/messages/parser/competition/SecondsUntilMessageParser.ts create mode 100644 packages/communication/src/messages/parser/competition/index.ts create mode 100644 packages/communication/src/messages/parser/crafting/CraftableProductsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/crafting/CraftingRecipeIngredientParser.ts create mode 100644 packages/communication/src/messages/parser/crafting/CraftingRecipeMessageParser.ts create mode 100644 packages/communication/src/messages/parser/crafting/CraftingRecipesAvailableMessageParser.ts create mode 100644 packages/communication/src/messages/parser/crafting/CraftingResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/crafting/CraftingResultObjectParser.ts create mode 100644 packages/communication/src/messages/parser/crafting/index.ts create mode 100644 packages/communication/src/messages/parser/desktop/DesktopViewParser.ts create mode 100644 packages/communication/src/messages/parser/desktop/index.ts create mode 100644 packages/communication/src/messages/parser/friendlist/AcceptFriendFailureData.ts create mode 100644 packages/communication/src/messages/parser/friendlist/AcceptFriendResultParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/FindFriendsProcessResultParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/FollowFriendFailedParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/FriendCategoryData.ts create mode 100644 packages/communication/src/messages/parser/friendlist/FriendListFragmentMessageParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/FriendListUpdateParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/FriendNotificationParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/FriendParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/FriendRequestData.ts create mode 100644 packages/communication/src/messages/parser/friendlist/FriendRequestsParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/HabboSearchResultData.ts create mode 100644 packages/communication/src/messages/parser/friendlist/HabboSearchResultParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/InstantMessageErrorParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/MessageErrorParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/MessengerInitParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/MiniMailNewMessageParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/MiniMailUnreadCountParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/NewConsoleMessageParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/NewFriendRequestMessageParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/RoomInviteErrorParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/RoomInviteMessageParser.ts create mode 100644 packages/communication/src/messages/parser/friendlist/index.ts create mode 100644 packages/communication/src/messages/parser/game/directory/Game2AccountGameStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/directory/Game2GameDirectoryStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/directory/Game2InArenaQueueMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/directory/Game2JoiningGameFailedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/directory/Game2StartingGameFailedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/directory/Game2StopCounterMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/directory/Game2UserLeftGameMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/directory/index.ts create mode 100644 packages/communication/src/messages/parser/game/index.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/AchievementResolutionCompletedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/AchievementResolutionProgressMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/AchievementResolutionsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/GameAchievementData.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/GameAchievementsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/GameConfigurationData.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/GameInviteMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/GameListMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/GameStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/JoinedQueueMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/JoiningQueueFailedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/LeftQueueMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/LoadGameMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/LoadGameUrlParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/UnloadGameMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/UserGameAchievementsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/game/lobby/index.ts create mode 100644 packages/communication/src/messages/parser/game/score/Game2WeeklyLeaderboardParser.ts create mode 100644 packages/communication/src/messages/parser/game/score/GameRewardWinnerEntry.ts create mode 100644 packages/communication/src/messages/parser/game/score/LeaderboardEntry.ts create mode 100644 packages/communication/src/messages/parser/game/score/WeeklyGameRewardParser.ts create mode 100644 packages/communication/src/messages/parser/game/score/WeeklyGameRewardWinnersParser.ts create mode 100644 packages/communication/src/messages/parser/game/score/index.ts create mode 100644 packages/communication/src/messages/parser/generic/GenericErrorParser.ts create mode 100644 packages/communication/src/messages/parser/generic/index.ts create mode 100644 packages/communication/src/messages/parser/gifts/PhoneCollectionStateParser.ts create mode 100644 packages/communication/src/messages/parser/gifts/TryPhoneNumberResultParser.ts create mode 100644 packages/communication/src/messages/parser/gifts/TryVerificationCodeResultParser.ts create mode 100644 packages/communication/src/messages/parser/gifts/index.ts create mode 100644 packages/communication/src/messages/parser/group/GroupBadgePartsParser.ts create mode 100644 packages/communication/src/messages/parser/group/GroupBuyDataParser.ts create mode 100644 packages/communication/src/messages/parser/group/GroupConfirmMemberRemoveParser.ts create mode 100644 packages/communication/src/messages/parser/group/GroupInformationParser.ts create mode 100644 packages/communication/src/messages/parser/group/GroupMembersParser.ts create mode 100644 packages/communication/src/messages/parser/group/GroupPurchasedParser.ts create mode 100644 packages/communication/src/messages/parser/group/GroupSettingsParser.ts create mode 100644 packages/communication/src/messages/parser/group/HabboGroupDeactivatedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/group/index.ts create mode 100644 packages/communication/src/messages/parser/group/utils/GroupDataBadgePart.ts create mode 100644 packages/communication/src/messages/parser/group/utils/GroupMemberParser.ts create mode 100644 packages/communication/src/messages/parser/group/utils/index.ts create mode 100644 packages/communication/src/messages/parser/groupforums/ExtendedForumData.ts create mode 100644 packages/communication/src/messages/parser/groupforums/ForumData.ts create mode 100644 packages/communication/src/messages/parser/groupforums/ForumDataMessageParser.ts create mode 100644 packages/communication/src/messages/parser/groupforums/GetForumsListMessageParser.ts create mode 100644 packages/communication/src/messages/parser/groupforums/GuildForumThread.ts create mode 100644 packages/communication/src/messages/parser/groupforums/GuildForumThreadsParser.ts create mode 100644 packages/communication/src/messages/parser/groupforums/MessageData.ts create mode 100644 packages/communication/src/messages/parser/groupforums/PostMessageMessageParser.ts create mode 100644 packages/communication/src/messages/parser/groupforums/PostThreadMessageParser.ts create mode 100644 packages/communication/src/messages/parser/groupforums/ThreadMessagesMessageParser.ts create mode 100644 packages/communication/src/messages/parser/groupforums/UnreadForumsCountMessageParser.ts create mode 100644 packages/communication/src/messages/parser/groupforums/UpdateMessageMessageParser.ts create mode 100644 packages/communication/src/messages/parser/groupforums/UpdateThreadMessageParser.ts create mode 100644 packages/communication/src/messages/parser/groupforums/index.ts create mode 100644 packages/communication/src/messages/parser/handshake/CompleteDiffieHandshakeParser.ts create mode 100644 packages/communication/src/messages/parser/handshake/DisconnectReasonParser.ts create mode 100644 packages/communication/src/messages/parser/handshake/IdentityAccountsParser.ts create mode 100644 packages/communication/src/messages/parser/handshake/InitDiffieHandshakeParser.ts create mode 100644 packages/communication/src/messages/parser/handshake/NoobnessLevelMessageParser.ts create mode 100644 packages/communication/src/messages/parser/handshake/index.ts create mode 100644 packages/communication/src/messages/parser/help/CallForHelpDisabledNotifyMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/CallForHelpPendingCallsDeletedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/CallForHelpPendingCallsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/CallForHelpReplyMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/CallForHelpResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/ChatReviewSessionDetachedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/ChatReviewSessionOfferedToGuideMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/ChatReviewSessionResultsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/ChatReviewSessionStartedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/ChatReviewSessionVotingStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideOnDutyStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideReportingStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideSessionAttachedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideSessionDetachedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideSessionEndedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideSessionErrorMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideSessionInvitedToGuideRoomMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideSessionMessageMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideSessionPartnerIsTypingMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideSessionRequesterRoomMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideSessionStartedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideTicketCreationResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/GuideTicketResolutionMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/HotelMergeNameChangeParser.ts create mode 100644 packages/communication/src/messages/parser/help/IssueCloseNotificationMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/PendingGuideTicketData.ts create mode 100644 packages/communication/src/messages/parser/help/QuizDataMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/QuizResultsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/help/index.ts create mode 100644 packages/communication/src/messages/parser/index.ts create mode 100644 packages/communication/src/messages/parser/inventory/achievements/AchievementData.ts create mode 100644 packages/communication/src/messages/parser/inventory/achievements/AchievementParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/achievements/AchievementResolutionData.ts create mode 100644 packages/communication/src/messages/parser/inventory/achievements/AchievementsParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/achievements/AchievementsScoreParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/achievements/index.ts create mode 100644 packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffect.ts create mode 100644 packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectActivatedParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectAddedParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectExpiredParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectSelectedParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectsParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/avatareffect/index.ts create mode 100644 packages/communication/src/messages/parser/inventory/badges/BadgeAndPointLimit.ts create mode 100644 packages/communication/src/messages/parser/inventory/badges/BadgePointLimitsParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/badges/BadgeReceivedParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/badges/BadgesParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/badges/IsBadgeRequestFulfilledParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/badges/index.ts create mode 100644 packages/communication/src/messages/parser/inventory/clothing/FigureSetIdsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/clothing/_Str_8728.ts create mode 100644 packages/communication/src/messages/parser/inventory/clothing/_Str_9021.ts create mode 100644 packages/communication/src/messages/parser/inventory/clothing/index.ts create mode 100644 packages/communication/src/messages/parser/inventory/furniture/FurnitureListAddOrUpdateParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/furniture/FurnitureListInvalidateParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/furniture/FurnitureListItemParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/furniture/FurnitureListParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/furniture/FurnitureListRemovedParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/furniture/FurniturePostItPlacedParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/furniture/IFurnitureItemData.ts create mode 100644 packages/communication/src/messages/parser/inventory/furniture/PresentOpenedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/furniture/index.ts create mode 100644 packages/communication/src/messages/parser/inventory/index.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/ConfirmBreedingRequestParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/ConfirmBreedingResultParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/GoToBreedingNestFailureParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/NestBreedingSuccessParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/PetAddedToInventoryParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/PetBreedingMessageParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/PetData.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/PetFigureDataParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/PetInventoryParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/PetReceivedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/PetRemovedFromInventoryParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/pets/index.ts create mode 100644 packages/communication/src/messages/parser/inventory/purse/UserCreditsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/purse/index.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/ItemDataStructure.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingAcceptParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingCloseParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingCompletedParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingConfirmationParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingListItemParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingNoSuchItemParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingNotOpenParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingOpenFailedParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingOpenParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingOtherNotAllowedParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/TradingYouAreNotAllowedParser.ts create mode 100644 packages/communication/src/messages/parser/inventory/trading/index.ts create mode 100644 packages/communication/src/messages/parser/landingview/PromoArticleData.ts create mode 100644 packages/communication/src/messages/parser/landingview/PromoArticlesMessageParser.ts create mode 100644 packages/communication/src/messages/parser/landingview/index.ts create mode 100644 packages/communication/src/messages/parser/landingview/votes/CommunityVoteReceivedParser.ts create mode 100644 packages/communication/src/messages/parser/landingview/votes/index.ts create mode 100644 packages/communication/src/messages/parser/marketplace/MarketplaceBuyOfferResultParser.ts create mode 100644 packages/communication/src/messages/parser/marketplace/MarketplaceCanMakeOfferResultParser.ts create mode 100644 packages/communication/src/messages/parser/marketplace/MarketplaceCancelOfferResultParser.ts create mode 100644 packages/communication/src/messages/parser/marketplace/MarketplaceConfigurationMessageParser.ts create mode 100644 packages/communication/src/messages/parser/marketplace/MarketplaceItemPostedParser.ts create mode 100644 packages/communication/src/messages/parser/marketplace/MarketplaceItemStatsParser.ts create mode 100644 packages/communication/src/messages/parser/marketplace/MarketplaceOffer.ts rename {src/api/catalog => packages/communication/src/messages/parser/marketplace}/MarketplaceOfferData.ts (94%) create mode 100644 packages/communication/src/messages/parser/marketplace/MarketplaceOffersParser.ts create mode 100644 packages/communication/src/messages/parser/marketplace/MarketplaceOwnOffersParser.ts create mode 100644 packages/communication/src/messages/parser/marketplace/index.ts create mode 100644 packages/communication/src/messages/parser/moderation/CfhChatlogData.ts create mode 100644 packages/communication/src/messages/parser/moderation/CfhChatlogMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/ChatRecordData.ts create mode 100644 packages/communication/src/messages/parser/moderation/ChatlineData.ts create mode 100644 packages/communication/src/messages/parser/moderation/INamed.ts create mode 100644 packages/communication/src/messages/parser/moderation/IssueDeletedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/IssueInfoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/IssueMessageData.ts create mode 100644 packages/communication/src/messages/parser/moderation/IssuePickFailedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/ModRoomData.ts create mode 100644 packages/communication/src/messages/parser/moderation/ModerationCautionParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/ModeratorActionResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/ModeratorInitData.ts create mode 100644 packages/communication/src/messages/parser/moderation/ModeratorInitMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/ModeratorMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/ModeratorRoomInfoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/ModeratorToolPreferencesMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/ModeratorUserInfoData.ts create mode 100644 packages/communication/src/messages/parser/moderation/ModeratorUserInfoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/PatternMatchData.ts create mode 100644 packages/communication/src/messages/parser/moderation/RoomChatlogMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/RoomModerationData.ts create mode 100644 packages/communication/src/messages/parser/moderation/RoomVisitData.ts create mode 100644 packages/communication/src/messages/parser/moderation/RoomVisitsData.ts create mode 100644 packages/communication/src/messages/parser/moderation/RoomVisitsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/UserBannedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/UserChatlogData.ts create mode 100644 packages/communication/src/messages/parser/moderation/UserChatlogMessageParser.ts create mode 100644 packages/communication/src/messages/parser/moderation/index.ts create mode 100644 packages/communication/src/messages/parser/mysterybox/CancelMysteryBoxWaitMessageParser.ts create mode 100644 packages/communication/src/messages/parser/mysterybox/GotMysteryBoxPrizeMessageParser.ts create mode 100644 packages/communication/src/messages/parser/mysterybox/MysteryBoxKeysParser.ts create mode 100644 packages/communication/src/messages/parser/mysterybox/ShowMysteryBoxWaitMessageParser.ts create mode 100644 packages/communication/src/messages/parser/mysterybox/index.ts create mode 100644 packages/communication/src/messages/parser/navigator/CanCreateRoomEventParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/CanCreateRoomMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/CategoriesWithVisitorCountParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/CompetitionRoomsDataMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/ConvertedRoomIdMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/DoorbellMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/FavouriteChangedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/FavouritesMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/FlatAccessDeniedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/FlatCreatedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/GetGuestRoomResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/GuestRoomSearchResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorCategoryDataParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorCollapsedParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorEventCategoryDataParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorHomeRoomParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorLiftedDataParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorLiftedParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorMetadataParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorOpenRoomCreatorParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorSearchParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorSearchesParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/NavigatorSettingsParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/PopularRoomTagsData.ts create mode 100644 packages/communication/src/messages/parser/navigator/PopularRoomTagsResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/PopularTagData.ts create mode 100644 packages/communication/src/messages/parser/navigator/RoomEventCancelMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/RoomEventMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/RoomFilterSettingsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/RoomSettingsUpdatedParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/RoomThumbnailUpdateResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/UserEventCatsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/UserFlatCatsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/navigator/index.ts create mode 100644 packages/communication/src/messages/parser/navigator/utils/CategoriesWithVisitorCountData.ts create mode 100644 packages/communication/src/messages/parser/navigator/utils/CompetitionRoomsData.ts create mode 100644 packages/communication/src/messages/parser/navigator/utils/GuestRoomSearchResultData.ts create mode 100644 packages/communication/src/messages/parser/navigator/utils/NavigatorSavedSearch.ts create mode 100644 packages/communication/src/messages/parser/navigator/utils/NavigatorSearchResultList.ts create mode 100644 packages/communication/src/messages/parser/navigator/utils/NavigatorSearchResultSet.ts create mode 100644 packages/communication/src/messages/parser/navigator/utils/NavigatorTopLevelContext.ts create mode 100644 packages/communication/src/messages/parser/navigator/utils/OfficialRoomEntryData.ts create mode 100644 packages/communication/src/messages/parser/navigator/utils/RoomEventData.ts create mode 100644 packages/communication/src/messages/parser/navigator/utils/index.ts create mode 100644 packages/communication/src/messages/parser/notifications/AchievementLevelUpData.ts create mode 100644 packages/communication/src/messages/parser/notifications/AchievementNotificationMessageParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/ActivityPointNotificationParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/BotErrorEventParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/ClubGiftNotificationParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/ConnectionErrorMessageParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/ElementPointerMessageParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/HabboBroadcastMessageParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/HotelWillShutdownParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/InfoFeedEnableMessageParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/MOTDNotificationParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/NotificationDialogMessageParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/OfferRewardDeliveredMessageParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/PetLevelNotificationParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/PetPlacingErrorEventParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/RestoreClientMessageParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/SimpleAlertMessageParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/UnseenItemsParser.ts create mode 100644 packages/communication/src/messages/parser/notifications/index.ts create mode 100644 packages/communication/src/messages/parser/nux/NewUserExperienceGiftOfferMessageParser.ts create mode 100644 packages/communication/src/messages/parser/nux/NewUserExperienceNotCompleteParser.ts create mode 100644 packages/communication/src/messages/parser/nux/index.ts create mode 100644 packages/communication/src/messages/parser/perk/PerkAllowancesMessageParser.ts create mode 100644 packages/communication/src/messages/parser/perk/common/PerkData.ts create mode 100644 packages/communication/src/messages/parser/perk/common/PerkEnum.ts create mode 100644 packages/communication/src/messages/parser/perk/common/index.ts create mode 100644 packages/communication/src/messages/parser/perk/index.ts create mode 100644 packages/communication/src/messages/parser/pet/OpenPetPackageRequestedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/pet/OpenPetPackageResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/pet/PetLevelUpdateMessageParser.ts create mode 100644 packages/communication/src/messages/parser/pet/PetScratchFailedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/pet/PetTrainingMessageParser.ts create mode 100644 packages/communication/src/messages/parser/pet/index.ts create mode 100644 packages/communication/src/messages/parser/poll/PollChoice.ts create mode 100644 packages/communication/src/messages/parser/poll/PollContentsParser.ts create mode 100644 packages/communication/src/messages/parser/poll/PollErrorParser.ts create mode 100644 packages/communication/src/messages/parser/poll/PollOfferParser.ts create mode 100644 packages/communication/src/messages/parser/poll/PollQuestion.ts create mode 100644 packages/communication/src/messages/parser/poll/QuestionAnsweredParser.ts create mode 100644 packages/communication/src/messages/parser/poll/QuestionFinishedParser.ts create mode 100644 packages/communication/src/messages/parser/poll/QuestionParser.ts create mode 100644 packages/communication/src/messages/parser/poll/RoomPollDataParser.ts create mode 100644 packages/communication/src/messages/parser/poll/RoomPollResultParser.ts create mode 100644 packages/communication/src/messages/parser/poll/index.ts create mode 100644 packages/communication/src/messages/parser/quest/CommunityGoalData.ts create mode 100644 packages/communication/src/messages/parser/quest/CommunityGoalEarnedPrizesMessageParser.ts create mode 100644 packages/communication/src/messages/parser/quest/CommunityGoalHallOfFameData.ts create mode 100644 packages/communication/src/messages/parser/quest/CommunityGoalHallOfFameMessageParser.ts create mode 100644 packages/communication/src/messages/parser/quest/CommunityGoalProgressMessageParser.ts create mode 100644 packages/communication/src/messages/parser/quest/ConcurrentUsersGoalProgressMessageParser.ts create mode 100644 packages/communication/src/messages/parser/quest/EpicPopupMessageParser.ts create mode 100644 packages/communication/src/messages/parser/quest/HallOfFameEntryData.ts create mode 100644 packages/communication/src/messages/parser/quest/ILandingPageUserEntry.ts create mode 100644 packages/communication/src/messages/parser/quest/PrizeData.ts create mode 100644 packages/communication/src/messages/parser/quest/QuestCancelledMessageParser.ts create mode 100644 packages/communication/src/messages/parser/quest/QuestCompletedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/quest/QuestDailyMessageParser.ts create mode 100644 packages/communication/src/messages/parser/quest/QuestMessageData.ts create mode 100644 packages/communication/src/messages/parser/quest/QuestMessageParser.ts create mode 100644 packages/communication/src/messages/parser/quest/QuestsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/quest/SeasonalQuestsParser.ts create mode 100644 packages/communication/src/messages/parser/quest/index.ts create mode 100644 packages/communication/src/messages/parser/recycler/RecyclerFinishedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/recycler/RecyclerStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/recycler/index.ts create mode 100644 packages/communication/src/messages/parser/room/access/CantConnectMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/access/RoomEnterParser.ts create mode 100644 packages/communication/src/messages/parser/room/access/RoomFowardParser.ts create mode 100644 packages/communication/src/messages/parser/room/access/doorbell/RoomDoorbellAcceptedParser.ts create mode 100644 packages/communication/src/messages/parser/room/access/doorbell/index.ts create mode 100644 packages/communication/src/messages/parser/room/access/index.ts create mode 100644 packages/communication/src/messages/parser/room/access/rights/RoomRightsClearParser.ts create mode 100644 packages/communication/src/messages/parser/room/access/rights/RoomRightsOwnerParser.ts create mode 100644 packages/communication/src/messages/parser/room/access/rights/RoomRightsParser.ts create mode 100644 packages/communication/src/messages/parser/room/access/rights/index.ts create mode 100644 packages/communication/src/messages/parser/room/bots/BotCommandConfigurationParser.ts create mode 100644 packages/communication/src/messages/parser/room/bots/BotForceOpenContextMenuParser.ts create mode 100644 packages/communication/src/messages/parser/room/bots/BotSkillData.ts create mode 100644 packages/communication/src/messages/parser/room/bots/BotSkillListUpdateParser.ts create mode 100644 packages/communication/src/messages/parser/room/bots/index.ts create mode 100644 packages/communication/src/messages/parser/room/data/RoomChatSettingsParser.ts create mode 100644 packages/communication/src/messages/parser/room/data/RoomDataParser.ts create mode 100644 packages/communication/src/messages/parser/room/data/RoomEntryInfoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/data/RoomScoreParser.ts create mode 100644 packages/communication/src/messages/parser/room/data/index.ts create mode 100644 packages/communication/src/messages/parser/room/engine/FavoriteMembershipUpdateMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/engine/ObjectData.ts create mode 100644 packages/communication/src/messages/parser/room/engine/ObjectsDataUpdateParser.ts create mode 100644 packages/communication/src/messages/parser/room/engine/ObjectsRollingParser.ts create mode 100644 packages/communication/src/messages/parser/room/engine/index.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/CustomUserNotificationMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/DiceValueMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/FurniRentOrBuyoutOfferMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/FurnitureAliasesParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/FurnitureDataParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/FurnitureStackHeightParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/GroupFurniContextMenuInfoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/ItemDataUpdateMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/LoveLockFurniFinishedParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/LoveLockFurniFriendConfirmedParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/LoveLockFurniStartParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/OneWayDoorStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/RentableSpaceRentFailedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/RentableSpaceRentOkMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/RentableSpaceStatusMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/RequestSpamWallPostItMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/RoomDimmerPresetsMessageData.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/RoomDimmerPresetsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/RoomMessageNotificationMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/WelcomeGiftStatusParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorAddParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorDataParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorRemoveParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorUpdateParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/floor/index.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/index.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallAddParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallDataParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallRemoveParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallUpdateParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/wall/index.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/youtube/YoutubeControlVideoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayPlaylist.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayPlaylistsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayVideoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/furniture/youtube/index.ts create mode 100644 packages/communication/src/messages/parser/room/index.ts create mode 100644 packages/communication/src/messages/parser/room/mapping/FloorHeightMapMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/mapping/RoomEntryTileMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/mapping/RoomHeightMapParser.ts create mode 100644 packages/communication/src/messages/parser/room/mapping/RoomHeightMapUpdateParser.ts create mode 100644 packages/communication/src/messages/parser/room/mapping/RoomOccupiedTilesMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/mapping/RoomPaintParser.ts create mode 100644 packages/communication/src/messages/parser/room/mapping/RoomReadyMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/mapping/RoomVisualizationSettingsParser.ts create mode 100644 packages/communication/src/messages/parser/room/mapping/index.ts create mode 100644 packages/communication/src/messages/parser/room/pet/PetBreedingResultParser.ts create mode 100644 packages/communication/src/messages/parser/room/pet/PetExperienceParser.ts create mode 100644 packages/communication/src/messages/parser/room/pet/PetFigureUpdateParser.ts create mode 100644 packages/communication/src/messages/parser/room/pet/PetInfoParser.ts create mode 100644 packages/communication/src/messages/parser/room/pet/PetStatusUpdateParser.ts create mode 100644 packages/communication/src/messages/parser/room/pet/index.ts create mode 100644 packages/communication/src/messages/parser/room/session/YouArePlayingGameParser.ts create mode 100644 packages/communication/src/messages/parser/room/session/YouAreSpectatorMessageParser.ts create mode 100644 packages/communication/src/messages/parser/room/session/index.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitDanceParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitEffectParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitExpressionParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitHandItemParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitHandItemReceivedParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitIdleParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitInfoParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitNumberParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitRemoveParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitStatusAction.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitStatusMessage.ts create mode 100644 packages/communication/src/messages/parser/room/unit/RoomUnitStatusParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/UserMessageData.ts create mode 100644 packages/communication/src/messages/parser/room/unit/chat/FloodControlParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/chat/RemainingMuteParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/chat/RoomUnitChatParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/chat/RoomUnitTypingParser.ts create mode 100644 packages/communication/src/messages/parser/room/unit/chat/index.ts create mode 100644 packages/communication/src/messages/parser/room/unit/index.ts create mode 100644 packages/communication/src/messages/parser/roomevents/ConditionDefinition.ts create mode 100644 packages/communication/src/messages/parser/roomevents/TriggerDefinition.ts create mode 100644 packages/communication/src/messages/parser/roomevents/Triggerable.ts create mode 100644 packages/communication/src/messages/parser/roomevents/WiredActionDefinition.ts create mode 100644 packages/communication/src/messages/parser/roomevents/WiredFurniActionParser.ts create mode 100644 packages/communication/src/messages/parser/roomevents/WiredFurniConditionParser.ts create mode 100644 packages/communication/src/messages/parser/roomevents/WiredFurniTriggerParser.ts create mode 100644 packages/communication/src/messages/parser/roomevents/WiredOpenParser.ts create mode 100644 packages/communication/src/messages/parser/roomevents/WiredRewardResultMessageParser.ts create mode 100644 packages/communication/src/messages/parser/roomevents/WiredSaveSuccessParser.ts create mode 100644 packages/communication/src/messages/parser/roomevents/WiredValidationErrorParser.ts create mode 100644 packages/communication/src/messages/parser/roomevents/index.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/BannedUserData.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/BannedUsersFromRoomParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/FlatControllerAddedParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/FlatControllerData.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/FlatControllerRemovedParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/FlatControllersParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/IFlatUser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/MuteAllInRoomParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/NoSuchFlatParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/RoomChatSettings.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/RoomModerationSettings.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/RoomSettingsData.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/RoomSettingsDataParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/RoomSettingsErrorParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/RoomSettingsSaveErrorParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/RoomSettingsSavedParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/ShowEnforceRoomCategoryDialogParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/UserUnbannedFromRoomParser.ts create mode 100644 packages/communication/src/messages/parser/roomsettings/index.ts create mode 100644 packages/communication/src/messages/parser/security/AuthenticatedParser.ts create mode 100644 packages/communication/src/messages/parser/security/index.ts create mode 100644 packages/communication/src/messages/parser/sound/JukeboxPlayListFullMessageParser.ts create mode 100644 packages/communication/src/messages/parser/sound/JukeboxSongDisksMessageParser.ts create mode 100644 packages/communication/src/messages/parser/sound/NowPlayingMessageParser.ts create mode 100644 packages/communication/src/messages/parser/sound/OfficialSongIdMessageParser.ts create mode 100644 packages/communication/src/messages/parser/sound/PlayListEntry.ts create mode 100644 packages/communication/src/messages/parser/sound/PlayListMessageParser.ts create mode 100644 packages/communication/src/messages/parser/sound/PlayListSongAddedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/sound/SongInfoEntry.ts create mode 100644 packages/communication/src/messages/parser/sound/TraxSongInfoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/sound/UserSongDisksInventoryMessageParser.ts create mode 100644 packages/communication/src/messages/parser/sound/index.ts create mode 100644 packages/communication/src/messages/parser/talent/TalentLevelUpMessageParser.ts create mode 100644 packages/communication/src/messages/parser/talent/TalentTrackLevel.ts create mode 100644 packages/communication/src/messages/parser/talent/TalentTrackLevelMessageParser.ts create mode 100644 packages/communication/src/messages/parser/talent/TalentTrackParser.ts create mode 100644 packages/communication/src/messages/parser/talent/TalentTrackRewardPerk.ts create mode 100644 packages/communication/src/messages/parser/talent/TalentTrackRewardProduct.ts create mode 100644 packages/communication/src/messages/parser/talent/TalentTrackTask.ts create mode 100644 packages/communication/src/messages/parser/talent/index.ts create mode 100644 packages/communication/src/messages/parser/user/AccountSafetyLockStatusChangeParser.ts create mode 100644 packages/communication/src/messages/parser/user/ApproveNameResultParser.ts create mode 100644 packages/communication/src/messages/parser/user/ChangeEmailResultParser.ts create mode 100644 packages/communication/src/messages/parser/user/EmailStatusParser.ts create mode 100644 packages/communication/src/messages/parser/user/ExtendedProfileChangedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/GroupDetailsChangedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/GroupMembershipRequestedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/GuildEditFailedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/GuildMemberMgmtFailedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/GuildMembershipsMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/HabboGroupBadgesMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/HabboGroupEntryData.ts create mode 100644 packages/communication/src/messages/parser/user/HabboGroupJoinFailedMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/IgnoreResultParser.ts create mode 100644 packages/communication/src/messages/parser/user/IgnoredUsersParser.ts create mode 100644 packages/communication/src/messages/parser/user/InClientLinkParser.ts create mode 100644 packages/communication/src/messages/parser/user/PetRespectNotificationParser.ts create mode 100644 packages/communication/src/messages/parser/user/PetSupplementTypeEnum.ts create mode 100644 packages/communication/src/messages/parser/user/PetSupplementedNotificationParser.ts create mode 100644 packages/communication/src/messages/parser/user/RespectReceivedParser.ts create mode 100644 packages/communication/src/messages/parser/user/RoomEntryData.ts create mode 100644 packages/communication/src/messages/parser/user/ScrKickbackData.ts create mode 100644 packages/communication/src/messages/parser/user/ScrSendKickbackInfoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/WelcomeGiftChangeEmailResultParser.ts create mode 100644 packages/communication/src/messages/parser/user/access/UserPermissionsParser.ts create mode 100644 packages/communication/src/messages/parser/user/access/index.ts create mode 100644 packages/communication/src/messages/parser/user/data/RelationshipStatusInfo.ts create mode 100644 packages/communication/src/messages/parser/user/data/RelationshipStatusInfoMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/data/UserCurrentBadgesParser.ts create mode 100644 packages/communication/src/messages/parser/user/data/UserFigureParser.ts create mode 100644 packages/communication/src/messages/parser/user/data/UserInfoDataParser.ts create mode 100644 packages/communication/src/messages/parser/user/data/UserInfoParser.ts create mode 100644 packages/communication/src/messages/parser/user/data/UserNameChangeMessageParser.ts create mode 100644 packages/communication/src/messages/parser/user/data/UserProfileParser.ts create mode 100644 packages/communication/src/messages/parser/user/data/UserSettingsParser.ts create mode 100644 packages/communication/src/messages/parser/user/data/UserTagsParser.ts create mode 100644 packages/communication/src/messages/parser/user/data/index.ts create mode 100644 packages/communication/src/messages/parser/user/index.ts create mode 100644 packages/communication/src/messages/parser/user/inventory/currency/UserCreditsParser.ts create mode 100644 packages/communication/src/messages/parser/user/inventory/currency/UserCurrencyParser.ts create mode 100644 packages/communication/src/messages/parser/user/inventory/currency/index.ts create mode 100644 packages/communication/src/messages/parser/user/inventory/index.ts create mode 100644 packages/communication/src/messages/parser/user/inventory/subscription/UserSubscriptionParser.ts create mode 100644 packages/communication/src/messages/parser/user/inventory/subscription/index.ts create mode 100644 packages/communication/src/messages/parser/user/wardrobe/UserWardrobePageParser.ts create mode 100644 packages/communication/src/messages/parser/user/wardrobe/index.ts create mode 100644 packages/communication/src/messages/parser/userclassification/UserClassificationMessageParser.ts create mode 100644 packages/communication/src/messages/parser/userclassification/index.ts create mode 100644 packages/communication/tsconfig.json create mode 100644 packages/configuration/.eslintrc.json create mode 100644 packages/configuration/.gitignore create mode 100644 packages/configuration/index.ts create mode 100644 packages/configuration/package.json create mode 100644 packages/configuration/src/ConfigurationManager.ts create mode 100644 packages/configuration/src/GetConfiguration.ts create mode 100644 packages/configuration/src/IConfigurationManager.ts create mode 100644 packages/configuration/src/index.ts create mode 100644 packages/configuration/tsconfig.json create mode 100644 packages/eslint-config/.eslintrc.json create mode 100644 packages/eslint-config/.gitignore create mode 100644 packages/eslint-config/index.js create mode 100644 packages/eslint-config/package.json create mode 100644 packages/events/.eslintrc.json create mode 100644 packages/events/.gitignore create mode 100644 packages/events/index.ts create mode 100644 packages/events/package.json create mode 100644 packages/events/src/EventDispatcher.ts create mode 100644 packages/events/src/GetEventDispatcher.ts create mode 100644 packages/events/src/NitroEventType.ts create mode 100644 packages/events/src/NitroSettingsEvent.ts create mode 100644 packages/events/src/NitroSoundEvent.ts create mode 100644 packages/events/src/NitroToolbarAnimateIconEvent.ts create mode 100644 packages/events/src/NitroToolbarEvent.ts create mode 100644 packages/events/src/avatar/AvatarRenderEffectLibraryEvent.ts create mode 100644 packages/events/src/avatar/AvatarRenderLibraryEvent.ts create mode 100644 packages/events/src/avatar/index.ts create mode 100644 packages/events/src/camera/RoomCameraWidgetManagerEvent.ts create mode 100644 packages/events/src/camera/index.ts create mode 100644 packages/events/src/communication/NitroCommunicationDemoEvent.ts create mode 100644 packages/events/src/communication/index.ts create mode 100644 packages/events/src/core/ConfigurationEvent.ts create mode 100644 packages/events/src/core/MessageEvent.ts create mode 100644 packages/events/src/core/NitroEvent.ts create mode 100644 packages/events/src/core/SocketConnectionEvent.ts create mode 100644 packages/events/src/core/index.ts create mode 100644 packages/events/src/index.ts create mode 100644 packages/events/src/room/RoomBackgroundColorEvent.ts create mode 100644 packages/events/src/room/RoomContentLoadedEvent.ts create mode 100644 packages/events/src/room/RoomDragEvent.ts create mode 100644 packages/events/src/room/RoomEngineDimmerStateEvent.ts create mode 100644 packages/events/src/room/RoomEngineEvent.ts create mode 100644 packages/events/src/room/RoomEngineObjectEvent.ts create mode 100644 packages/events/src/room/RoomEngineObjectPlacedEvent.ts create mode 100644 packages/events/src/room/RoomEngineObjectPlacedOnUserEvent.ts create mode 100644 packages/events/src/room/RoomEngineObjectPlaySoundEvent.ts create mode 100644 packages/events/src/room/RoomEngineRoomAdEvent.ts create mode 100644 packages/events/src/room/RoomEngineSamplePlaybackEvent.ts create mode 100644 packages/events/src/room/RoomEngineTriggerWidgetEvent.ts create mode 100644 packages/events/src/room/RoomEngineUseProductEvent.ts create mode 100644 packages/events/src/room/RoomObjectBadgeAssetEvent.ts create mode 100644 packages/events/src/room/RoomObjectDataRequestEvent.ts create mode 100644 packages/events/src/room/RoomObjectDimmerStateUpdateEvent.ts create mode 100644 packages/events/src/room/RoomObjectEvent.ts create mode 100644 packages/events/src/room/RoomObjectFloorHoleEvent.ts create mode 100644 packages/events/src/room/RoomObjectFurnitureActionEvent.ts create mode 100644 packages/events/src/room/RoomObjectHSLColorEnableEvent.ts create mode 100644 packages/events/src/room/RoomObjectHSLColorEnabledEvent.ts create mode 100644 packages/events/src/room/RoomObjectMouseEvent.ts create mode 100644 packages/events/src/room/RoomObjectMoveEvent.ts create mode 100644 packages/events/src/room/RoomObjectPlaySoundIdEvent.ts create mode 100644 packages/events/src/room/RoomObjectRoomAdEvent.ts create mode 100644 packages/events/src/room/RoomObjectSamplePlaybackEvent.ts create mode 100644 packages/events/src/room/RoomObjectSoundMachineEvent.ts create mode 100644 packages/events/src/room/RoomObjectStateChangedEvent.ts create mode 100644 packages/events/src/room/RoomObjectTileMouseEvent.ts create mode 100644 packages/events/src/room/RoomObjectWallMouseEvent.ts create mode 100644 packages/events/src/room/RoomObjectWidgetRequestEvent.ts create mode 100644 packages/events/src/room/RoomSpriteMouseEvent.ts create mode 100644 packages/events/src/room/RoomToObjectEvent.ts create mode 100644 packages/events/src/room/RoomToObjectOwnAvatarMoveEvent.ts create mode 100644 packages/events/src/room/RoomZoomEvent.ts create mode 100644 packages/events/src/room/index.ts create mode 100644 packages/events/src/session/BadgeImageReadyEvent.ts create mode 100644 packages/events/src/session/MysteryBoxKeysUpdateEvent.ts create mode 100644 packages/events/src/session/PerksUpdatedEvent.ts create mode 100644 packages/events/src/session/RoomSessionChatEvent.ts create mode 100644 packages/events/src/session/RoomSessionConfirmPetBreedingEvent.ts create mode 100644 packages/events/src/session/RoomSessionConfirmPetBreedingResultEvent.ts create mode 100644 packages/events/src/session/RoomSessionDanceEvent.ts create mode 100644 packages/events/src/session/RoomSessionDimmerPresetsEvent.ts create mode 100644 packages/events/src/session/RoomSessionDimmerPresetsEventPresetItem.ts create mode 100644 packages/events/src/session/RoomSessionDoorbellEvent.ts create mode 100644 packages/events/src/session/RoomSessionErrorMessageEvent.ts create mode 100644 packages/events/src/session/RoomSessionEvent.ts create mode 100644 packages/events/src/session/RoomSessionFavoriteGroupUpdateEvent.ts create mode 100644 packages/events/src/session/RoomSessionFriendRequestEvent.ts create mode 100644 packages/events/src/session/RoomSessionNestBreedingSuccessEvent.ts create mode 100644 packages/events/src/session/RoomSessionPetBreedingEvent.ts create mode 100644 packages/events/src/session/RoomSessionPetBreedingResultEvent.ts create mode 100644 packages/events/src/session/RoomSessionPetCommandsUpdateEvent.ts create mode 100644 packages/events/src/session/RoomSessionPetFigureUpdateEvent.ts create mode 100644 packages/events/src/session/RoomSessionPetInfoUpdateEvent.ts create mode 100644 packages/events/src/session/RoomSessionPetLevelUpdateEvent.ts create mode 100644 packages/events/src/session/RoomSessionPetPackageEvent.ts create mode 100644 packages/events/src/session/RoomSessionPetStatusUpdateEvent.ts create mode 100644 packages/events/src/session/RoomSessionPollEvent.ts create mode 100644 packages/events/src/session/RoomSessionPresentEvent.ts create mode 100644 packages/events/src/session/RoomSessionPropertyUpdateEvent.ts create mode 100644 packages/events/src/session/RoomSessionQueueEvent.ts create mode 100644 packages/events/src/session/RoomSessionSpectatorModeEvent.ts create mode 100644 packages/events/src/session/RoomSessionUserBadgesEvent.ts create mode 100644 packages/events/src/session/RoomSessionUserDataUpdateEvent.ts create mode 100644 packages/events/src/session/RoomSessionUserFigureUpdateEvent.ts create mode 100644 packages/events/src/session/RoomSessionUserTagsEvent.ts create mode 100644 packages/events/src/session/RoomSessionVoteEvent.ts create mode 100644 packages/events/src/session/RoomSessionWordQuizEvent.ts create mode 100644 packages/events/src/session/SessionDataPreferencesEvent.ts create mode 100644 packages/events/src/session/UserNameUpdateEvent.ts create mode 100644 packages/events/src/session/index.ts create mode 100644 packages/events/src/sound/NotifyPlayedSongEvent.ts create mode 100644 packages/events/src/sound/NowPlayingEvent.ts create mode 100644 packages/events/src/sound/PlayListStatusEvent.ts create mode 100644 packages/events/src/sound/SongDiskInventoryReceivedEvent.ts create mode 100644 packages/events/src/sound/SongInfoReceivedEvent.ts create mode 100644 packages/events/src/sound/SoundManagerEvent.ts create mode 100644 packages/events/src/sound/index.ts create mode 100644 packages/events/tsconfig.json create mode 100644 packages/localization/.eslintrc.json create mode 100644 packages/localization/.gitignore create mode 100644 packages/localization/index.ts create mode 100644 packages/localization/package.json create mode 100644 packages/localization/src/BadgeBaseAndLevel.ts create mode 100644 packages/localization/src/GetLocalization.ts create mode 100644 packages/localization/src/LocalizationManager.ts create mode 100644 packages/localization/src/index.ts create mode 100644 packages/localization/tsconfig.json create mode 100644 packages/room/.eslintrc.json create mode 100644 packages/room/.gitignore create mode 100644 packages/room/index.ts create mode 100644 packages/room/package.json create mode 100644 packages/room/src/GetRoomContentLoader.ts create mode 100644 packages/room/src/GetRoomEngine.ts create mode 100644 packages/room/src/GetRoomManager.ts create mode 100644 packages/room/src/GetRoomMessageHandler.ts create mode 100644 packages/room/src/GetRoomObjectLogicFactory.ts create mode 100644 packages/room/src/GetRoomObjectVisualizationFactory.ts create mode 100644 packages/room/src/ImageResult.ts create mode 100644 packages/room/src/PetColorResult.ts create mode 100644 packages/room/src/RoomContentLoader.ts create mode 100644 packages/room/src/RoomEngine.ts create mode 100644 packages/room/src/RoomInstance.ts create mode 100644 packages/room/src/RoomManager.ts create mode 100644 packages/room/src/RoomMessageHandler.ts create mode 100644 packages/room/src/RoomObjectEventHandler.ts create mode 100644 packages/room/src/RoomObjectLogicFactory.ts create mode 100644 packages/room/src/RoomObjectManager.ts create mode 100644 packages/room/src/RoomObjectVisualizationFactory.ts create mode 100644 packages/room/src/RoomPreviewer.ts create mode 100644 packages/room/src/RoomVariableEnum.ts create mode 100644 packages/room/src/index.ts create mode 100644 packages/room/src/messages/ObjectAdUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarCarryObjectUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarChatUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarDanceUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarEffectUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarExperienceUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarExpressionUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarFigureUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarFlatControlUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarGestureUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarGuideStatusUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarMutedUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarOwnMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarPetGestureUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarPlayerValueUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarPlayingGameUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarPostureUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarSelectedMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarSignUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarSleepUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarTypingUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectAvatarUseObjectUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectDataUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectGroupBadgeUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectHeightUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectItemDataUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectModelDataUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectMoveUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectRoomColorUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectRoomFloorHoleUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectRoomMapUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectRoomMaskUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectRoomPlanePropertyUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectRoomPlaneVisibilityUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectRoomUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectSelectedMessage.ts create mode 100644 packages/room/src/messages/ObjectStateUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectTileCursorUpdateMessage.ts create mode 100644 packages/room/src/messages/ObjectVisibilityUpdateMessage.ts create mode 100644 packages/room/src/messages/RoomObjectUpdateMessage.ts create mode 100644 packages/room/src/messages/index.ts create mode 100644 packages/room/src/object/RoomFloorHole.ts create mode 100644 packages/room/src/object/RoomMapData.ts create mode 100644 packages/room/src/object/RoomMapMaskData.ts create mode 100644 packages/room/src/object/RoomObject.ts create mode 100644 packages/room/src/object/RoomObjectModel.ts create mode 100644 packages/room/src/object/RoomPlaneBitmapMaskData.ts create mode 100644 packages/room/src/object/RoomPlaneBitmapMaskParser.ts create mode 100644 packages/room/src/object/RoomPlaneData.ts create mode 100644 packages/room/src/object/RoomPlaneMaskData.ts create mode 100644 packages/room/src/object/RoomPlaneParser.ts create mode 100644 packages/room/src/object/RoomWallData.ts create mode 100644 packages/room/src/object/index.ts create mode 100644 packages/room/src/object/logic/AvatarLogic.ts create mode 100644 packages/room/src/object/logic/MovingObjectLogic.ts create mode 100644 packages/room/src/object/logic/PetLogic.ts create mode 100644 packages/room/src/object/logic/RoomLogic.ts create mode 100644 packages/room/src/object/logic/RoomObjectLogicBase.ts create mode 100644 packages/room/src/object/logic/SelectionArrowLogic.ts create mode 100644 packages/room/src/object/logic/TileCursorLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureAchievementResolutionLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureBadgeDisplayLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureChangeStateWhenStepOnLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureClothingChangeLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureCounterClockLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureCrackableLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureCraftingGizmoLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureCreditLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureCuckooClockLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureCustomStackHeightLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureDiceLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureEcotronBoxLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureEditableInternalLinkLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureEditableRoomLinkLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureEffectBoxLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureExternalImageLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureFireworksLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureFloorHoleLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureFriendFurniLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureGroupForumTerminalLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureGuildCustomizedLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureHabboWheelLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureHighScoreLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureHockeyScoreLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureHweenLovelockLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureIceStormLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureInternalLinkLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureJukeboxLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureLoveLockLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureMannequinLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureMonsterplantSeedLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureMultiHeightLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureMultiStateLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureMysteryBoxLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureMysteryTrophyLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureOneWayDoorLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurniturePetCustomizationLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurniturePlaceholderLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurniturePlanetSystemLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurniturePresentLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurniturePurchaseableClothingLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurniturePushableLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureRandomStateLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureRandomTeleportLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureRentableSpaceLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureRoomBackgroundColorLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureRoomBackgroundLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureRoomBillboardLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureRoomBrandingLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureRoomDimmerLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureScoreLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureSongDiskLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureSoundBlockLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureSoundMachineLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureStickieLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureTrophyLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureVoteCounterLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureVoteMajorityLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureWelcomeGiftLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureWindowLogic.ts create mode 100644 packages/room/src/object/logic/furniture/FurnitureYoutubeLogic.ts create mode 100644 packages/room/src/object/logic/furniture/index.ts create mode 100644 packages/room/src/object/logic/index.ts create mode 100644 packages/room/src/object/visualization/RoomObjectSprite.ts create mode 100644 packages/room/src/object/visualization/RoomObjectSpriteVisualization.ts create mode 100644 packages/room/src/object/visualization/avatar/AvatarVisualization.ts create mode 100644 packages/room/src/object/visualization/avatar/AvatarVisualizationData.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/ExpressionAddition.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/ExpressionAdditionFactory.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/FloatingHeartAddition.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/FloatingIdleZAddition.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/GameClickTargetAddition.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/GuideStatusBubbleAddition.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/IAvatarAddition.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/IExpressionAddition.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/MutedBubbleAddition.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/NumberBubbleAddition.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/TypingBubbleAddition.ts create mode 100644 packages/room/src/object/visualization/avatar/additions/index.ts create mode 100644 packages/room/src/object/visualization/avatar/index.ts create mode 100644 packages/room/src/object/visualization/data/AnimationData.ts create mode 100644 packages/room/src/object/visualization/data/AnimationFrame.ts create mode 100644 packages/room/src/object/visualization/data/AnimationFrameData.ts create mode 100644 packages/room/src/object/visualization/data/AnimationFrameDirectionalData.ts create mode 100644 packages/room/src/object/visualization/data/AnimationFrameSequenceData.ts create mode 100644 packages/room/src/object/visualization/data/AnimationLayerData.ts create mode 100644 packages/room/src/object/visualization/data/AnimationSizeData.ts create mode 100644 packages/room/src/object/visualization/data/AnimationStateData.ts create mode 100644 packages/room/src/object/visualization/data/ColorData.ts create mode 100644 packages/room/src/object/visualization/data/DirectionData.ts create mode 100644 packages/room/src/object/visualization/data/DirectionalOffsetData.ts create mode 100644 packages/room/src/object/visualization/data/LayerData.ts create mode 100644 packages/room/src/object/visualization/data/ParticleSystemParticle.ts create mode 100644 packages/room/src/object/visualization/data/PetSizeData.ts create mode 100644 packages/room/src/object/visualization/data/SizeData.ts create mode 100644 packages/room/src/object/visualization/data/index.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureAnimatedVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureAnimatedVisualizationData.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureBBVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureBottleVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureBrandedImageVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureBuilderPlaceholderVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureCounterClockVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureCuboidVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureExternalImageVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureFireworksVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureGiftWrappedFireworksVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureGiftWrappedVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureGuildCustomizedVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureGuildIsometricBadgeVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureHabboWheelVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureIsometricBBVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureMannequinVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureMannequinVisualizationData.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureParticleSystem.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureParticleSystemEmitter.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureParticleSystemParticle.ts create mode 100644 packages/room/src/object/visualization/furniture/FurniturePartyBeamerVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurniturePlanetSystemVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurniturePlanetSystemVisualizationPlanetObject.ts create mode 100644 packages/room/src/object/visualization/furniture/FurniturePosterVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureQueueTileVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureResettingAnimatedVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureRoomBackgroundVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureScoreBoardVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureSoundBlockVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureStickieVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureValRandomizerVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureVisualizationData.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureVoteCounterVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureVoteMajorityVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureWaterAreaVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/FurnitureYoutubeVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts create mode 100644 packages/room/src/object/visualization/furniture/index.ts create mode 100644 packages/room/src/object/visualization/index.ts create mode 100644 packages/room/src/object/visualization/pet/ExperienceData.ts create mode 100644 packages/room/src/object/visualization/pet/PetVisualization.ts create mode 100644 packages/room/src/object/visualization/pet/PetVisualizationData.ts create mode 100644 packages/room/src/object/visualization/pet/index.ts create mode 100644 packages/room/src/object/visualization/room/PlaneDrawingData.ts create mode 100644 packages/room/src/object/visualization/room/RoomPlane.ts create mode 100644 packages/room/src/object/visualization/room/RoomPlaneBitmapMask.ts create mode 100644 packages/room/src/object/visualization/room/RoomPlaneRectangleMask.ts create mode 100644 packages/room/src/object/visualization/room/RoomVisualization.ts create mode 100644 packages/room/src/object/visualization/room/RoomVisualizationData.ts create mode 100644 packages/room/src/object/visualization/room/TileCursorVisualization.ts create mode 100644 packages/room/src/object/visualization/room/index.ts create mode 100644 packages/room/src/object/visualization/room/mask/PlaneMask.ts create mode 100644 packages/room/src/object/visualization/room/mask/PlaneMaskBitmap.ts create mode 100644 packages/room/src/object/visualization/room/mask/PlaneMaskManager.ts create mode 100644 packages/room/src/object/visualization/room/mask/PlaneMaskVisualization.ts create mode 100644 packages/room/src/object/visualization/room/mask/index.ts create mode 100644 packages/room/src/object/visualization/room/utils/PlaneBitmapData.ts create mode 100644 packages/room/src/object/visualization/room/utils/Randomizer.ts create mode 100644 packages/room/src/object/visualization/room/utils/index.ts create mode 100644 packages/room/src/renderer/RoomRenderer.ts create mode 100644 packages/room/src/renderer/RoomSpriteCanvas.ts create mode 100644 packages/room/src/renderer/cache/RoomObjectCache.ts create mode 100644 packages/room/src/renderer/cache/RoomObjectCacheItem.ts create mode 100644 packages/room/src/renderer/cache/RoomObjectLocationCacheItem.ts create mode 100644 packages/room/src/renderer/cache/RoomObjectSortableSpriteCacheItem.ts create mode 100644 packages/room/src/renderer/cache/index.ts create mode 100644 packages/room/src/renderer/index.ts create mode 100644 packages/room/src/renderer/utils/ExtendedSprite.ts create mode 100644 packages/room/src/renderer/utils/ObjectMouseData.ts create mode 100644 packages/room/src/renderer/utils/SortableSprite.ts create mode 100644 packages/room/src/renderer/utils/index.ts create mode 100644 packages/room/src/utils/FurnitureStackingHeightMap.ts create mode 100644 packages/room/src/utils/LegacyWallGeometry.ts create mode 100644 packages/room/src/utils/RoomCamera.ts create mode 100644 packages/room/src/utils/RoomData.ts create mode 100644 packages/room/src/utils/RoomEnterEffect.ts create mode 100644 packages/room/src/utils/RoomFurnitureData.ts create mode 100644 packages/room/src/utils/RoomGeometry.ts create mode 100644 packages/room/src/utils/RoomInstanceData.ts create mode 100644 packages/room/src/utils/RoomObjectBadgeImageAssetListener.ts create mode 100644 packages/room/src/utils/RoomRotatingEffect.ts create mode 100644 packages/room/src/utils/RoomShakingEffect.ts create mode 100644 packages/room/src/utils/SelectedRoomObjectData.ts create mode 100644 packages/room/src/utils/SpriteDataCollector.ts create mode 100644 packages/room/src/utils/TileObjectMap.ts create mode 100644 packages/room/src/utils/index.ts create mode 100644 packages/room/tsconfig.json create mode 100644 packages/session/.eslintrc.json create mode 100644 packages/session/.gitignore create mode 100644 packages/session/index.ts create mode 100644 packages/session/package.json create mode 100644 packages/session/src/GetRoomSessionManager.ts create mode 100644 packages/session/src/GetSessionDataManager.ts create mode 100644 packages/session/src/GroupInformationManager.ts create mode 100644 packages/session/src/HabboClubLevelEnum.ts create mode 100644 packages/session/src/IgnoredUsersManager.ts create mode 100644 packages/session/src/RoomPetData.ts create mode 100644 packages/session/src/RoomSession.ts create mode 100644 packages/session/src/RoomSessionManager.ts create mode 100644 packages/session/src/RoomUserData.ts create mode 100644 packages/session/src/SessionDataManager.ts create mode 100644 packages/session/src/UserDataManager.ts create mode 100644 packages/session/src/badge/BadgeImageManager.ts create mode 100644 packages/session/src/badge/BadgeInfo.ts create mode 100644 packages/session/src/badge/GroupBadge.ts create mode 100644 packages/session/src/badge/GroupBadgePart.ts create mode 100644 packages/session/src/badge/index.ts create mode 100644 packages/session/src/furniture/FurnitureData.ts create mode 100644 packages/session/src/furniture/FurnitureDataLoader.ts create mode 100644 packages/session/src/furniture/index.ts create mode 100644 packages/session/src/handler/BaseHandler.ts create mode 100644 packages/session/src/handler/GenericErrorHandler.ts create mode 100644 packages/session/src/handler/PetPackageHandler.ts create mode 100644 packages/session/src/handler/PollHandler.ts create mode 100644 packages/session/src/handler/RoomChatHandler.ts create mode 100644 packages/session/src/handler/RoomDataHandler.ts create mode 100644 packages/session/src/handler/RoomDimmerPresetsHandler.ts create mode 100644 packages/session/src/handler/RoomPermissionsHandler.ts create mode 100644 packages/session/src/handler/RoomPresentHandler.ts create mode 100644 packages/session/src/handler/RoomSessionHandler.ts create mode 100644 packages/session/src/handler/RoomUsersHandler.ts create mode 100644 packages/session/src/handler/WordQuizHandler.ts create mode 100644 packages/session/src/handler/index.ts create mode 100644 packages/session/src/index.ts create mode 100644 packages/session/src/product/ProductData.ts create mode 100644 packages/session/src/product/ProductDataLoader.ts create mode 100644 packages/session/src/product/index.ts create mode 100644 packages/session/tsconfig.json create mode 100644 packages/sound/.eslintrc.json create mode 100644 packages/sound/.gitignore create mode 100644 packages/sound/index.ts create mode 100644 packages/sound/package.json create mode 100644 packages/sound/src/GetSoundManager.ts create mode 100644 packages/sound/src/SoundManager.ts create mode 100644 packages/sound/src/common/SongDataEntry.ts create mode 100644 packages/sound/src/common/SongStartRequestData.ts create mode 100644 packages/sound/src/common/index.ts create mode 100644 packages/sound/src/index.ts create mode 100644 packages/sound/src/music/JukeboxPlaylistController.ts create mode 100644 packages/sound/src/music/MusicController.ts create mode 100644 packages/sound/src/music/MusicPlayer.ts create mode 100644 packages/sound/src/music/MusicPriorities.ts create mode 100644 packages/sound/src/music/index.ts create mode 100644 packages/sound/src/trax/TraxChannel.ts create mode 100644 packages/sound/src/trax/TraxChannelItem.ts create mode 100644 packages/sound/src/trax/TraxData.ts create mode 100644 packages/sound/src/trax/index.ts create mode 100644 packages/sound/tsconfig.json create mode 100644 packages/utils/.eslintrc.json create mode 100644 packages/utils/.gitignore create mode 100644 packages/utils/index.ts create mode 100644 packages/utils/package.json create mode 100644 packages/utils/src/AdvancedMap.ts create mode 100644 packages/utils/src/ArrayBufferToBase64.ts create mode 100644 packages/utils/src/BinaryReader.ts create mode 100644 packages/utils/src/BinaryWriter.ts create mode 100644 packages/utils/src/ColorConverter.ts create mode 100644 packages/utils/src/FurniId.ts create mode 100644 packages/utils/src/GetPixi.ts create mode 100644 packages/utils/src/GetRenderer.ts create mode 100644 packages/utils/src/GetStage.ts create mode 100644 packages/utils/src/GetTexturePool.ts create mode 100644 packages/utils/src/GetTicker.ts create mode 100644 packages/utils/src/GetTickerFPS.ts create mode 100644 packages/utils/src/GetTickerTime.ts create mode 100644 packages/utils/src/HabboWebTools.ts create mode 100644 packages/utils/src/Int32.ts create mode 100644 packages/utils/src/LegacyExternalInterface.ts create mode 100644 packages/utils/src/LinkTracker.ts create mode 100644 packages/utils/src/Matrix4x4.ts create mode 100644 packages/utils/src/NitroBundle.ts create mode 100644 packages/utils/src/NitroConfig.ts create mode 100644 packages/utils/src/NitroLogger.ts create mode 100644 packages/utils/src/NitroVersion.ts create mode 100644 packages/utils/src/Node3D.ts create mode 100644 packages/utils/src/NumberBank.ts create mode 100644 packages/utils/src/PointMath.ts create mode 100644 packages/utils/src/RoomId.ts create mode 100644 packages/utils/src/TexturePool.ts create mode 100644 packages/utils/src/TextureUtils.ts create mode 100644 packages/utils/src/Vector3d.ts create mode 100644 packages/utils/src/filters/PaletteMapFilter.ts create mode 100644 packages/utils/src/filters/PlaneMaskFilter.ts create mode 100644 packages/utils/src/filters/WiredFilter.ts create mode 100644 packages/utils/src/filters/index.ts create mode 100644 packages/utils/src/index.ts create mode 100644 packages/utils/src/motion/Callback.ts create mode 100644 packages/utils/src/motion/Combo.ts create mode 100644 packages/utils/src/motion/Dispose.ts create mode 100644 packages/utils/src/motion/DropBounce.ts create mode 100644 packages/utils/src/motion/Ease.ts create mode 100644 packages/utils/src/motion/EaseOut.ts create mode 100644 packages/utils/src/motion/EaseRate.ts create mode 100644 packages/utils/src/motion/Interval.ts create mode 100644 packages/utils/src/motion/JumpBy.ts create mode 100644 packages/utils/src/motion/Motion.ts create mode 100644 packages/utils/src/motion/Motions.ts create mode 100644 packages/utils/src/motion/MoveBy.ts create mode 100644 packages/utils/src/motion/MoveTo.ts create mode 100644 packages/utils/src/motion/Queue.ts create mode 100644 packages/utils/src/motion/ResizeTo.ts create mode 100644 packages/utils/src/motion/Wait.ts create mode 100644 packages/utils/src/motion/index.ts create mode 100644 packages/utils/tsconfig.json delete mode 100644 public/android-chrome-192x192.png delete mode 100644 public/android-chrome-512x512.png delete mode 100644 public/apple-touch-icon.png delete mode 100644 public/browserconfig.xml delete mode 100644 public/favicon-16x16.png delete mode 100644 public/favicon-32x32.png delete mode 100644 public/favicon.ico delete mode 100644 public/mstile-150x150.png delete mode 100644 public/robots.txt delete mode 100644 public/safari-pinned-tab.svg delete mode 100644 public/site.webmanifest delete mode 100644 src/App.scss delete mode 100644 src/App.tsx create mode 100644 src/DevTools.ts delete mode 100644 src/api/GetRendererVersion.ts delete mode 100644 src/api/GetUIVersion.ts delete mode 100644 src/api/achievements/AchievementCategory.ts delete mode 100644 src/api/achievements/AchievementUtilities.ts delete mode 100644 src/api/achievements/IAchievementCategory.ts delete mode 100644 src/api/achievements/index.ts delete mode 100644 src/api/avatar/AvatarEditorAction.ts delete mode 100644 src/api/avatar/AvatarEditorGridColorItem.ts delete mode 100644 src/api/avatar/AvatarEditorGridPartItem.ts delete mode 100644 src/api/avatar/AvatarEditorThumbnailsHelper.ts delete mode 100644 src/api/avatar/AvatarEditorUtilities.ts delete mode 100644 src/api/avatar/BodyModel.ts delete mode 100644 src/api/avatar/CategoryBaseModel.ts delete mode 100644 src/api/avatar/CategoryData.ts delete mode 100644 src/api/avatar/FigureData.ts delete mode 100644 src/api/avatar/FigureGenerator.ts delete mode 100644 src/api/avatar/HeadModel.ts delete mode 100644 src/api/avatar/IAvatarEditorCategory.ts delete mode 100644 src/api/avatar/IAvatarEditorCategoryModel.ts delete mode 100644 src/api/avatar/IAvatarEditorCategoryPartItem.ts delete mode 100644 src/api/avatar/LegModel.ts delete mode 100644 src/api/avatar/TorsoModel.ts delete mode 100644 src/api/avatar/index.ts delete mode 100644 src/api/camera/CameraEditorTabs.ts delete mode 100644 src/api/camera/CameraPicture.ts delete mode 100644 src/api/camera/CameraPictureThumbnail.ts delete mode 100644 src/api/camera/index.ts delete mode 100644 src/api/campaign/CalendarItem.ts delete mode 100644 src/api/campaign/CalendarItemState.ts delete mode 100644 src/api/campaign/ICalendarItem.ts delete mode 100644 src/api/campaign/index.ts delete mode 100644 src/api/catalog/BuilderFurniPlaceableStatus.ts delete mode 100644 src/api/catalog/CatalogNode.ts delete mode 100644 src/api/catalog/CatalogPage.ts delete mode 100644 src/api/catalog/CatalogPageName.ts delete mode 100644 src/api/catalog/CatalogPetPalette.ts delete mode 100644 src/api/catalog/CatalogPurchaseState.ts delete mode 100644 src/api/catalog/CatalogType.ts delete mode 100644 src/api/catalog/CatalogUtilities.ts delete mode 100644 src/api/catalog/FurnitureOffer.ts delete mode 100644 src/api/catalog/GetImageIconUrlForProduct.ts delete mode 100644 src/api/catalog/GiftWrappingConfiguration.ts delete mode 100644 src/api/catalog/ICatalogNode.ts delete mode 100644 src/api/catalog/ICatalogOptions.ts delete mode 100644 src/api/catalog/ICatalogPage.ts delete mode 100644 src/api/catalog/IMarketplaceSearchOptions.ts delete mode 100644 src/api/catalog/IPageLocalization.ts delete mode 100644 src/api/catalog/IProduct.ts delete mode 100644 src/api/catalog/IPurchasableOffer.ts delete mode 100644 src/api/catalog/IPurchaseOptions.ts delete mode 100644 src/api/catalog/MarketplaceOfferState.ts delete mode 100644 src/api/catalog/MarketplaceSearchType.ts delete mode 100644 src/api/catalog/Offer.ts delete mode 100644 src/api/catalog/PageLocalization.ts delete mode 100644 src/api/catalog/PlacedObjectPurchaseData.ts delete mode 100644 src/api/catalog/Product.ts delete mode 100644 src/api/catalog/ProductTypeEnum.ts delete mode 100644 src/api/catalog/RequestedPage.ts delete mode 100644 src/api/catalog/SearchResult.ts delete mode 100644 src/api/catalog/index.ts delete mode 100644 src/api/chat-history/ChatEntryType.ts delete mode 100644 src/api/chat-history/ChatHistoryCurrentDate.ts delete mode 100644 src/api/chat-history/IChatEntry.ts delete mode 100644 src/api/chat-history/IRoomHistoryEntry.ts delete mode 100644 src/api/chat-history/MessengerHistoryCurrentDate.ts delete mode 100644 src/api/chat-history/index.ts delete mode 100644 src/api/events/DispatchEvent.ts delete mode 100644 src/api/events/DispatchMainEvent.ts delete mode 100644 src/api/events/DispatchUiEvent.ts delete mode 100644 src/api/events/UI_EVENT_DISPATCHER.ts delete mode 100644 src/api/events/index.ts delete mode 100644 src/api/friends/GetGroupChatData.ts delete mode 100644 src/api/friends/IGroupChatData.ts delete mode 100644 src/api/friends/MessengerFriend.ts delete mode 100644 src/api/friends/MessengerGroupType.ts delete mode 100644 src/api/friends/MessengerIconState.ts delete mode 100644 src/api/friends/MessengerRequest.ts delete mode 100644 src/api/friends/MessengerSettings.ts delete mode 100644 src/api/friends/MessengerThread.ts delete mode 100644 src/api/friends/MessengerThreadChat.ts delete mode 100644 src/api/friends/MessengerThreadChatGroup.ts delete mode 100644 src/api/friends/OpenMessengerChat.ts delete mode 100644 src/api/friends/index.ts delete mode 100644 src/api/groups/GetGroupInformation.ts delete mode 100644 src/api/groups/GetGroupManager.ts delete mode 100644 src/api/groups/GetGroupMembers.ts delete mode 100644 src/api/groups/GroupBadgePart.ts delete mode 100644 src/api/groups/GroupMembershipType.ts delete mode 100644 src/api/groups/GroupType.ts delete mode 100644 src/api/groups/IGroupCustomize.ts delete mode 100644 src/api/groups/IGroupData.ts delete mode 100644 src/api/groups/ToggleFavoriteGroup.ts delete mode 100644 src/api/groups/TryJoinGroup.ts delete mode 100644 src/api/groups/index.ts delete mode 100644 src/api/guide-tool/GuideSessionState.ts delete mode 100644 src/api/guide-tool/GuideToolMessage.ts delete mode 100644 src/api/guide-tool/GuideToolMessageGroup.ts delete mode 100644 src/api/guide-tool/index.ts delete mode 100644 src/api/hc-center/ClubStatus.ts delete mode 100644 src/api/hc-center/GetClubBadge.ts delete mode 100644 src/api/hc-center/index.ts delete mode 100644 src/api/help/CallForHelpResult.ts delete mode 100644 src/api/help/GetCloseReasonKey.ts delete mode 100644 src/api/help/IHelpReport.ts delete mode 100644 src/api/help/IReportedUser.ts delete mode 100644 src/api/help/ReportState.ts delete mode 100644 src/api/help/ReportType.ts delete mode 100644 src/api/help/index.ts delete mode 100644 src/api/index.ts delete mode 100644 src/api/inventory/FurniCategory.ts delete mode 100644 src/api/inventory/FurnitureItem.ts delete mode 100644 src/api/inventory/FurnitureUtilities.ts delete mode 100644 src/api/inventory/GroupItem.ts delete mode 100644 src/api/inventory/IBotItem.ts delete mode 100644 src/api/inventory/IFurnitureItem.ts delete mode 100644 src/api/inventory/IPetItem.ts delete mode 100644 src/api/inventory/IUnseenItemTracker.ts delete mode 100644 src/api/inventory/InventoryUtilities.ts delete mode 100644 src/api/inventory/PetUtilities.ts delete mode 100644 src/api/inventory/TradeState.ts delete mode 100644 src/api/inventory/TradeUserData.ts delete mode 100644 src/api/inventory/TradingNotificationType.ts delete mode 100644 src/api/inventory/TradingUtilities.ts delete mode 100644 src/api/inventory/UnseenItemCategory.ts delete mode 100644 src/api/inventory/index.ts delete mode 100644 src/api/mod-tools/GetIssueCategoryName.ts delete mode 100644 src/api/mod-tools/ISelectedUser.ts delete mode 100644 src/api/mod-tools/IUserInfo.ts delete mode 100644 src/api/mod-tools/ModActionDefinition.ts delete mode 100644 src/api/mod-tools/index.ts delete mode 100644 src/api/navigator/DoorStateType.ts delete mode 100644 src/api/navigator/INavigatorData.ts delete mode 100644 src/api/navigator/INavigatorSearchFilter.ts delete mode 100644 src/api/navigator/IRoomChatSettings.ts delete mode 100644 src/api/navigator/IRoomData.ts delete mode 100644 src/api/navigator/IRoomModel.ts delete mode 100644 src/api/navigator/IRoomModerationSettings.ts delete mode 100644 src/api/navigator/NavigatorSearchResultViewDisplayMode.ts delete mode 100644 src/api/navigator/RoomInfoData.ts delete mode 100644 src/api/navigator/RoomSettingsUtils.ts delete mode 100644 src/api/navigator/SearchFilterOptions.ts delete mode 100644 src/api/navigator/TryVisitRoom.ts delete mode 100644 src/api/navigator/index.ts delete mode 100644 src/api/nitro/GetConfigurationValue.ts delete mode 100644 src/api/nitro/OpenUrl.ts delete mode 100644 src/api/nitro/SendMessageComposer.ts delete mode 100644 src/api/nitro/index.ts delete mode 100644 src/api/nitro/room/DispatchMouseEvent.ts delete mode 100644 src/api/nitro/room/DispatchTouchEvent.ts delete mode 100644 src/api/nitro/room/GetOwnRoomObject.ts delete mode 100644 src/api/nitro/room/GetRoomObjectBounds.ts delete mode 100644 src/api/nitro/room/GetRoomObjectScreenLocation.ts delete mode 100644 src/api/nitro/room/InitializeRoomInstanceRenderingCanvas.ts delete mode 100644 src/api/nitro/room/IsFurnitureSelectionDisabled.ts delete mode 100644 src/api/nitro/room/ProcessRoomObjectOperation.ts delete mode 100644 src/api/nitro/room/SetActiveRoomId.ts delete mode 100644 src/api/nitro/room/index.ts delete mode 100644 src/api/nitro/session/CanManipulateFurniture.ts delete mode 100644 src/api/nitro/session/CreateRoomSession.ts delete mode 100644 src/api/nitro/session/GetCanStandUp.ts delete mode 100644 src/api/nitro/session/GetCanUseExpression.ts delete mode 100644 src/api/nitro/session/GetClubMemberLevel.ts delete mode 100644 src/api/nitro/session/GetFurnitureData.ts delete mode 100644 src/api/nitro/session/GetFurnitureDataForProductOffer.ts delete mode 100644 src/api/nitro/session/GetFurnitureDataForRoomObject.ts delete mode 100644 src/api/nitro/session/GetOwnPosture.ts delete mode 100644 src/api/nitro/session/GetProductDataForLocalization.ts delete mode 100644 src/api/nitro/session/GetRoomSession.ts delete mode 100644 src/api/nitro/session/GoToDesktop.ts delete mode 100644 src/api/nitro/session/HasHabboClub.ts delete mode 100644 src/api/nitro/session/HasHabboVip.ts delete mode 100644 src/api/nitro/session/IsOwnerOfFloorFurniture.ts delete mode 100644 src/api/nitro/session/IsOwnerOfFurniture.ts delete mode 100644 src/api/nitro/session/IsRidingHorse.ts delete mode 100644 src/api/nitro/session/StartRoomSession.ts delete mode 100644 src/api/nitro/session/VisitDesktop.ts delete mode 100644 src/api/nitro/session/index.ts delete mode 100644 src/api/notification/NotificationAlertItem.ts delete mode 100644 src/api/notification/NotificationAlertType.ts delete mode 100644 src/api/notification/NotificationBubbleItem.ts delete mode 100644 src/api/notification/NotificationBubbleType.ts delete mode 100644 src/api/notification/NotificationConfirmItem.ts delete mode 100644 src/api/notification/NotificationConfirmType.ts delete mode 100644 src/api/notification/index.ts delete mode 100644 src/api/purse/IPurse.ts delete mode 100644 src/api/purse/Purse.ts delete mode 100644 src/api/purse/index.ts delete mode 100644 src/api/room/events/RoomWidgetPollUpdateEvent.ts delete mode 100644 src/api/room/events/RoomWidgetUpdateBackgroundColorPreviewEvent.ts delete mode 100644 src/api/room/events/RoomWidgetUpdateChatInputContentEvent.ts delete mode 100644 src/api/room/events/RoomWidgetUpdateEvent.ts delete mode 100644 src/api/room/events/RoomWidgetUpdateRentableBotChatEvent.ts delete mode 100644 src/api/room/events/RoomWidgetUpdateRoomObjectEvent.ts delete mode 100644 src/api/room/events/index.ts delete mode 100644 src/api/room/index.ts delete mode 100644 src/api/room/widgets/AvatarInfoFurni.ts delete mode 100644 src/api/room/widgets/AvatarInfoName.ts delete mode 100644 src/api/room/widgets/AvatarInfoPet.ts delete mode 100644 src/api/room/widgets/AvatarInfoRentableBot.ts delete mode 100644 src/api/room/widgets/AvatarInfoUser.ts delete mode 100644 src/api/room/widgets/AvatarInfoUtilities.ts delete mode 100644 src/api/room/widgets/BotSkillsEnum.ts delete mode 100644 src/api/room/widgets/ChatBubbleMessage.ts delete mode 100644 src/api/room/widgets/ChatBubbleUtilities.ts delete mode 100644 src/api/room/widgets/ChatMessageTypeEnum.ts delete mode 100644 src/api/room/widgets/DimmerFurnitureWidgetPresetItem.ts delete mode 100644 src/api/room/widgets/DoChatsOverlap.ts delete mode 100644 src/api/room/widgets/FurnitureDimmerUtilities.ts delete mode 100644 src/api/room/widgets/GetDiskColor.ts delete mode 100644 src/api/room/widgets/IAvatarInfo.ts delete mode 100644 src/api/room/widgets/ICraftingIngredient.ts delete mode 100644 src/api/room/widgets/ICraftingRecipe.ts delete mode 100644 src/api/room/widgets/IPhotoData.ts delete mode 100644 src/api/room/widgets/MannequinUtilities.ts delete mode 100644 src/api/room/widgets/PetSupplementEnum.ts delete mode 100644 src/api/room/widgets/PostureTypeEnum.ts delete mode 100644 src/api/room/widgets/RoomDimmerPreset.ts delete mode 100644 src/api/room/widgets/RoomObjectItem.ts delete mode 100644 src/api/room/widgets/UseProductItem.ts delete mode 100644 src/api/room/widgets/VoteValue.ts delete mode 100644 src/api/room/widgets/YoutubeVideoPlaybackStateEnum.ts delete mode 100644 src/api/room/widgets/index.ts delete mode 100644 src/api/user/GetUserProfile.ts delete mode 100644 src/api/user/index.ts delete mode 100644 src/api/utils/CloneObject.ts delete mode 100644 src/api/utils/ColorUtils.ts delete mode 100644 src/api/utils/ConvertSeconds.ts delete mode 100644 src/api/utils/FixedSizeStack.ts delete mode 100644 src/api/utils/FriendlyTime.ts delete mode 100644 src/api/utils/GetLocalStorage.ts delete mode 100644 src/api/utils/LocalStorageKeys.ts delete mode 100644 src/api/utils/LocalizeBadgeDescription.ts delete mode 100644 src/api/utils/LocalizeBageName.ts delete mode 100644 src/api/utils/LocalizeFormattedNumber.ts delete mode 100644 src/api/utils/LocalizeShortNumber.ts delete mode 100644 src/api/utils/LocalizeText.ts delete mode 100644 src/api/utils/PlaySound.ts delete mode 100644 src/api/utils/ProductImageUtility.ts delete mode 100644 src/api/utils/Randomizer.ts delete mode 100644 src/api/utils/RoomChatFormatter.ts delete mode 100644 src/api/utils/SetLocalStorage.ts delete mode 100644 src/api/utils/SoundNames.ts delete mode 100644 src/api/utils/WindowSaveOptions.ts delete mode 100644 src/api/utils/index.ts delete mode 100644 src/api/wired/GetWiredTimeLocale.ts delete mode 100644 src/api/wired/WiredActionLayoutCode.ts delete mode 100644 src/api/wired/WiredConditionLayoutCode.ts delete mode 100644 src/api/wired/WiredDateToString.ts delete mode 100644 src/api/wired/WiredFurniType.ts delete mode 100644 src/api/wired/WiredSelectionVisualizer.ts delete mode 100644 src/api/wired/WiredStringDelimeter.ts delete mode 100644 src/api/wired/WiredTriggerLayoutCode.ts delete mode 100644 src/api/wired/index.ts delete mode 100644 src/assets/images/achievements/back-arrow.png delete mode 100644 src/assets/images/avatareditor/arrow-left-icon.png delete mode 100644 src/assets/images/avatareditor/arrow-right-icon.png delete mode 100644 src/assets/images/avatareditor/avatar-editor-spritesheet.png delete mode 100644 src/assets/images/avatareditor/ca-icon.png delete mode 100644 src/assets/images/avatareditor/ca-selected-icon.png delete mode 100644 src/assets/images/avatareditor/cc-icon.png delete mode 100644 src/assets/images/avatareditor/cc-selected-icon.png delete mode 100644 src/assets/images/avatareditor/ch-icon.png delete mode 100644 src/assets/images/avatareditor/ch-selected-icon.png delete mode 100644 src/assets/images/avatareditor/clear-icon.png delete mode 100644 src/assets/images/avatareditor/cp-icon.png delete mode 100644 src/assets/images/avatareditor/cp-selected-icon.png delete mode 100644 src/assets/images/avatareditor/ea-icon.png delete mode 100644 src/assets/images/avatareditor/ea-selected-icon.png delete mode 100644 src/assets/images/avatareditor/fa-icon.png delete mode 100644 src/assets/images/avatareditor/fa-selected-icon.png delete mode 100644 src/assets/images/avatareditor/female-icon.png delete mode 100644 src/assets/images/avatareditor/female-selected-icon.png delete mode 100644 src/assets/images/avatareditor/ha-icon.png delete mode 100644 src/assets/images/avatareditor/ha-selected-icon.png delete mode 100644 src/assets/images/avatareditor/he-icon.png delete mode 100644 src/assets/images/avatareditor/he-selected-icon.png delete mode 100644 src/assets/images/avatareditor/hr-icon.png delete mode 100644 src/assets/images/avatareditor/hr-selected-icon.png delete mode 100644 src/assets/images/avatareditor/lg-icon.png delete mode 100644 src/assets/images/avatareditor/lg-selected-icon.png delete mode 100644 src/assets/images/avatareditor/loading-icon.png delete mode 100644 src/assets/images/avatareditor/male-icon.png delete mode 100644 src/assets/images/avatareditor/male-selected-icon.png delete mode 100644 src/assets/images/avatareditor/sellable-icon.png delete mode 100644 src/assets/images/avatareditor/sh-icon.png delete mode 100644 src/assets/images/avatareditor/sh-selected-icon.png delete mode 100644 src/assets/images/avatareditor/spotlight-icon.png delete mode 100644 src/assets/images/avatareditor/wa-icon.png delete mode 100644 src/assets/images/avatareditor/wa-selected-icon.png delete mode 100644 src/assets/images/campaign/available.png delete mode 100644 src/assets/images/campaign/campaign_day_generic_bg.png delete mode 100644 src/assets/images/campaign/campaign_opened.png delete mode 100644 src/assets/images/campaign/campaign_spritesheet.png delete mode 100644 src/assets/images/campaign/locked.png delete mode 100644 src/assets/images/campaign/locked_bg.png delete mode 100644 src/assets/images/campaign/next.png delete mode 100644 src/assets/images/campaign/prev.png delete mode 100644 src/assets/images/campaign/unavailable.png delete mode 100644 src/assets/images/campaign/unlocked_bg.png delete mode 100644 src/assets/images/catalog/diamond_info_illustration.gif delete mode 100644 src/assets/images/catalog/hc_banner_big.png delete mode 100644 src/assets/images/catalog/hc_big.png delete mode 100644 src/assets/images/catalog/hc_small.png delete mode 100644 src/assets/images/catalog/paint-icon.png delete mode 100644 src/assets/images/catalog/target-price.png delete mode 100644 src/assets/images/catalog/vip.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_0.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_0_transparent.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_1.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_10.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_10_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_11.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_11_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_12.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_12_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_13.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_13_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_14.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_14_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_15.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_15_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_16.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_16_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_17.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_17_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_18.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_18_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_19.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_19_20_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_2.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_20.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_21.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_21_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_22.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_22_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_23.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_23_37_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_24.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_24_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_25.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_25_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_26.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_26_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_27.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_27_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_28.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_28_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_29.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_29_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_2_31_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_3.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_30.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_30_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_32.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_32_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_33_34.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_33_extra.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_34_extra.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_35.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_35_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_36.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_36_extra.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_36_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_37.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_38.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_38_extra.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_38_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_3_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_4.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_4_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_5.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_5_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_6.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_6_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_7.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_7_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_8.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_8_pointer.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_9.png delete mode 100644 src/assets/images/chat/chatbubbles/bubble_9_pointer.png delete mode 100644 src/assets/images/chat/styles-icon.png delete mode 100644 src/assets/images/floorplaneditor/door-direction-0.png delete mode 100644 src/assets/images/floorplaneditor/door-direction-1.png delete mode 100644 src/assets/images/floorplaneditor/door-direction-2.png delete mode 100644 src/assets/images/floorplaneditor/door-direction-3.png delete mode 100644 src/assets/images/floorplaneditor/door-direction-4.png delete mode 100644 src/assets/images/floorplaneditor/door-direction-5.png delete mode 100644 src/assets/images/floorplaneditor/door-direction-6.png delete mode 100644 src/assets/images/floorplaneditor/door-direction-7.png delete mode 100644 src/assets/images/floorplaneditor/icon-door.png delete mode 100644 src/assets/images/floorplaneditor/icon-tile-down.png delete mode 100644 src/assets/images/floorplaneditor/icon-tile-set.png delete mode 100644 src/assets/images/floorplaneditor/icon-tile-unset.png delete mode 100644 src/assets/images/floorplaneditor/icon-tile-up.png delete mode 100644 src/assets/images/floorplaneditor/preview_tile.png delete mode 100644 src/assets/images/floorplaneditor/selected_height_icon.png delete mode 100644 src/assets/images/friends/friends-spritesheet.png delete mode 100644 src/assets/images/friends/icon-accept.png delete mode 100644 src/assets/images/friends/icon-add.png delete mode 100644 src/assets/images/friends/icon-bobba.png delete mode 100644 src/assets/images/friends/icon-chat.png delete mode 100644 src/assets/images/friends/icon-deny.png delete mode 100644 src/assets/images/friends/icon-follow.png delete mode 100644 src/assets/images/friends/icon-friendbar-chat.png delete mode 100644 src/assets/images/friends/icon-friendbar-visit.png delete mode 100644 src/assets/images/friends/icon-heart.png delete mode 100644 src/assets/images/friends/icon-new-message.png delete mode 100644 src/assets/images/friends/icon-none.png delete mode 100644 src/assets/images/friends/icon-profile-sm-hover.png delete mode 100644 src/assets/images/friends/icon-profile-sm.png delete mode 100644 src/assets/images/friends/icon-profile.png delete mode 100644 src/assets/images/friends/icon-smile.png delete mode 100644 src/assets/images/friends/icon-warning.png delete mode 100644 src/assets/images/friends/messenger_notification_icon.png delete mode 100644 src/assets/images/gamecenter/selectedIcon.png delete mode 100644 src/assets/images/gift/gift_tag.png delete mode 100644 src/assets/images/gift/incognito.png delete mode 100644 src/assets/images/groups/creator_images.png delete mode 100644 src/assets/images/groups/creator_tabs.png delete mode 100644 src/assets/images/groups/icons/group_decorate_icon.png delete mode 100644 src/assets/images/groups/icons/group_favorite.png delete mode 100644 src/assets/images/groups/icons/group_icon_admin.png delete mode 100644 src/assets/images/groups/icons/group_icon_big_admin.png delete mode 100644 src/assets/images/groups/icons/group_icon_big_member.png delete mode 100644 src/assets/images/groups/icons/group_icon_big_owner.png delete mode 100644 src/assets/images/groups/icons/group_icon_not_admin.png delete mode 100644 src/assets/images/groups/icons/group_icon_small_owner.png delete mode 100644 src/assets/images/groups/icons/group_notfavorite.png delete mode 100644 src/assets/images/groups/icons/grouptype_icon_0.png delete mode 100644 src/assets/images/groups/icons/grouptype_icon_1.png delete mode 100644 src/assets/images/groups/icons/grouptype_icon_2.png delete mode 100644 src/assets/images/groups/no-group-1.png delete mode 100644 src/assets/images/groups/no-group-2.png delete mode 100644 src/assets/images/groups/no-group-3.png delete mode 100644 src/assets/images/groups/no-group-spritesheet.png delete mode 100644 src/assets/images/guide-tool/guide_tool_duty_switch.png delete mode 100644 src/assets/images/guide-tool/guide_tool_info_icon.png delete mode 100644 src/assets/images/hc-center/benefits.png delete mode 100644 src/assets/images/hc-center/clock.png delete mode 100644 src/assets/images/hc-center/hc_logo.gif delete mode 100644 src/assets/images/hc-center/payday.png delete mode 100644 src/assets/images/help/help_index.png delete mode 100644 src/assets/images/icons/arrows.png delete mode 100644 src/assets/images/icons/camera-colormatrix.png delete mode 100644 src/assets/images/icons/camera-composite.png delete mode 100644 src/assets/images/icons/camera-small.png delete mode 100644 src/assets/images/icons/chat-history.png delete mode 100644 src/assets/images/icons/close.png delete mode 100644 src/assets/images/icons/cog.png delete mode 100644 src/assets/images/icons/help.png delete mode 100644 src/assets/images/icons/house-small.png delete mode 100644 src/assets/images/icons/icon_cog.png delete mode 100644 src/assets/images/icons/like-room.png delete mode 100644 src/assets/images/icons/loading-icon.png delete mode 100644 src/assets/images/icons/room-link.png delete mode 100644 src/assets/images/icons/sign-exclamation.png delete mode 100644 src/assets/images/icons/sign-heart.png delete mode 100644 src/assets/images/icons/sign-red.png delete mode 100644 src/assets/images/icons/sign-skull.png delete mode 100644 src/assets/images/icons/sign-smile.png delete mode 100644 src/assets/images/icons/sign-soccer.png delete mode 100644 src/assets/images/icons/sign-yellow.png delete mode 100644 src/assets/images/icons/small-room.png delete mode 100644 src/assets/images/icons/tickets.png delete mode 100644 src/assets/images/icons/user.png delete mode 100644 src/assets/images/icons/zoom-less.png delete mode 100644 src/assets/images/icons/zoom-more.png delete mode 100644 src/assets/images/infostand/bot_background.png delete mode 100644 src/assets/images/infostand/countown-timer.png delete mode 100644 src/assets/images/infostand/disk-creator.png delete mode 100644 src/assets/images/infostand/disk-icon.png delete mode 100644 src/assets/images/infostand/pencil-icon.png delete mode 100644 src/assets/images/infostand/rarity-level.png delete mode 100644 src/assets/images/inventory/empty.png delete mode 100644 src/assets/images/inventory/rarity-level.png delete mode 100644 src/assets/images/inventory/trading/locked-icon.png delete mode 100644 src/assets/images/inventory/trading/unlocked-icon.png delete mode 100644 src/assets/images/loading/connecting-duck-spritesheet.png delete mode 100644 src/assets/images/loading/connecting_duck_01.png delete mode 100644 src/assets/images/loading/connecting_duck_02.png delete mode 100644 src/assets/images/loading/connecting_duck_03.png delete mode 100644 src/assets/images/loading/connecting_duck_04.png delete mode 100644 src/assets/images/loading/connecting_duck_05.png delete mode 100644 src/assets/images/loading/connecting_duck_06.png delete mode 100644 src/assets/images/loading/connecting_duck_07.png delete mode 100644 src/assets/images/loading/progress_habbos.gif delete mode 100644 src/assets/images/modtool/chatlog.gif delete mode 100644 src/assets/images/modtool/key.gif delete mode 100644 src/assets/images/modtool/m_icon.png delete mode 100644 src/assets/images/modtool/reports.png delete mode 100644 src/assets/images/modtool/room.gif delete mode 100644 src/assets/images/modtool/room.png delete mode 100644 src/assets/images/modtool/user.gif delete mode 100644 src/assets/images/modtool/wrench.gif delete mode 100644 src/assets/images/mysterybox/chain_mysterybox_box_overlay.png delete mode 100644 src/assets/images/mysterybox/key_overlay.png delete mode 100644 src/assets/images/mysterybox/mystery_box.png delete mode 100644 src/assets/images/mysterybox/mystery_box_key.png delete mode 100644 src/assets/images/mysterytrophy/frank_mystery_trophy.png delete mode 100644 src/assets/images/navigator/icons/info.png delete mode 100644 src/assets/images/navigator/icons/room_group.png delete mode 100644 src/assets/images/navigator/icons/room_invisible.png delete mode 100644 src/assets/images/navigator/icons/room_locked.png delete mode 100644 src/assets/images/navigator/icons/room_password.png delete mode 100644 src/assets/images/navigator/models/model_0.png delete mode 100644 src/assets/images/navigator/models/model_1.png delete mode 100644 src/assets/images/navigator/models/model_2.png delete mode 100644 src/assets/images/navigator/models/model_3.png delete mode 100644 src/assets/images/navigator/models/model_4.png delete mode 100644 src/assets/images/navigator/models/model_5.png delete mode 100644 src/assets/images/navigator/models/model_6.png delete mode 100644 src/assets/images/navigator/models/model_7.png delete mode 100644 src/assets/images/navigator/models/model_8.png delete mode 100644 src/assets/images/navigator/models/model_9.png delete mode 100644 src/assets/images/navigator/models/model_a.png delete mode 100644 src/assets/images/navigator/models/model_b.png delete mode 100644 src/assets/images/navigator/models/model_c.png delete mode 100644 src/assets/images/navigator/models/model_d.png delete mode 100644 src/assets/images/navigator/models/model_e.png delete mode 100644 src/assets/images/navigator/models/model_f.png delete mode 100644 src/assets/images/navigator/models/model_g.png delete mode 100644 src/assets/images/navigator/models/model_h.png delete mode 100644 src/assets/images/navigator/models/model_i.png delete mode 100644 src/assets/images/navigator/models/model_j.png delete mode 100644 src/assets/images/navigator/models/model_k.png delete mode 100644 src/assets/images/navigator/models/model_l.png delete mode 100644 src/assets/images/navigator/models/model_m.png delete mode 100644 src/assets/images/navigator/models/model_n.png delete mode 100644 src/assets/images/navigator/models/model_o.png delete mode 100644 src/assets/images/navigator/models/model_p.png delete mode 100644 src/assets/images/navigator/models/model_q.png delete mode 100644 src/assets/images/navigator/models/model_r.png delete mode 100644 src/assets/images/navigator/models/model_snowwar1.png delete mode 100644 src/assets/images/navigator/models/model_snowwar2.png delete mode 100644 src/assets/images/navigator/models/model_t.png delete mode 100644 src/assets/images/navigator/models/model_u.png delete mode 100644 src/assets/images/navigator/models/model_v.png delete mode 100644 src/assets/images/navigator/models/model_w.png delete mode 100644 src/assets/images/navigator/models/model_x.png delete mode 100644 src/assets/images/navigator/models/model_y.png delete mode 100644 src/assets/images/navigator/models/model_z.png delete mode 100644 src/assets/images/navigator/thumbnail_placeholder.png delete mode 100644 src/assets/images/nitro/nitro-dark.svg delete mode 100644 src/assets/images/nitro/nitro-light.svg delete mode 100644 src/assets/images/nitro/nitro-n-dark.svg delete mode 100644 src/assets/images/nitro/nitro-n-light.svg delete mode 100644 src/assets/images/notifications/frank.gif delete mode 100644 src/assets/images/pets/pet-package/gnome.png delete mode 100644 src/assets/images/pets/pet-package/leprechaun_box.png delete mode 100644 src/assets/images/pets/pet-package/petbox_epic.png delete mode 100644 src/assets/images/pets/pet-package/pterosaur_egg.png delete mode 100644 src/assets/images/pets/pet-package/val11_present.png delete mode 100644 src/assets/images/pets/pet-package/velociraptor_egg.png delete mode 100644 src/assets/images/prize/prize_background.png delete mode 100644 src/assets/images/profile/icons/offline.png delete mode 100644 src/assets/images/profile/icons/online.gif delete mode 100644 src/assets/images/profile/icons/tick.png delete mode 100644 src/assets/images/room-spectator/room_spectator_bottom_left.png delete mode 100644 src/assets/images/room-spectator/room_spectator_bottom_right.png delete mode 100644 src/assets/images/room-spectator/room_spectator_middle_bottom.png delete mode 100644 src/assets/images/room-spectator/room_spectator_middle_left.png delete mode 100644 src/assets/images/room-spectator/room_spectator_middle_right.png delete mode 100644 src/assets/images/room-spectator/room_spectator_middle_top.png delete mode 100644 src/assets/images/room-spectator/room_spectator_top_left.png delete mode 100644 src/assets/images/room-spectator/room_spectator_top_right.png delete mode 100644 src/assets/images/room-widgets/avatar-info/preview-background.png delete mode 100644 src/assets/images/room-widgets/camera-widget/btn.png delete mode 100644 src/assets/images/room-widgets/camera-widget/btn_down.png delete mode 100644 src/assets/images/room-widgets/camera-widget/btn_hi.png delete mode 100644 src/assets/images/room-widgets/camera-widget/cam_bg.png delete mode 100644 src/assets/images/room-widgets/camera-widget/camera-spritesheet.png delete mode 100644 src/assets/images/room-widgets/camera-widget/viewfinder.png delete mode 100644 src/assets/images/room-widgets/dimmer-widget/dimmer_banner.png delete mode 100644 src/assets/images/room-widgets/engraving-lock-widget/engraving-lock-spritesheet.png delete mode 100644 src/assets/images/room-widgets/exchange-credit/exchange-credit-image.png delete mode 100644 src/assets/images/room-widgets/furni-context-menu/monsterplant-preview.png delete mode 100644 src/assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png delete mode 100644 src/assets/images/room-widgets/playlist-editor/disk_2.png delete mode 100644 src/assets/images/room-widgets/playlist-editor/disk_image.png delete mode 100644 src/assets/images/room-widgets/playlist-editor/move.png delete mode 100644 src/assets/images/room-widgets/playlist-editor/pause-btn.png delete mode 100644 src/assets/images/room-widgets/playlist-editor/pause.png delete mode 100644 src/assets/images/room-widgets/playlist-editor/playing.png delete mode 100644 src/assets/images/room-widgets/playlist-editor/preview.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-blue.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-christmas.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-close.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-dreams.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-green.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-heart.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-juninas.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-pink.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-shakesp.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-spritesheet.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-trash.png delete mode 100644 src/assets/images/room-widgets/stickie-widget/stickie-yellow.png delete mode 100644 src/assets/images/room-widgets/thumbnail-widget/thumbnail-camera-spritesheet.png delete mode 100644 src/assets/images/room-widgets/trophy-widget/trophy-spritesheet.png delete mode 100644 src/assets/images/room-widgets/wordquiz-widget/thumbs-down-small.png delete mode 100644 src/assets/images/room-widgets/wordquiz-widget/thumbs-down.png delete mode 100644 src/assets/images/room-widgets/wordquiz-widget/thumbs-up-small.png delete mode 100644 src/assets/images/room-widgets/wordquiz-widget/thumbs-up.png delete mode 100644 src/assets/images/room-widgets/youtube-widget/next.png delete mode 100644 src/assets/images/room-widgets/youtube-widget/prev.png delete mode 100644 src/assets/images/stackhelper/slider-background.png delete mode 100644 src/assets/images/stackhelper/slider-pointer.png delete mode 100644 src/assets/images/toolbar/arrow.png delete mode 100644 src/assets/images/toolbar/friend-search.png delete mode 100644 src/assets/images/toolbar/icons/buildersclub.png delete mode 100644 src/assets/images/toolbar/icons/camera.png delete mode 100644 src/assets/images/toolbar/icons/catalog.png delete mode 100644 src/assets/images/toolbar/icons/friend_all.png delete mode 100644 src/assets/images/toolbar/icons/friend_head.png delete mode 100644 src/assets/images/toolbar/icons/friend_search.png delete mode 100644 src/assets/images/toolbar/icons/game.png delete mode 100644 src/assets/images/toolbar/icons/habbo.png delete mode 100644 src/assets/images/toolbar/icons/house.png delete mode 100644 src/assets/images/toolbar/icons/inventory.png delete mode 100644 src/assets/images/toolbar/icons/joinroom.png delete mode 100644 src/assets/images/toolbar/icons/me-menu/achievements.png delete mode 100644 src/assets/images/toolbar/icons/me-menu/clothing.png delete mode 100644 src/assets/images/toolbar/icons/me-menu/cog.png delete mode 100644 src/assets/images/toolbar/icons/me-menu/forums.png delete mode 100644 src/assets/images/toolbar/icons/me-menu/helper-tool.png delete mode 100644 src/assets/images/toolbar/icons/me-menu/my-rooms.png delete mode 100644 src/assets/images/toolbar/icons/me-menu/profile.png delete mode 100644 src/assets/images/toolbar/icons/me-menu/rooms.png delete mode 100644 src/assets/images/toolbar/icons/me-menu/talents.png delete mode 100644 src/assets/images/toolbar/icons/message.png delete mode 100644 src/assets/images/toolbar/icons/message_unsee.gif delete mode 100644 src/assets/images/toolbar/icons/modtools.png delete mode 100644 src/assets/images/toolbar/icons/rooms.png delete mode 100644 src/assets/images/toolbar/icons/sendmessage.png delete mode 100644 src/assets/images/unique/catalog-info-amount-bg.png delete mode 100644 src/assets/images/unique/catalog-info-sold-out.png delete mode 100644 src/assets/images/unique/grid-bg-glass.png delete mode 100644 src/assets/images/unique/grid-bg-sold-out.png delete mode 100644 src/assets/images/unique/grid-bg.png delete mode 100644 src/assets/images/unique/grid-count-bg.png delete mode 100644 src/assets/images/unique/inventory-info-amount-bg.png delete mode 100644 src/assets/images/unique/numbers.png delete mode 100644 src/assets/images/wired/card-action-corners.png delete mode 100644 src/assets/images/wired/icon_action.png delete mode 100644 src/assets/images/wired/icon_condition.png delete mode 100644 src/assets/images/wired/icon_trigger.png delete mode 100644 src/assets/images/wired/icon_wired_around.png delete mode 100644 src/assets/images/wired/icon_wired_left_right.png delete mode 100644 src/assets/images/wired/icon_wired_north_east.png delete mode 100644 src/assets/images/wired/icon_wired_north_west.png delete mode 100644 src/assets/images/wired/icon_wired_rotate_clockwise.png delete mode 100644 src/assets/images/wired/icon_wired_rotate_counter_clockwise.png delete mode 100644 src/assets/images/wired/icon_wired_south_east.png delete mode 100644 src/assets/images/wired/icon_wired_south_west.png delete mode 100644 src/assets/images/wired/icon_wired_up_down.png delete mode 100644 src/assets/styles/bootstrap/_accordion.scss delete mode 100644 src/assets/styles/bootstrap/_alert.scss delete mode 100644 src/assets/styles/bootstrap/_badge.scss delete mode 100644 src/assets/styles/bootstrap/_breadcrumb.scss delete mode 100644 src/assets/styles/bootstrap/_button-group.scss delete mode 100644 src/assets/styles/bootstrap/_buttons.scss delete mode 100644 src/assets/styles/bootstrap/_card.scss delete mode 100644 src/assets/styles/bootstrap/_carousel.scss delete mode 100644 src/assets/styles/bootstrap/_close.scss delete mode 100644 src/assets/styles/bootstrap/_containers.scss delete mode 100644 src/assets/styles/bootstrap/_dropdown.scss delete mode 100644 src/assets/styles/bootstrap/_forms.scss delete mode 100644 src/assets/styles/bootstrap/_functions.scss delete mode 100644 src/assets/styles/bootstrap/_grid.scss delete mode 100644 src/assets/styles/bootstrap/_helpers.scss delete mode 100644 src/assets/styles/bootstrap/_images.scss delete mode 100644 src/assets/styles/bootstrap/_list-group.scss delete mode 100644 src/assets/styles/bootstrap/_mixins.scss delete mode 100644 src/assets/styles/bootstrap/_modal.scss delete mode 100644 src/assets/styles/bootstrap/_nav.scss delete mode 100644 src/assets/styles/bootstrap/_navbar.scss delete mode 100644 src/assets/styles/bootstrap/_offcanvas.scss delete mode 100644 src/assets/styles/bootstrap/_pagination.scss delete mode 100644 src/assets/styles/bootstrap/_placeholders.scss delete mode 100644 src/assets/styles/bootstrap/_popover.scss delete mode 100644 src/assets/styles/bootstrap/_progress.scss delete mode 100644 src/assets/styles/bootstrap/_reboot.scss delete mode 100644 src/assets/styles/bootstrap/_root.scss delete mode 100644 src/assets/styles/bootstrap/_spinners.scss delete mode 100644 src/assets/styles/bootstrap/_tables.scss delete mode 100644 src/assets/styles/bootstrap/_toasts.scss delete mode 100644 src/assets/styles/bootstrap/_tooltip.scss delete mode 100644 src/assets/styles/bootstrap/_transitions.scss delete mode 100644 src/assets/styles/bootstrap/_type.scss delete mode 100644 src/assets/styles/bootstrap/_utilities.scss delete mode 100644 src/assets/styles/bootstrap/_variables.scss delete mode 100644 src/assets/styles/bootstrap/bootstrap-grid.scss delete mode 100644 src/assets/styles/bootstrap/bootstrap-reboot.scss delete mode 100644 src/assets/styles/bootstrap/bootstrap-utilities.scss delete mode 100644 src/assets/styles/bootstrap/bootstrap.scss delete mode 100644 src/assets/styles/bootstrap/forms/_floating-labels.scss delete mode 100644 src/assets/styles/bootstrap/forms/_form-check.scss delete mode 100644 src/assets/styles/bootstrap/forms/_form-control.scss delete mode 100644 src/assets/styles/bootstrap/forms/_form-range.scss delete mode 100644 src/assets/styles/bootstrap/forms/_form-select.scss delete mode 100644 src/assets/styles/bootstrap/forms/_form-text.scss delete mode 100644 src/assets/styles/bootstrap/forms/_input-group.scss delete mode 100644 src/assets/styles/bootstrap/forms/_labels.scss delete mode 100644 src/assets/styles/bootstrap/forms/_validation.scss delete mode 100644 src/assets/styles/bootstrap/helpers/_clearfix.scss delete mode 100644 src/assets/styles/bootstrap/helpers/_colored-links.scss delete mode 100644 src/assets/styles/bootstrap/helpers/_position.scss delete mode 100644 src/assets/styles/bootstrap/helpers/_ratio.scss delete mode 100644 src/assets/styles/bootstrap/helpers/_stacks.scss delete mode 100644 src/assets/styles/bootstrap/helpers/_stretched-link.scss delete mode 100644 src/assets/styles/bootstrap/helpers/_text-truncation.scss delete mode 100644 src/assets/styles/bootstrap/helpers/_visually-hidden.scss delete mode 100644 src/assets/styles/bootstrap/helpers/_vr.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_alert.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_backdrop.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_border-radius.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_box-shadow.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_breakpoints.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_buttons.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_caret.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_clearfix.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_color-scheme.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_container.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_deprecate.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_forms.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_gradients.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_grid.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_image.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_list-group.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_lists.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_pagination.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_reset-text.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_resize.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_table-variants.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_text-truncate.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_transition.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_utilities.scss delete mode 100644 src/assets/styles/bootstrap/mixins/_visually-hidden.scss delete mode 100644 src/assets/styles/bootstrap/utilities/_api.scss delete mode 100644 src/assets/styles/bootstrap/vendor/_rfs.scss delete mode 100644 src/assets/styles/fonts.scss delete mode 100644 src/assets/styles/icons.scss delete mode 100644 src/assets/styles/index.scss delete mode 100644 src/assets/styles/scrollbars.scss delete mode 100644 src/assets/styles/slider.scss delete mode 100644 src/assets/styles/utils.scss delete mode 100644 src/assets/webfonts/Ubuntu-C.ttf delete mode 100644 src/assets/webfonts/Ubuntu-b.ttf delete mode 100644 src/assets/webfonts/Ubuntu-i.ttf delete mode 100644 src/assets/webfonts/Ubuntu-ib.ttf delete mode 100644 src/assets/webfonts/Ubuntu-m.ttf delete mode 100644 src/assets/webfonts/Ubuntu.ttf delete mode 100644 src/common/AutoGrid.tsx delete mode 100644 src/common/Base.tsx delete mode 100644 src/common/Button.tsx delete mode 100644 src/common/ButtonGroup.tsx delete mode 100644 src/common/Column.tsx delete mode 100644 src/common/Flex.tsx delete mode 100644 src/common/FormGroup.tsx delete mode 100644 src/common/Grid.tsx delete mode 100644 src/common/GridContext.tsx delete mode 100644 src/common/HorizontalRule.tsx delete mode 100644 src/common/InfiniteGrid.tsx delete mode 100644 src/common/InfiniteScroll.tsx delete mode 100644 src/common/Text.tsx delete mode 100644 src/common/card/NitroCardContentView.tsx delete mode 100644 src/common/card/NitroCardContext.tsx delete mode 100644 src/common/card/NitroCardHeaderView.tsx delete mode 100644 src/common/card/NitroCardSubHeaderView.tsx delete mode 100644 src/common/card/NitroCardView.scss delete mode 100644 src/common/card/NitroCardView.tsx delete mode 100644 src/common/card/accordion/NitroCardAccordionContext.tsx delete mode 100644 src/common/card/accordion/NitroCardAccordionItemView.tsx delete mode 100644 src/common/card/accordion/NitroCardAccordionSetView.tsx delete mode 100644 src/common/card/accordion/NitroCardAccordionView.tsx delete mode 100644 src/common/card/accordion/index.ts delete mode 100644 src/common/card/index.ts delete mode 100644 src/common/card/tabs/NitroCardTabsItemView.tsx delete mode 100644 src/common/card/tabs/NitroCardTabsView.tsx delete mode 100644 src/common/card/tabs/index.ts delete mode 100644 src/common/classNames.ts delete mode 100644 src/common/draggable-window/DraggableWindow.tsx delete mode 100644 src/common/draggable-window/DraggableWindowPosition.ts delete mode 100644 src/common/draggable-window/index.ts delete mode 100644 src/common/index.scss delete mode 100644 src/common/index.ts delete mode 100644 src/common/layout/LayoutAvatarImageView.tsx delete mode 100644 src/common/layout/LayoutBackgroundImage.tsx delete mode 100644 src/common/layout/LayoutBadgeImageView.tsx delete mode 100644 src/common/layout/LayoutCounterTimeView.tsx delete mode 100644 src/common/layout/LayoutCurrencyIcon.tsx delete mode 100644 src/common/layout/LayoutFurniIconImageView.tsx delete mode 100644 src/common/layout/LayoutFurniImageView.tsx delete mode 100644 src/common/layout/LayoutGiftTagView.tsx delete mode 100644 src/common/layout/LayoutGridItem.tsx delete mode 100644 src/common/layout/LayoutImage.tsx delete mode 100644 src/common/layout/LayoutItemCountView.tsx delete mode 100644 src/common/layout/LayoutLoadingSpinnerView.tsx delete mode 100644 src/common/layout/LayoutMiniCameraView.tsx delete mode 100644 src/common/layout/LayoutNotificationAlertView.tsx delete mode 100644 src/common/layout/LayoutNotificationBubbleView.tsx delete mode 100644 src/common/layout/LayoutPetImageView.tsx delete mode 100644 src/common/layout/LayoutPrizeProductImageView.tsx delete mode 100644 src/common/layout/LayoutProgressBar.tsx delete mode 100644 src/common/layout/LayoutRarityLevelView.tsx delete mode 100644 src/common/layout/LayoutRoomObjectImageView.tsx delete mode 100644 src/common/layout/LayoutRoomPreviewerView.tsx delete mode 100644 src/common/layout/LayoutRoomThumbnailView.tsx delete mode 100644 src/common/layout/LayoutTrophyView.tsx delete mode 100644 src/common/layout/UserProfileIconView.tsx delete mode 100644 src/common/layout/index.ts delete mode 100644 src/common/layout/limited-edition/LayoutLimitedEditionCompactPlateView.tsx delete mode 100644 src/common/layout/limited-edition/LayoutLimitedEditionCompletePlateView.tsx delete mode 100644 src/common/layout/limited-edition/LayoutLimitedEditionStyledNumberView.tsx delete mode 100644 src/common/layout/limited-edition/index.ts delete mode 100644 src/common/transitions/TransitionAnimation.tsx delete mode 100644 src/common/transitions/TransitionAnimationStyles.ts delete mode 100644 src/common/transitions/TransitionAnimationTypes.ts delete mode 100644 src/common/transitions/index.ts delete mode 100644 src/common/types/AlignItemType.ts delete mode 100644 src/common/types/AlignSelfType.ts delete mode 100644 src/common/types/ButtonSizeType.ts delete mode 100644 src/common/types/ColorVariantType.ts delete mode 100644 src/common/types/ColumnSizesType.ts delete mode 100644 src/common/types/DisplayType.ts delete mode 100644 src/common/types/FloatType.ts delete mode 100644 src/common/types/FontSizeType.ts delete mode 100644 src/common/types/FontWeightType.ts delete mode 100644 src/common/types/JustifyContentType.ts delete mode 100644 src/common/types/OverflowType.ts delete mode 100644 src/common/types/PositionType.ts delete mode 100644 src/common/types/SpacingType.ts delete mode 100644 src/common/types/TextAlignType.ts delete mode 100644 src/common/types/index.ts delete mode 100644 src/common/utils/CreateTransitionToIcon.ts delete mode 100644 src/common/utils/FriendlyTimeView.tsx delete mode 100644 src/common/utils/index.ts delete mode 100644 src/components/achievements/AchievementsView.scss delete mode 100644 src/components/achievements/AchievementsView.tsx delete mode 100644 src/components/achievements/views/AchievementBadgeView.tsx delete mode 100644 src/components/achievements/views/AchievementCategoryView.tsx delete mode 100644 src/components/achievements/views/AchievementDetailsView.tsx delete mode 100644 src/components/achievements/views/achievement-list/AchievementListItemView.tsx delete mode 100644 src/components/achievements/views/achievement-list/AchievementListView.tsx delete mode 100644 src/components/achievements/views/achievement-list/index.ts delete mode 100644 src/components/achievements/views/category-list/AchievementsCategoryListItemView.tsx delete mode 100644 src/components/achievements/views/category-list/AchievementsCategoryListView.tsx delete mode 100644 src/components/achievements/views/category-list/index.ts delete mode 100644 src/components/achievements/views/index.ts delete mode 100644 src/components/avatar-editor-new/AvatarEditorView.scss delete mode 100644 src/components/avatar-editor-new/AvatarEditorView.tsx delete mode 100644 src/components/avatar-editor-new/views/AvatarEditorIcon.tsx delete mode 100644 src/components/avatar-editor-new/views/AvatarEditorModelView.tsx delete mode 100644 src/components/avatar-editor-new/views/figure-set/AvatarEditorFigureSetItemView.tsx delete mode 100644 src/components/avatar-editor-new/views/figure-set/AvatarEditorFigureSetView.tsx delete mode 100644 src/components/avatar-editor-new/views/figure-set/index.ts delete mode 100644 src/components/avatar-editor-new/views/palette-set/AvatarEditorPaletteSetItemView.tsx delete mode 100644 src/components/avatar-editor-new/views/palette-set/AvatarEditorPaletteSetView.tsx delete mode 100644 src/components/avatar-editor-new/views/palette-set/index.ts delete mode 100644 src/components/avatar-editor/AvatarEditorView.scss delete mode 100644 src/components/avatar-editor/AvatarEditorView.tsx delete mode 100644 src/components/avatar-editor/views/AvatarEditorFigurePreviewView.tsx delete mode 100644 src/components/avatar-editor/views/AvatarEditorIcon.tsx delete mode 100644 src/components/avatar-editor/views/AvatarEditorModelView.tsx delete mode 100644 src/components/avatar-editor/views/AvatarEditorWardrobeView.tsx delete mode 100644 src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetItemView.tsx delete mode 100644 src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetView.tsx delete mode 100644 src/components/avatar-editor/views/figure-set/index.ts delete mode 100644 src/components/avatar-editor/views/index.ts delete mode 100644 src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetItemView.tsx delete mode 100644 src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.tsx delete mode 100644 src/components/avatar-editor/views/palette-set/index.ts delete mode 100644 src/components/camera/CameraWidgetView.scss delete mode 100644 src/components/camera/CameraWidgetView.tsx delete mode 100644 src/components/camera/index.ts delete mode 100644 src/components/camera/views/CameraWidgetCaptureView.tsx delete mode 100644 src/components/camera/views/CameraWidgetCheckoutView.tsx delete mode 100644 src/components/camera/views/CameraWidgetShowPhotoView.tsx delete mode 100644 src/components/camera/views/editor/CameraWidgetEditorView.tsx delete mode 100644 src/components/camera/views/editor/effect-list/CameraWidgetEffectListItemView.tsx delete mode 100644 src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx delete mode 100644 src/components/camera/views/editor/effect-list/index.ts delete mode 100644 src/components/camera/views/editor/index.ts delete mode 100644 src/components/camera/views/index.ts delete mode 100644 src/components/campaign/CalendarItemView.tsx delete mode 100644 src/components/campaign/CalendarView.tsx delete mode 100644 src/components/campaign/CampaignView.scss delete mode 100644 src/components/campaign/CampaignView.tsx delete mode 100644 src/components/catalog/CatalogView.scss delete mode 100644 src/components/catalog/CatalogView.tsx delete mode 100644 src/components/catalog/views/CatalogPurchaseConfirmView.tsx delete mode 100644 src/components/catalog/views/catalog-header/CatalogHeaderView.tsx delete mode 100644 src/components/catalog/views/catalog-icon/CatalogIconView.tsx delete mode 100644 src/components/catalog/views/catalog-room-previewer/CatalogRoomPreviewerView.tsx delete mode 100644 src/components/catalog/views/gift/CatalogGiftView.tsx delete mode 100644 src/components/catalog/views/navigation/CatalogNavigationItemView.tsx delete mode 100644 src/components/catalog/views/navigation/CatalogNavigationSetView.tsx delete mode 100644 src/components/catalog/views/navigation/CatalogNavigationView.tsx delete mode 100644 src/components/catalog/views/page/common/CatalogGridOfferView.tsx delete mode 100644 src/components/catalog/views/page/common/CatalogRedeemVoucherView.tsx delete mode 100644 src/components/catalog/views/page/common/CatalogSearchView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayout.types.ts delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutBadgeDisplayView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutColorGroupingView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutDefaultView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutGuildCustomFurniView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutGuildForumView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutGuildFrontpageView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutInfoLoyaltyView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutPets2View.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutPets3View.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutRoomAdsView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutRoomBundleView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutSingleBundleView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutSoundMachineView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutSpacesView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutTrophiesView.tsx delete mode 100644 src/components/catalog/views/page/layout/CatalogLayoutVipBuyView.tsx delete mode 100644 src/components/catalog/views/page/layout/GetCatalogLayout.tsx delete mode 100644 src/components/catalog/views/page/layout/frontpage4/CatalogLayoutFrontPageItemView.tsx delete mode 100644 src/components/catalog/views/page/layout/frontpage4/CatalogLayoutFrontpage4View.tsx delete mode 100644 src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceItemView.tsx delete mode 100644 src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceOwnItemsView.tsx delete mode 100644 src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplacePublicItemsView.tsx delete mode 100644 src/components/catalog/views/page/layout/marketplace/CatalogLayoutMarketplaceSearchFormView.tsx delete mode 100644 src/components/catalog/views/page/layout/marketplace/MarketplacePostOfferView.tsx delete mode 100644 src/components/catalog/views/page/layout/pets/CatalogLayoutPetView.tsx delete mode 100644 src/components/catalog/views/page/layout/vip-gifts/CatalogLayoutVipGiftsView.tsx delete mode 100644 src/components/catalog/views/page/layout/vip-gifts/VipGiftItemView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogAddOnBadgeWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogBadgeSelectorWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogBundleGridWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogFirstProductSelectorWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogGuildBadgeWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogGuildSelectorWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogItemGridWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogLimitedItemWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogPriceDisplayWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogPurchaseWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogSimplePriceWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogSingleViewWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogSpacesWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogSpinnerWidgetView.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogTotalPriceWidget.tsx delete mode 100644 src/components/catalog/views/page/widgets/CatalogViewProductWidgetView.tsx delete mode 100644 src/components/catalog/views/targeted-offer/Offer.scss delete mode 100644 src/components/catalog/views/targeted-offer/OfferBubbleView.tsx delete mode 100644 src/components/catalog/views/targeted-offer/OfferView.tsx delete mode 100644 src/components/catalog/views/targeted-offer/OfferWindowView.tsx delete mode 100644 src/components/chat-history/ChatHistoryView.scss delete mode 100644 src/components/chat-history/ChatHistoryView.tsx delete mode 100644 src/components/floorplan-editor/FloorplanEditorContext.tsx delete mode 100644 src/components/floorplan-editor/FloorplanEditorView.scss delete mode 100644 src/components/floorplan-editor/FloorplanEditorView.tsx delete mode 100644 src/components/floorplan-editor/common/ActionSettings.ts delete mode 100644 src/components/floorplan-editor/common/Constants.ts delete mode 100644 src/components/floorplan-editor/common/ConvertMapToString.ts delete mode 100644 src/components/floorplan-editor/common/FloorplanEditor.ts delete mode 100644 src/components/floorplan-editor/common/FloorplanResource.ts delete mode 100644 src/components/floorplan-editor/common/IFloorplanSettings.ts delete mode 100644 src/components/floorplan-editor/common/IVisualizationSettings.ts delete mode 100644 src/components/floorplan-editor/common/Tile.ts delete mode 100644 src/components/floorplan-editor/common/Utils.ts delete mode 100644 src/components/floorplan-editor/views/FloorplanCanvasView.tsx delete mode 100644 src/components/floorplan-editor/views/FloorplanImportExportView.tsx delete mode 100644 src/components/floorplan-editor/views/FloorplanOptionsView.tsx delete mode 100644 src/components/friends/FriendsView.scss delete mode 100644 src/components/friends/FriendsView.tsx delete mode 100644 src/components/friends/views/friends-bar/FriendBarItemView.tsx delete mode 100644 src/components/friends/views/friends-bar/FriendsBarView.tsx delete mode 100644 src/components/friends/views/friends-list/FriendsListRemoveConfirmationView.tsx delete mode 100644 src/components/friends/views/friends-list/FriendsListRoomInviteView.tsx delete mode 100644 src/components/friends/views/friends-list/FriendsListSearchView.tsx delete mode 100644 src/components/friends/views/friends-list/FriendsListView.tsx delete mode 100644 src/components/friends/views/friends-list/friends-list-group/FriendsListGroupItemView.tsx delete mode 100644 src/components/friends/views/friends-list/friends-list-group/FriendsListGroupView.tsx delete mode 100644 src/components/friends/views/friends-list/friends-list-request/FriendsListRequestItemView.tsx delete mode 100644 src/components/friends/views/friends-list/friends-list-request/FriendsListRequestView.tsx delete mode 100644 src/components/friends/views/messenger/FriendsMessengerView.tsx delete mode 100644 src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadGroup.tsx delete mode 100644 src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadView.tsx delete mode 100644 src/components/game-center/GameCenterView.scss delete mode 100644 src/components/game-center/GameCenterView.tsx delete mode 100644 src/components/game-center/views/GameListView.tsx delete mode 100644 src/components/game-center/views/GameStageView.tsx delete mode 100644 src/components/game-center/views/GameView.tsx delete mode 100644 src/components/groups/GroupView.scss delete mode 100644 src/components/groups/GroupsView.tsx delete mode 100644 src/components/groups/views/GroupBadgeCreatorView.tsx delete mode 100644 src/components/groups/views/GroupCreatorView.tsx delete mode 100644 src/components/groups/views/GroupInformationStandaloneView.tsx delete mode 100644 src/components/groups/views/GroupInformationView.tsx delete mode 100644 src/components/groups/views/GroupManagerView.tsx delete mode 100644 src/components/groups/views/GroupMembersView.tsx delete mode 100644 src/components/groups/views/GroupRoomInformationView.tsx delete mode 100644 src/components/groups/views/tabs/GroupTabBadgeView.tsx delete mode 100644 src/components/groups/views/tabs/GroupTabColorsView.tsx delete mode 100644 src/components/groups/views/tabs/GroupTabCreatorConfirmationView.tsx delete mode 100644 src/components/groups/views/tabs/GroupTabIdentityView.tsx delete mode 100644 src/components/groups/views/tabs/GroupTabSettingsView.tsx delete mode 100644 src/components/guide-tool/GuideToolView.scss delete mode 100644 src/components/guide-tool/GuideToolView.tsx delete mode 100644 src/components/guide-tool/views/GuideToolAcceptView.tsx delete mode 100644 src/components/guide-tool/views/GuideToolMenuView.tsx delete mode 100644 src/components/guide-tool/views/GuideToolOngoingView.tsx delete mode 100644 src/components/guide-tool/views/GuideToolUserCreateRequestView.tsx delete mode 100644 src/components/guide-tool/views/GuideToolUserFeedbackView.tsx delete mode 100644 src/components/guide-tool/views/GuideToolUserNoHelpersView.tsx delete mode 100644 src/components/guide-tool/views/GuideToolUserPendingView.tsx delete mode 100644 src/components/guide-tool/views/GuideToolUserSomethingWrogView.tsx delete mode 100644 src/components/guide-tool/views/GuideToolUserThanksView.tsx delete mode 100644 src/components/hc-center/HcCenterView.scss delete mode 100644 src/components/hc-center/HcCenterView.tsx delete mode 100644 src/components/help/HelpView.scss delete mode 100644 src/components/help/HelpView.tsx delete mode 100644 src/components/help/views/DescribeReportView.tsx delete mode 100644 src/components/help/views/HelpIndexView.tsx delete mode 100644 src/components/help/views/ReportSummaryView.tsx delete mode 100644 src/components/help/views/SanctionStatusView.tsx delete mode 100644 src/components/help/views/SelectReportedChatsView.tsx delete mode 100644 src/components/help/views/SelectReportedUserView.tsx delete mode 100644 src/components/help/views/SelectTopicView.tsx delete mode 100644 src/components/help/views/name-change/NameChangeConfirmationView.tsx delete mode 100644 src/components/help/views/name-change/NameChangeInitView.tsx delete mode 100644 src/components/help/views/name-change/NameChangeInputView.tsx delete mode 100644 src/components/help/views/name-change/NameChangeView.tsx delete mode 100644 src/components/help/views/name-change/NameChangeView.types.ts delete mode 100644 src/components/hotel-view/HotelView.scss delete mode 100644 src/components/hotel-view/HotelView.tsx delete mode 100644 src/components/hotel-view/views/widgets/GetWidgetLayout.tsx delete mode 100644 src/components/hotel-view/views/widgets/HotelViewWidgets.scss delete mode 100644 src/components/hotel-view/views/widgets/WidgetSlotView.tsx delete mode 100644 src/components/hotel-view/views/widgets/bonus-rare/BonusRareWidgetView.scss delete mode 100644 src/components/hotel-view/views/widgets/bonus-rare/BonusRareWidgetView.tsx delete mode 100644 src/components/hotel-view/views/widgets/hall-of-fame-item/HallOfFameItemView.tsx delete mode 100644 src/components/hotel-view/views/widgets/hall-of-fame/HallOfFameWidgetView.scss delete mode 100644 src/components/hotel-view/views/widgets/hall-of-fame/HallOfFameWidgetView.tsx delete mode 100644 src/components/hotel-view/views/widgets/hall-of-fame/HallOfFameWidgetView.types.ts delete mode 100644 src/components/hotel-view/views/widgets/promo-article/PromoArticleWidgetView.scss delete mode 100644 src/components/hotel-view/views/widgets/promo-article/PromoArticleWidgetView.tsx delete mode 100644 src/components/hotel-view/views/widgets/widget-container/WidgetContainerView.scss delete mode 100644 src/components/hotel-view/views/widgets/widget-container/WidgetContainerView.tsx delete mode 100644 src/components/index.scss delete mode 100644 src/components/inventory/InventoryView.scss delete mode 100644 src/components/inventory/InventoryView.tsx delete mode 100644 src/components/inventory/views/InventoryCategoryEmptyView.tsx delete mode 100644 src/components/inventory/views/badge/InventoryBadgeItemView.tsx delete mode 100644 src/components/inventory/views/badge/InventoryBadgeView.tsx delete mode 100644 src/components/inventory/views/bot/InventoryBotItemView.tsx delete mode 100644 src/components/inventory/views/bot/InventoryBotView.tsx delete mode 100644 src/components/inventory/views/furniture/InventoryFurnitureItemView.tsx delete mode 100644 src/components/inventory/views/furniture/InventoryFurnitureSearchView.tsx delete mode 100644 src/components/inventory/views/furniture/InventoryFurnitureView.tsx delete mode 100644 src/components/inventory/views/furniture/InventoryTradeView.tsx delete mode 100644 src/components/inventory/views/pet/InventoryPetItemView.tsx delete mode 100644 src/components/inventory/views/pet/InventoryPetView.tsx delete mode 100644 src/components/loading/LoadingView.scss delete mode 100644 src/components/loading/LoadingView.tsx delete mode 100644 src/components/main/MainView.tsx delete mode 100644 src/components/mod-tools/ModToolsView.scss delete mode 100644 src/components/mod-tools/ModToolsView.tsx delete mode 100644 src/components/mod-tools/views/chatlog/ChatlogRecord.ts delete mode 100644 src/components/mod-tools/views/chatlog/ChatlogView.tsx delete mode 100644 src/components/mod-tools/views/room/ModToolsChatlogView.tsx delete mode 100644 src/components/mod-tools/views/room/ModToolsRoomView.tsx delete mode 100644 src/components/mod-tools/views/tickets/CfhChatlogView.tsx delete mode 100644 src/components/mod-tools/views/tickets/ModToolsIssueInfoView.tsx delete mode 100644 src/components/mod-tools/views/tickets/ModToolsMyIssuesTabView.tsx delete mode 100644 src/components/mod-tools/views/tickets/ModToolsOpenIssuesTabView.tsx delete mode 100644 src/components/mod-tools/views/tickets/ModToolsPickedIssuesTabView.tsx delete mode 100644 src/components/mod-tools/views/tickets/ModToolsTicketsView.tsx delete mode 100644 src/components/mod-tools/views/user/ModToolsUserChatlogView.tsx delete mode 100644 src/components/mod-tools/views/user/ModToolsUserModActionView.tsx delete mode 100644 src/components/mod-tools/views/user/ModToolsUserRoomVisitsView.tsx delete mode 100644 src/components/mod-tools/views/user/ModToolsUserSendMessageView.tsx delete mode 100644 src/components/mod-tools/views/user/ModToolsUserView.tsx delete mode 100644 src/components/navigator/NavigatorView.scss delete mode 100644 src/components/navigator/NavigatorView.tsx delete mode 100644 src/components/navigator/views/NavigatorDoorStateView.tsx delete mode 100644 src/components/navigator/views/NavigatorRoomCreatorView.tsx delete mode 100644 src/components/navigator/views/NavigatorRoomInfoView.tsx delete mode 100644 src/components/navigator/views/NavigatorRoomLinkView.tsx delete mode 100644 src/components/navigator/views/room-settings/NavigatorRoomSettingsAccessTabView.tsx delete mode 100644 src/components/navigator/views/room-settings/NavigatorRoomSettingsBasicTabView.tsx delete mode 100644 src/components/navigator/views/room-settings/NavigatorRoomSettingsModTabView.tsx delete mode 100644 src/components/navigator/views/room-settings/NavigatorRoomSettingsRightsTabView.tsx delete mode 100644 src/components/navigator/views/room-settings/NavigatorRoomSettingsView.tsx delete mode 100644 src/components/navigator/views/room-settings/NavigatorRoomSettingsVipChatTabView.tsx delete mode 100644 src/components/navigator/views/search/NavigatorSearchResultItemInfoView.tsx delete mode 100644 src/components/navigator/views/search/NavigatorSearchResultItemView.tsx delete mode 100644 src/components/navigator/views/search/NavigatorSearchResultView.tsx delete mode 100644 src/components/navigator/views/search/NavigatorSearchView.tsx delete mode 100644 src/components/nitropedia/NitropediaView.scss delete mode 100644 src/components/nitropedia/NitropediaView.tsx delete mode 100644 src/components/notification-center/NotificationCenterView.scss delete mode 100644 src/components/notification-center/NotificationCenterView.tsx delete mode 100644 src/components/notification-center/views/alert-layouts/GetAlertLayout.tsx delete mode 100644 src/components/notification-center/views/alert-layouts/NitroSystemAlertView.tsx delete mode 100644 src/components/notification-center/views/alert-layouts/NotificationDefaultAlertView.tsx delete mode 100644 src/components/notification-center/views/alert-layouts/NotificationSearchAlertView.tsx delete mode 100644 src/components/notification-center/views/bubble-layouts/GetBubbleLayout.tsx delete mode 100644 src/components/notification-center/views/bubble-layouts/NotificationClubGiftBubbleView.tsx delete mode 100644 src/components/notification-center/views/bubble-layouts/NotificationDefaultBubbleView.tsx delete mode 100644 src/components/notification-center/views/confirm-layouts/GetConfirmLayout.tsx delete mode 100644 src/components/notification-center/views/confirm-layouts/NotificationDefaultConfirmView.tsx delete mode 100644 src/components/purse/PurseView.scss delete mode 100644 src/components/purse/PurseView.tsx delete mode 100644 src/components/purse/views/CurrencyView.tsx delete mode 100644 src/components/purse/views/SeasonalView.tsx delete mode 100644 src/components/right-side/RightSideView.scss delete mode 100644 src/components/right-side/RightSideView.tsx delete mode 100644 src/components/room/RoomView.scss delete mode 100644 src/components/room/RoomView.tsx delete mode 100644 src/components/room/spectator/RoomSpectatorView.scss delete mode 100644 src/components/room/spectator/RoomSpectatorView.tsx delete mode 100644 src/components/room/widgets/RoomWidgets.scss delete mode 100644 src/components/room/widgets/RoomWidgetsView.tsx delete mode 100644 src/components/room/widgets/avatar-info/AvatarInfoPetTrainingPanelView.tsx delete mode 100644 src/components/room/widgets/avatar-info/AvatarInfoRentableBotChatView.tsx delete mode 100644 src/components/room/widgets/avatar-info/AvatarInfoUseProductConfirmView.tsx delete mode 100644 src/components/room/widgets/avatar-info/AvatarInfoUseProductView.tsx delete mode 100644 src/components/room/widgets/avatar-info/AvatarInfoWidgetView.scss delete mode 100644 src/components/room/widgets/avatar-info/AvatarInfoWidgetView.tsx delete mode 100644 src/components/room/widgets/avatar-info/infostand/InfoStandWidgetBotView.tsx delete mode 100644 src/components/room/widgets/avatar-info/infostand/InfoStandWidgetFurniView.tsx delete mode 100644 src/components/room/widgets/avatar-info/infostand/InfoStandWidgetPetView.tsx delete mode 100644 src/components/room/widgets/avatar-info/infostand/InfoStandWidgetRentableBotView.tsx delete mode 100644 src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserRelationshipItemView.tsx delete mode 100644 src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserRelationshipsView.tsx delete mode 100644 src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserTagsView.tsx delete mode 100644 src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserView.tsx delete mode 100644 src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetAvatarView.tsx delete mode 100644 src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetDecorateView.tsx delete mode 100644 src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetFurniView.tsx delete mode 100644 src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetNameView.tsx delete mode 100644 src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetOwnAvatarView.tsx delete mode 100644 src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetOwnPetView.tsx delete mode 100644 src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetPetView.tsx delete mode 100644 src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetRentableBotView.tsx delete mode 100644 src/components/room/widgets/chat-input/ChatInputStyleSelectorView.tsx delete mode 100644 src/components/room/widgets/chat-input/ChatInputView.scss delete mode 100644 src/components/room/widgets/chat-input/ChatInputView.tsx delete mode 100644 src/components/room/widgets/chat/ChatWidgetMessageView.tsx delete mode 100644 src/components/room/widgets/chat/ChatWidgetView.scss delete mode 100644 src/components/room/widgets/chat/ChatWidgetView.tsx delete mode 100644 src/components/room/widgets/choosers/ChooserWidgetView.scss delete mode 100644 src/components/room/widgets/choosers/ChooserWidgetView.tsx delete mode 100644 src/components/room/widgets/choosers/FurniChooserWidgetView.tsx delete mode 100644 src/components/room/widgets/choosers/UserChooserWidgetView.tsx delete mode 100644 src/components/room/widgets/context-menu/ContextMenu.scss delete mode 100644 src/components/room/widgets/context-menu/ContextMenuCaretView.tsx delete mode 100644 src/components/room/widgets/context-menu/ContextMenuHeaderView.tsx delete mode 100644 src/components/room/widgets/context-menu/ContextMenuListItemView.tsx delete mode 100644 src/components/room/widgets/context-menu/ContextMenuListView.tsx delete mode 100644 src/components/room/widgets/context-menu/ContextMenuView.tsx delete mode 100644 src/components/room/widgets/doorbell/DoorbellWidgetView.tsx delete mode 100644 src/components/room/widgets/friend-request/FriendRequestDialogView.scss delete mode 100644 src/components/room/widgets/friend-request/FriendRequestDialogView.tsx delete mode 100644 src/components/room/widgets/friend-request/FriendRequestWidgetView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureBackgroundColorView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureBadgeDisplayView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureCraftingView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureDimmerView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureExchangeCreditView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureExternalImageView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureFriendFurniView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureGiftOpeningView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureHighScoreView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureInternalLinkView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureMannequinView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureMysteryBoxOpenDialogView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureMysteryTrophyOpenDialogView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureRoomLinkView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureSpamWallPostItView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureStackHeightView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureStickieView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureTrophyView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureWidgets.scss delete mode 100644 src/components/room/widgets/furniture/FurnitureWidgetsView.tsx delete mode 100644 src/components/room/widgets/furniture/FurnitureYoutubeDisplayView.tsx delete mode 100644 src/components/room/widgets/furniture/context-menu/EffectBoxConfirmView.tsx delete mode 100644 src/components/room/widgets/furniture/context-menu/FurnitureContextMenuView.tsx delete mode 100644 src/components/room/widgets/furniture/context-menu/MonsterPlantSeedConfirmView.tsx delete mode 100644 src/components/room/widgets/furniture/context-menu/PurchasableClothingConfirmView.tsx delete mode 100644 src/components/room/widgets/furniture/playlist-editor/DiskInventoryView.tsx delete mode 100644 src/components/room/widgets/furniture/playlist-editor/FurniturePlaylistEditorWidgetView.tsx delete mode 100644 src/components/room/widgets/furniture/playlist-editor/SongPlaylistView.tsx delete mode 100644 src/components/room/widgets/mysterybox/MysteryBoxExtensionView.scss delete mode 100644 src/components/room/widgets/mysterybox/MysteryBoxExtensionView.tsx delete mode 100644 src/components/room/widgets/object-location/ObjectLocationView.tsx delete mode 100644 src/components/room/widgets/pet-package/PetPackageWidgetView.scss delete mode 100644 src/components/room/widgets/pet-package/PetPackageWidgetView.tsx delete mode 100644 src/components/room/widgets/room-filter-words/RoomFilterWordsWidgetView.tsx delete mode 100644 src/components/room/widgets/room-promotes/RoomPromotesWidgetView.tsx delete mode 100644 src/components/room/widgets/room-promotes/views/RoomPromoteEditWidgetView.tsx delete mode 100644 src/components/room/widgets/room-promotes/views/RoomPromoteMyOwnEventWidgetView.tsx delete mode 100644 src/components/room/widgets/room-promotes/views/RoomPromoteOtherEventWidgetView.tsx delete mode 100644 src/components/room/widgets/room-promotes/views/index.ts delete mode 100644 src/components/room/widgets/room-thumbnail/RoomThumbnailWidgetView.tsx delete mode 100644 src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx delete mode 100644 src/components/room/widgets/user-location/UserLocationView.tsx delete mode 100644 src/components/room/widgets/word-quiz/WordQuizQuestionView.tsx delete mode 100644 src/components/room/widgets/word-quiz/WordQuizVoteView.tsx delete mode 100644 src/components/room/widgets/word-quiz/WordQuizWidgetView.tsx delete mode 100644 src/components/toolbar/ToolbarMeView.tsx delete mode 100644 src/components/toolbar/ToolbarView.scss delete mode 100644 src/components/toolbar/ToolbarView.tsx delete mode 100644 src/components/user-profile/UserProfileVew.scss delete mode 100644 src/components/user-profile/UserProfileView.tsx delete mode 100644 src/components/user-profile/views/BadgesContainerView.tsx delete mode 100644 src/components/user-profile/views/FriendsContainerView.tsx delete mode 100644 src/components/user-profile/views/GroupsContainerView.tsx delete mode 100644 src/components/user-profile/views/RelationshipsContainerView.tsx delete mode 100644 src/components/user-profile/views/UserContainerView.tsx delete mode 100644 src/components/user-settings/UserSettingsView.tsx delete mode 100644 src/components/wired/WiredView.scss delete mode 100644 src/components/wired/WiredView.tsx delete mode 100644 src/components/wired/views/WiredBaseView.tsx delete mode 100644 src/components/wired/views/WiredFurniSelectorView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionBaseView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionBotChangeFigureView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionBotFollowAvatarView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionBotGiveHandItemView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionBotMoveView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionBotTalkToAvatarView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionBotTalkView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionBotTeleportView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionCallAnotherStackView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionChaseView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionChatView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionFleeView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionGiveRewardView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionGiveScoreToPredefinedTeamView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionGiveScoreView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionJoinTeamView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionKickFromRoomView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionLayoutView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionLeaveTeamView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionMoveAndRotateFurniView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionMoveFurniToView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionMoveFurniView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionMuteUserView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionResetView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionSetFurniStateToView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionTeleportView.tsx delete mode 100644 src/components/wired/views/actions/WiredActionToggleFurniStateView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionActorHasHandItem.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionActorIsGroupMemberView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionActorIsOnFurniView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionActorIsTeamMemberView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionActorIsWearingBadgeView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionActorIsWearingEffectView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionBaseView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionDateRangeView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionFurniHasAvatarOnView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionFurniHasFurniOnView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionFurniHasNotFurniOnView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionFurniIsOfTypeView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionFurniMatchesSnapshotView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionLayoutView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionTimeElapsedLessView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionTimeElapsedMoreView.tsx delete mode 100644 src/components/wired/views/conditions/WiredConditionUserCountInRoomView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerAvatarEnterRoomView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerAvatarSaysSomethingView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerAvatarWalksOffFurniView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerAvatarWalksOnFurni.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerBaseView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerBotReachedAvatarView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerBotReachedStuffView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerCollisionView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerExecuteOnceView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerExecutePeriodicallyLongView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerExecutePeriodicallyView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerGameEndsView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerGameStartsView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerLayoutView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerScoreAchievedView.tsx delete mode 100644 src/components/wired/views/triggers/WiredTriggerToggleFurniView.tsx delete mode 100644 src/events/catalog/CatalogEvent.ts delete mode 100644 src/events/catalog/CatalogInitGiftEvent.ts delete mode 100644 src/events/catalog/CatalogPostMarketplaceOfferEvent.ts delete mode 100644 src/events/catalog/CatalogPurchaseFailureEvent.ts delete mode 100644 src/events/catalog/CatalogPurchaseNotAllowedEvent.ts delete mode 100644 src/events/catalog/CatalogPurchaseOverrideEvent.ts delete mode 100644 src/events/catalog/CatalogPurchaseSoldOutEvent.ts delete mode 100644 src/events/catalog/CatalogPurchasedEvent.ts delete mode 100644 src/events/catalog/CatalogSetRoomPreviewerStuffDataEvent.ts delete mode 100644 src/events/catalog/CatalogWidgetEvent.ts delete mode 100644 src/events/catalog/SetRoomPreviewerStuffDataEvent.ts delete mode 100644 src/events/catalog/index.ts delete mode 100644 src/events/guide-tool/GuideToolEvent.ts delete mode 100644 src/events/guide-tool/index.ts delete mode 100644 src/events/help/HelpNameChangeEvent.ts delete mode 100644 src/events/help/index.ts delete mode 100644 src/events/index.ts delete mode 100644 src/events/inventory/InventoryFurniAddedEvent.ts delete mode 100644 src/events/inventory/index.ts delete mode 100644 src/events/room-widgets/index.ts delete mode 100644 src/events/room-widgets/thumbnail/RoomWidgetThumbnailEvent.ts delete mode 100644 src/events/room-widgets/thumbnail/index.ts delete mode 100644 src/hooks/UseMountEffect.tsx delete mode 100644 src/hooks/achievements/index.ts delete mode 100644 src/hooks/achievements/useAchievements.ts delete mode 100644 src/hooks/avatar-editor/index.ts delete mode 100644 src/hooks/avatar-editor/useAvatarEditor.ts delete mode 100644 src/hooks/avatar-editor/useFigureData.ts delete mode 100644 src/hooks/camera/index.ts delete mode 100644 src/hooks/camera/useCamera.ts delete mode 100644 src/hooks/catalog/index.ts delete mode 100644 src/hooks/catalog/useCatalog.ts delete mode 100644 src/hooks/catalog/useCatalogPlaceMultipleItems.ts delete mode 100644 src/hooks/catalog/useCatalogSkipPurchaseConfirmation.ts delete mode 100644 src/hooks/chat-history/index.ts delete mode 100644 src/hooks/chat-history/useChatHistory.ts delete mode 100644 src/hooks/events/index.ts delete mode 100644 src/hooks/events/useEventDispatcher.tsx delete mode 100644 src/hooks/events/useMessageEvent.tsx delete mode 100644 src/hooks/events/useNitroEvent.tsx delete mode 100644 src/hooks/events/useUiEvent.tsx delete mode 100644 src/hooks/friends/index.ts delete mode 100644 src/hooks/friends/useFriends.ts delete mode 100644 src/hooks/friends/useMessenger.ts delete mode 100644 src/hooks/game-center/index.ts delete mode 100644 src/hooks/game-center/useGameCenter.ts delete mode 100644 src/hooks/groups/index.ts delete mode 100644 src/hooks/groups/useGroup.ts delete mode 100644 src/hooks/help/index.ts delete mode 100644 src/hooks/help/useHelp.ts delete mode 100644 src/hooks/index.ts delete mode 100644 src/hooks/inventory/index.ts delete mode 100644 src/hooks/inventory/useInventoryBadges.ts delete mode 100644 src/hooks/inventory/useInventoryBots.ts delete mode 100644 src/hooks/inventory/useInventoryFurni.ts delete mode 100644 src/hooks/inventory/useInventoryPets.ts delete mode 100644 src/hooks/inventory/useInventoryTrade.ts delete mode 100644 src/hooks/inventory/useInventoryUnseenTracker.ts delete mode 100644 src/hooks/mod-tools/index.ts delete mode 100644 src/hooks/mod-tools/useModTools.ts delete mode 100644 src/hooks/navigator/index.ts delete mode 100644 src/hooks/navigator/useNavigator.ts delete mode 100644 src/hooks/notification/index.ts delete mode 100644 src/hooks/notification/useNotification.ts delete mode 100644 src/hooks/purse/index.ts delete mode 100644 src/hooks/purse/usePurse.ts delete mode 100644 src/hooks/rooms/engine/index.ts delete mode 100644 src/hooks/rooms/engine/useFurniAddedEvent.ts delete mode 100644 src/hooks/rooms/engine/useFurniRemovedEvent.ts delete mode 100644 src/hooks/rooms/engine/useObjectDeselectedEvent.ts delete mode 100644 src/hooks/rooms/engine/useObjectDoubleClickedEvent.ts delete mode 100644 src/hooks/rooms/engine/useObjectRollOutEvent.ts delete mode 100644 src/hooks/rooms/engine/useObjectRollOverEvent.ts delete mode 100644 src/hooks/rooms/engine/useObjectSelectedEvent.ts delete mode 100644 src/hooks/rooms/engine/useUserAddedEvent.ts delete mode 100644 src/hooks/rooms/engine/useUserRemovedEvent.ts delete mode 100644 src/hooks/rooms/index.ts delete mode 100644 src/hooks/rooms/promotes/index.ts delete mode 100644 src/hooks/rooms/promotes/useRoomPromote.ts delete mode 100644 src/hooks/rooms/useRoom.ts delete mode 100644 src/hooks/rooms/widgets/furniture/index.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureBackgroundColorWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureBadgeDisplayWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureContextMenuWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureCraftingWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureDimmerWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureExchangeWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureExternalImageWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureFriendFurniWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureHighScoreWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureInternalLinkWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureMannequinWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurniturePlaylistEditorWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurniturePresentWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureRoomLinkWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureSpamWallPostItWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureStackHeightWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureStickieWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureTrophyWidget.ts delete mode 100644 src/hooks/rooms/widgets/furniture/useFurnitureYoutubeWidget.ts delete mode 100644 src/hooks/rooms/widgets/index.ts delete mode 100644 src/hooks/rooms/widgets/useAvatarInfoWidget.ts delete mode 100644 src/hooks/rooms/widgets/useChatInputWidget.ts delete mode 100644 src/hooks/rooms/widgets/useChatWidget.ts delete mode 100644 src/hooks/rooms/widgets/useDoorbellWidget.ts delete mode 100644 src/hooks/rooms/widgets/useFilterWordsWidget.ts delete mode 100644 src/hooks/rooms/widgets/useFriendRequestWidget.ts delete mode 100644 src/hooks/rooms/widgets/useFurniChooserWidget.ts delete mode 100644 src/hooks/rooms/widgets/usePetPackageWidget.ts delete mode 100644 src/hooks/rooms/widgets/usePollWidget.ts delete mode 100644 src/hooks/rooms/widgets/useUserChooserWidget.ts delete mode 100644 src/hooks/rooms/widgets/useWordQuizWidget.ts delete mode 100644 src/hooks/session/index.ts delete mode 100644 src/hooks/session/useSessionInfo.ts delete mode 100644 src/hooks/useLocalStorage.ts delete mode 100644 src/hooks/useSharedVisibility.ts delete mode 100644 src/hooks/wired/index.ts delete mode 100644 src/hooks/wired/useWired.ts delete mode 100644 src/index.scss create mode 100644 src/index.ts delete mode 100644 src/index.tsx create mode 100644 src/pixi-proxy/NitroAdjustmentFilter.ts create mode 100644 src/pixi-proxy/NitroAlphaFilter.ts create mode 100644 src/pixi-proxy/NitroContainer.ts create mode 100644 src/pixi-proxy/NitroFilter.ts create mode 100644 src/pixi-proxy/NitroRectangle.ts create mode 100644 src/pixi-proxy/NitroRenderTexture.ts create mode 100644 src/pixi-proxy/NitroSprite.ts create mode 100644 src/pixi-proxy/NitroTexture.ts create mode 100644 src/pixi-proxy/NitroTicker.ts create mode 100644 src/pixi-proxy/index.ts delete mode 100644 src/react-app-env.d.ts delete mode 100644 src/workers/IntervalWebWorker.ts delete mode 100644 src/workers/WorkerBuilder.ts create mode 100644 vite.config.js delete mode 100644 vite.config.mjs diff --git a/.browserslistrc b/.browserslistrc index 3e5809a..c529e38 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -1,11 +1,12 @@ # 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 + # You can see what browsers were selected by your queries by running: # npx browserslist last 1 Chrome version last 1 Firefox version -last 1 Edge major versions +last 2 Edge major versions last 2 Safari major versions last 2 iOS major versions diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0792692 --- /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 deleted file mode 100644 index 695c05d..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module", - "ecmaFeatures": { - "jsx": true - } - }, - "settings": { - "react": { - "pragma": "React", - "version": "18.0.0" - } - }, - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "plugin:react/recommended", - "plugin:react/jsx-runtime", - "plugin:react-hooks/recommended" - ], - "plugins": [ - "@typescript-eslint", - "react" - ], - "rules": { - "linebreak-style": [ - "off" - ], - "quotes": [ - "error", - "single" - ], - "@typescript-eslint/indent": [ - "error", - 4, - { - "SwitchCase": 1 - } - ], - "array-bracket-spacing": [ - "error", - "always" - ], - "brace-style": [ - "error", - "allman" - ], - "template-curly-spacing": [ - "error", - "always" - ], - "no-multi-spaces": [ - "error" - ], - "@typescript-eslint/object-curly-spacing": [ - "error", - "always", - { - "arraysInObjects": true, - "objectsInObjects": false - } - ], - "@typescript-eslint/ban-types": [ - "error", - { - "types": { - "String": true, - "Boolean": true, - "Number": true, - "Symbol": true, - "{}": false, - "Object": false, - "object": false, - "Function": false - }, - "extendDefaults": true - } - ], - "no-switch-case-fall-through": [ - "off" - ], - "jsx-quotes": [ - "error" - ], - "react/prop-types": [ - "off" - ], - "react/jsx-curly-spacing": [ - "error", - { - "when": "always", - "children": true - } - ], - "react/jsx-equals-spacing": [ - "error" - ], - "react/jsx-newline": [ - "error", - { - "prevent": true - } - ] - } -} diff --git a/.gitignore b/.gitignore index 154341f..1413af9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,20 @@ +# 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 @@ -9,23 +22,30 @@ *.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 -*.log +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings .git + +# System Files .DS_Store Thumbs.db -# Nitro -/build *.zip -.env -public/renderer-config* -public/ui-config* +*.as +*.bin diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /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/README.md b/README.md index 7b6ffc1..33c4b6b 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,17 @@ -# Nitro React v2.1 +# Nitro Renderer -## Prerequisites - -- [Git](https://git-scm.com/) -- [NodeJS](https://nodejs.org/) >= 18 - - If using NodeJS < 18 remove `--openssl-legacy-provider` from the package.json scripts -- [Yarn](https://yarnpkg.com/) `npm i yarn -g` +nitro-renderer is a Javascript library for rendering Nitro in the browser using PixiJS ## Installation -- First you should open terminal and navigate to the folder where you want to clone Nitro -- Clone Nitro - - `git clone https://git.krews.org/nitro/nitro-react.git` -- Install the dependencies - - `yarn install` - - This may take some time, please be patient -- Rename a few files - - Rename `public/renderer-config.json.example` to `public/renderer-config.json` - - Rename `public/ui-config.json.example` to `public/ui-config.json` -- Set your links - - Open `public/renderer-config.json` - - Update `socket.url, asset.url, image.library.url, & hof.furni.url` - - Open `public/ui-config.json` - - Update `camera.url, thumbnails.url, url.prefix, habbopages.url` - - You can override any variable by passing it to `NitroConfig` in the index.html - -## Usage - -- To use Nitro you need `.nitro` assets generated, see [nitro-converter](https://git.krews.org/nitro/nitro-converter) for instructions -- See [Morningstar Websockets](https://git.krews.org/nitro/ms-websockets) for instructions on configuring websockets on your server - -### Development - -Run Nitro in development mode when you are editing the files, this way you can see the changes in your browser instantly +npm ``` -yarn start +npm install @nitrots/nitro-renderer ``` -### Production - -To build a production version of Nitro just run the following command +yarn ``` -yarn build:prod +yarn add @nitrots/nitro-renderer ``` - -- A `dist` folder will be generated, these are the files that must be uploaded to your webserver -- Consult your CMS documentation for compatibility with Nitro and how to add the production files diff --git a/index.html b/index.html deleted file mode 100644 index 18b1a79..0000000 --- a/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - Nitro - - - -
- - - - diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/package.json b/package.json index 4910ee8..6a0b294 100644 --- a/package.json +++ b/package.json @@ -1,39 +1,45 @@ { - "name": "nitro-react", - "version": "2.2", - "homepage": ".", + "name": "@nitrots/nitro-renderer", + "description": "Javascript library for rendering Nitro in the browser using PixiJS", + "version": "2.0.0", "private": true, - "scripts": { - "start": "vite", - "build": "vite build", - "build:prod": "npx browserslist@latest --update-db && yarn build", - "eslint": "eslint src --ext .ts,.tsx" + "type": "module", + "workspaces": [ + "packages/*" + ], + "publishConfig": { + "access": "public" }, + "repository": { + "type": "git", + "url": "https://github.com/billsonnn/nitro-renderer.git" + }, + "license": "GPL-3.0", + "bugs": { + "url": "https://github.com/billsonnn/nitro-renderer/issues" + }, + "homepage": "https://github.com/billsonnn/nitro-renderer", + "scripts": { + "build": "vite build", + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", "dependencies": { - "@tanstack/react-virtual": "3.2.0", - "react": "^18.2.0", - "react-bootstrap": "^2.2.2", - "react-dom": "^18.2.0", - "react-icons": "^5.0.1", - "react-slider": "^2.0.6", - "react-youtube": "^7.13.1", - "use-between": "^1.3.5" + "howler": "^2.2.4", + "pako": "^2.1.0", + "pixi-filters": "^6.0.0", + "pixi.js": "~8.0.4" }, "devDependencies": { - "@types/node": "^20.11.30", - "@types/react": "^18.2.67", - "@types/react-dom": "^18.2.22", - "@types/react-slider": "^1.3.6", - "@typescript-eslint/eslint-plugin": "^7.3.1", - "@typescript-eslint/parser": "^7.3.1", - "@vitejs/plugin-react": "^4.2.1", + "@rollup/plugin-typescript": "^11.1.6", + "@types/howler": "^2.2.11", + "@types/pako": "^2.0.3", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", "eslint": "^8.57.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsx-a11y": "^6.8.0", - "eslint-plugin-react": "^7.34.1", - "eslint-plugin-react-hooks": "^4.6.0", - "sass": "^1.72.0", - "typescript": "^5.4.2", - "vite": "^5.1.6" + "tslib": "^2.3.1", + "typescript": "~5.4.2", + "vite": "^5.1.3" } } diff --git a/packages/api/.gitignore b/packages/api/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/api/.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/packages/api/index.ts b/packages/api/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/api/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/api/package.json b/packages/api/package.json new file mode 100644 index 0000000..6539872 --- /dev/null +++ b/packages/api/package.json @@ -0,0 +1,22 @@ +{ + "name": "@nitrots/api", + "description": "Nitro api module", + "version": "1.0.0", + "type": "module", + "publishConfig": { + "access": "public" + }, + "license": "GPL-3.0", + "scripts": { + "build": "vite build", + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "pixi.js": "^8.0.4" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/api/src/asset/IAsset.ts b/packages/api/src/asset/IAsset.ts new file mode 100644 index 0000000..f4e4fb4 --- /dev/null +++ b/packages/api/src/asset/IAsset.ts @@ -0,0 +1,9 @@ +export interface IAsset +{ + source?: string; + x?: number; + y?: number; + flipH?: boolean; + flipV?: boolean; + usesPalette?: boolean; +} diff --git a/packages/api/src/asset/IAssetAlias.ts b/packages/api/src/asset/IAssetAlias.ts new file mode 100644 index 0000000..5c14027 --- /dev/null +++ b/packages/api/src/asset/IAssetAlias.ts @@ -0,0 +1,6 @@ +export interface IAssetAlias +{ + link?: string; + flipH?: boolean; + flipV?: boolean; +} diff --git a/packages/api/src/asset/IAssetData.ts b/packages/api/src/asset/IAssetData.ts new file mode 100644 index 0000000..f12820f --- /dev/null +++ b/packages/api/src/asset/IAssetData.ts @@ -0,0 +1,23 @@ +import { IAssetAnimation } from './animation'; +import { IAsset } from './IAsset'; +import { IAssetAlias } from './IAssetAlias'; +import { IAssetPalette } from './IAssetPalette'; +import { IAssetLogicData } from './logic'; +import { IAssetRoomVisualizationData } from './room-visualization'; +import { ISpritesheetData } from './spritesheet'; +import { IAssetVisualizationData } from './visualization'; + +export interface IAssetData { + type?: string; + name?: string; + visualizationType?: string; + logicType?: string; + spritesheet?: ISpritesheetData; + logic?: IAssetLogicData; + assets?: { [index: string]: IAsset }; + aliases?: { [index: string]: IAssetAlias }; + animations?: { [index: string]: IAssetAnimation }; + palettes?: { [index: string]: IAssetPalette }; + visualizations?: IAssetVisualizationData[]; + roomVisualization?: IAssetRoomVisualizationData; +} diff --git a/packages/api/src/asset/IAssetManager.ts b/packages/api/src/asset/IAssetManager.ts new file mode 100644 index 0000000..6457e28 --- /dev/null +++ b/packages/api/src/asset/IAssetManager.ts @@ -0,0 +1,18 @@ + +import { Spritesheet, Texture } from 'pixi.js'; +import { IAssetData } from './IAssetData'; +import { IGraphicAsset } from './IGraphicAsset'; +import { IGraphicAssetCollection } from './IGraphicAssetCollection'; + +export interface IAssetManager +{ + getTexture(name: string): Texture; + setTexture(name: string, texture: Texture): void; + addAssetToCollection(collectionName: string, assetName: string, texture: Texture, override?: boolean): boolean; + getAsset(name: string): IGraphicAsset; + getCollection(name: string): IGraphicAssetCollection; + createCollection(data: IAssetData, spritesheet: Spritesheet): IGraphicAssetCollection; + downloadAssets(urls: string[]): Promise; + downloadAsset(url: string): Promise; + readonly collections: Map; +} diff --git a/packages/api/src/asset/IAssetPalette.ts b/packages/api/src/asset/IAssetPalette.ts new file mode 100644 index 0000000..9b0384b --- /dev/null +++ b/packages/api/src/asset/IAssetPalette.ts @@ -0,0 +1,12 @@ +export interface IAssetPalette +{ + id?: number; + source?: string; + master?: boolean; + tags?: string[]; + breed?: number; + colorTag?: number; + color1?: string; + color2?: string; + rgb?: [ number, number, number ][]; +} diff --git a/packages/api/src/asset/IGraphicAsset.ts b/packages/api/src/asset/IGraphicAsset.ts new file mode 100644 index 0000000..620a115 --- /dev/null +++ b/packages/api/src/asset/IGraphicAsset.ts @@ -0,0 +1,19 @@ +import { Rectangle, Texture } from 'pixi.js'; + +export interface IGraphicAsset +{ + recycle(): void; + readonly name: string; + readonly source: string; + readonly texture: Texture; + readonly usesPalette: boolean; + readonly x: number; + readonly y: number; + readonly width: number; + readonly height: number; + readonly offsetX: number; + readonly offsetY: number; + readonly flipH: boolean; + readonly flipV: boolean; + readonly rectangle: Rectangle; +} diff --git a/packages/api/src/asset/IGraphicAssetCollection.ts b/packages/api/src/asset/IGraphicAssetCollection.ts new file mode 100644 index 0000000..40a513b --- /dev/null +++ b/packages/api/src/asset/IGraphicAssetCollection.ts @@ -0,0 +1,24 @@ +import { Texture, TextureSource } from 'pixi.js'; +import { IAssetData } from './IAssetData'; +import { IGraphicAsset } from './IGraphicAsset'; +import { IGraphicAssetPalette } from './IGraphicAssetPalette'; + +export interface IGraphicAssetCollection +{ + dispose(): void; + addReference(): void; + removeReference(): void; + define(data: IAssetData): void; + getAsset(name: string): IGraphicAsset; + getAssetWithPalette(name: string, paletteName: string): IGraphicAsset; + getTexture(name: string): Texture; + getPaletteNames(): string[]; + getPaletteColors(paletteName: string): number[]; + getPalette(name: string): IGraphicAssetPalette; + addAsset(name: string, texture: Texture, override: boolean, x?: number, y?: number, flipH?: boolean, flipV?: boolean): boolean; + disposeAsset(name: string): void; + referenceCount: number; + name: string; + textureSource: TextureSource; + data: IAssetData; +} diff --git a/packages/api/src/asset/IGraphicAssetPalette.ts b/packages/api/src/asset/IGraphicAssetPalette.ts new file mode 100644 index 0000000..cf4a8f5 --- /dev/null +++ b/packages/api/src/asset/IGraphicAssetPalette.ts @@ -0,0 +1,8 @@ +import { Texture } from 'pixi.js'; + +export interface IGraphicAssetPalette +{ + applyPalette(texture: Texture): Texture; + primaryColor: number; + secondaryColor: number; +} diff --git a/packages/api/src/asset/animation/IAssetAnimation.ts b/packages/api/src/asset/animation/IAssetAnimation.ts new file mode 100644 index 0000000..b35e0eb --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/animation/IAssetAnimationAdd.ts b/packages/api/src/asset/animation/IAssetAnimationAdd.ts new file mode 100644 index 0000000..3da37c6 --- /dev/null +++ b/packages/api/src/asset/animation/IAssetAnimationAdd.ts @@ -0,0 +1,8 @@ +export interface IAssetAnimationAdd +{ + id?: string; + align?: string; + blend?: string; + ink?: number; + base?: string; +} diff --git a/packages/api/src/asset/animation/IAssetAnimationAvatar.ts b/packages/api/src/asset/animation/IAssetAnimationAvatar.ts new file mode 100644 index 0000000..dcd030e --- /dev/null +++ b/packages/api/src/asset/animation/IAssetAnimationAvatar.ts @@ -0,0 +1,6 @@ +export interface IAssetAnimationAvatar +{ + ink?: number; + foreground?: string; + background?: string; +} diff --git a/packages/api/src/asset/animation/IAssetAnimationDirection.ts b/packages/api/src/asset/animation/IAssetAnimationDirection.ts new file mode 100644 index 0000000..0c18eae --- /dev/null +++ b/packages/api/src/asset/animation/IAssetAnimationDirection.ts @@ -0,0 +1,4 @@ +export interface IAssetAnimationDirection +{ + offset?: number; +} diff --git a/packages/api/src/asset/animation/IAssetAnimationFrame.ts b/packages/api/src/asset/animation/IAssetAnimationFrame.ts new file mode 100644 index 0000000..b8b88a0 --- /dev/null +++ b/packages/api/src/asset/animation/IAssetAnimationFrame.ts @@ -0,0 +1,8 @@ +import { IAssetAnimationFramePart } from './IAssetAnimationFramePart'; + +export interface IAssetAnimationFrame +{ + repeats?: number; + fxs?: IAssetAnimationFramePart[]; + bodyparts?: IAssetAnimationFramePart[]; +} diff --git a/packages/api/src/asset/animation/IAssetAnimationFramePart.ts b/packages/api/src/asset/animation/IAssetAnimationFramePart.ts new file mode 100644 index 0000000..ac8c093 --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/animation/IAssetAnimationFramePartItem.ts b/packages/api/src/asset/animation/IAssetAnimationFramePartItem.ts new file mode 100644 index 0000000..45a7642 --- /dev/null +++ b/packages/api/src/asset/animation/IAssetAnimationFramePartItem.ts @@ -0,0 +1,5 @@ +export interface IAssetAnimationFramePartItem +{ + id?: string; + base?: string; +} diff --git a/packages/api/src/asset/animation/IAssetAnimationOverride.ts b/packages/api/src/asset/animation/IAssetAnimationOverride.ts new file mode 100644 index 0000000..3d56833 --- /dev/null +++ b/packages/api/src/asset/animation/IAssetAnimationOverride.ts @@ -0,0 +1,8 @@ +import { IAssetAnimationFrame } from './IAssetAnimationFrame'; + +export interface IAssetAnimationOverride +{ + name?: string; + override?: string; + frames?: IAssetAnimationFrame[]; +} diff --git a/packages/api/src/asset/animation/IAssetAnimationRemove.ts b/packages/api/src/asset/animation/IAssetAnimationRemove.ts new file mode 100644 index 0000000..ac65fb5 --- /dev/null +++ b/packages/api/src/asset/animation/IAssetAnimationRemove.ts @@ -0,0 +1,4 @@ +export interface IAssetAnimationRemove +{ + id?: string; +} diff --git a/packages/api/src/asset/animation/IAssetAnimationShadow.ts b/packages/api/src/asset/animation/IAssetAnimationShadow.ts new file mode 100644 index 0000000..dfe22a8 --- /dev/null +++ b/packages/api/src/asset/animation/IAssetAnimationShadow.ts @@ -0,0 +1,4 @@ +export interface IAssetAnimationShadow +{ + id?: string; +} diff --git a/packages/api/src/asset/animation/IAssetAnimationSprite.ts b/packages/api/src/asset/animation/IAssetAnimationSprite.ts new file mode 100644 index 0000000..afc7b05 --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/animation/IAssetAnimationSpriteDirection.ts b/packages/api/src/asset/animation/IAssetAnimationSpriteDirection.ts new file mode 100644 index 0000000..746719d --- /dev/null +++ b/packages/api/src/asset/animation/IAssetAnimationSpriteDirection.ts @@ -0,0 +1,7 @@ +export interface IAssetAnimationSpriteDirection +{ + id?: number; + dx?: number; + dy?: number; + dz?: number; +} diff --git a/packages/api/src/asset/animation/index.ts b/packages/api/src/asset/animation/index.ts new file mode 100644 index 0000000..56543d0 --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/index.ts b/packages/api/src/asset/index.ts new file mode 100644 index 0000000..1211968 --- /dev/null +++ b/packages/api/src/asset/index.ts @@ -0,0 +1,19 @@ +export * from './IAsset'; +export * from './IAssetAlias'; +export * from './IAssetData'; +export * from './IAssetManager'; +export * from './IAssetPalette'; +export * from './IGraphicAsset'; +export * from './IGraphicAssetCollection'; +export * from './IGraphicAssetPalette'; +export * from './animation'; +export * from './logic'; +export * from './logic/model'; +export * from './logic/particlesystem'; +export * from './room-visualization'; +export * from './spritesheet'; +export * from './visualization'; +export * from './visualization/animation'; +export * from './visualization/color'; +export * from './visualization/gestures'; +export * from './visualization/postures'; diff --git a/packages/api/src/asset/logic/IAssetLogicCustomVars.ts b/packages/api/src/asset/logic/IAssetLogicCustomVars.ts new file mode 100644 index 0000000..1ebd4a8 --- /dev/null +++ b/packages/api/src/asset/logic/IAssetLogicCustomVars.ts @@ -0,0 +1,4 @@ +export interface ICustomVars +{ + variables?: string[]; +} diff --git a/packages/api/src/asset/logic/IAssetLogicData.ts b/packages/api/src/asset/logic/IAssetLogicData.ts new file mode 100644 index 0000000..acf484c --- /dev/null +++ b/packages/api/src/asset/logic/IAssetLogicData.ts @@ -0,0 +1,17 @@ +import { ICustomVars } from './IAssetLogicCustomVars'; +import { IAssetLogicPlanetSystem } from './IAssetLogicPlanetSystem'; +import { ISoundSample } from './ISoundSample'; +import { IAssetLogicModel } from './model/IAssetLogicModel'; +import { IParticleSystem } from './particlesystem'; + +export interface IAssetLogicData +{ + model?: IAssetLogicModel; + maskType?: string; + credits?: string; + soundSample?: ISoundSample; + action?: { link?: string, startState?: number }; + planetSystems?: IAssetLogicPlanetSystem[]; + particleSystems?: IParticleSystem[]; + customVars?: ICustomVars; +} diff --git a/packages/api/src/asset/logic/IAssetLogicPlanetSystem.ts b/packages/api/src/asset/logic/IAssetLogicPlanetSystem.ts new file mode 100644 index 0000000..47521bc --- /dev/null +++ b/packages/api/src/asset/logic/IAssetLogicPlanetSystem.ts @@ -0,0 +1,11 @@ +export interface IAssetLogicPlanetSystem +{ + id?: number; + name?: string; + parent?: string; + radius?: number; + arcSpeed?: number; + arcOffset?: number; + blend?: number; + height?: number; +} diff --git a/packages/api/src/asset/logic/ISoundSample.ts b/packages/api/src/asset/logic/ISoundSample.ts new file mode 100644 index 0000000..003f9f6 --- /dev/null +++ b/packages/api/src/asset/logic/ISoundSample.ts @@ -0,0 +1,5 @@ +export interface ISoundSample +{ + id?: number; + noPitch?: boolean; +} diff --git a/packages/api/src/asset/logic/index.ts b/packages/api/src/asset/logic/index.ts new file mode 100644 index 0000000..569907b --- /dev/null +++ b/packages/api/src/asset/logic/index.ts @@ -0,0 +1,6 @@ +export * from './IAssetLogicCustomVars'; +export * from './IAssetLogicData'; +export * from './IAssetLogicPlanetSystem'; +export * from './ISoundSample'; +export * from './model'; +export * from './particlesystem'; diff --git a/packages/api/src/asset/logic/model/IAssetDimension.ts b/packages/api/src/asset/logic/model/IAssetDimension.ts new file mode 100644 index 0000000..4a4629f --- /dev/null +++ b/packages/api/src/asset/logic/model/IAssetDimension.ts @@ -0,0 +1,6 @@ +export interface IAssetDimension +{ + x: number; + y: number; + z?: number; +} \ No newline at end of file diff --git a/packages/api/src/asset/logic/model/IAssetLogicModel.ts b/packages/api/src/asset/logic/model/IAssetLogicModel.ts new file mode 100644 index 0000000..eef3245 --- /dev/null +++ b/packages/api/src/asset/logic/model/IAssetLogicModel.ts @@ -0,0 +1,7 @@ +import { IAssetDimension } from './IAssetDimension'; + +export interface IAssetLogicModel +{ + dimensions?: IAssetDimension; + directions?: number[]; +} diff --git a/packages/api/src/asset/logic/model/index.ts b/packages/api/src/asset/logic/model/index.ts new file mode 100644 index 0000000..4d08a72 --- /dev/null +++ b/packages/api/src/asset/logic/model/index.ts @@ -0,0 +1,2 @@ +export * from './IAssetDimension'; +export * from './IAssetLogicModel'; diff --git a/packages/api/src/asset/logic/particlesystem/IParticleSystem.ts b/packages/api/src/asset/logic/particlesystem/IParticleSystem.ts new file mode 100644 index 0000000..871f5f3 --- /dev/null +++ b/packages/api/src/asset/logic/particlesystem/IParticleSystem.ts @@ -0,0 +1,11 @@ +import { IParticleSystemEmitter } from './IParticleSystemEmitter'; + +export interface IParticleSystem +{ + size?: number; + canvasId?: number; + offsetY?: number; + blend?: number; + bgColor?: string; + emitters?: IParticleSystemEmitter[]; +} diff --git a/packages/api/src/asset/logic/particlesystem/IParticleSystemEmitter.ts b/packages/api/src/asset/logic/particlesystem/IParticleSystemEmitter.ts new file mode 100644 index 0000000..fa175e2 --- /dev/null +++ b/packages/api/src/asset/logic/particlesystem/IParticleSystemEmitter.ts @@ -0,0 +1,15 @@ +import { IParticleSystemParticle } from './IParticleSystemParticle'; +import { IParticleSystemSimulation } from './IParticleSystemSimulation'; + +export interface IParticleSystemEmitter +{ + id?: number; + name?: string; + spriteId?: number; + maxNumParticles?: number; + particlesPerFrame?: number; + burstPulse?: number; + fuseTime?: number; + simulation?: IParticleSystemSimulation; + particles?: IParticleSystemParticle[]; +} diff --git a/packages/api/src/asset/logic/particlesystem/IParticleSystemParticle.ts b/packages/api/src/asset/logic/particlesystem/IParticleSystemParticle.ts new file mode 100644 index 0000000..99281fa --- /dev/null +++ b/packages/api/src/asset/logic/particlesystem/IParticleSystemParticle.ts @@ -0,0 +1,7 @@ +export interface IParticleSystemParticle +{ + isEmitter?: boolean; + lifeTime?: number; + fade?: boolean; + frames?: string[]; +} diff --git a/packages/api/src/asset/logic/particlesystem/IParticleSystemSimulation.ts b/packages/api/src/asset/logic/particlesystem/IParticleSystemSimulation.ts new file mode 100644 index 0000000..fef400c --- /dev/null +++ b/packages/api/src/asset/logic/particlesystem/IParticleSystemSimulation.ts @@ -0,0 +1,9 @@ +export interface IParticleSystemSimulation +{ + force?: number; + direction?: number; + gravity?: number; + airFriction?: number; + shape?: string; + energy?: number; +} diff --git a/packages/api/src/asset/logic/particlesystem/index.ts b/packages/api/src/asset/logic/particlesystem/index.ts new file mode 100644 index 0000000..428f6fc --- /dev/null +++ b/packages/api/src/asset/logic/particlesystem/index.ts @@ -0,0 +1,4 @@ +export * from './IParticleSystem'; +export * from './IParticleSystemEmitter'; +export * from './IParticleSystemParticle'; +export * from './IParticleSystemSimulation'; diff --git a/packages/api/src/asset/room-visualization/IAssetPlane.ts b/packages/api/src/asset/room-visualization/IAssetPlane.ts new file mode 100644 index 0000000..6007641 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlane.ts @@ -0,0 +1,8 @@ +import { IAssetPlaneVisualization } from './IAssetPlaneVisualization'; + +export interface IAssetPlane +{ + id?: string; + visualizations?: IAssetPlaneVisualization[]; + animatedVisualization?: IAssetPlaneVisualization[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneMask.ts b/packages/api/src/asset/room-visualization/IAssetPlaneMask.ts new file mode 100644 index 0000000..0fd8465 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneMask.ts @@ -0,0 +1,7 @@ +import { IAssetPlaneMaskVisualization } from './IAssetPlaneMaskVisualization'; + +export interface IAssetPlaneMask +{ + id?: string; + visualizations?: IAssetPlaneMaskVisualization[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneMaskData.ts b/packages/api/src/asset/room-visualization/IAssetPlaneMaskData.ts new file mode 100644 index 0000000..2767b59 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneMaskData.ts @@ -0,0 +1,6 @@ +import { IAssetPlaneMask } from './IAssetPlaneMask'; + +export interface IAssetPlaneMaskData +{ + masks?: IAssetPlaneMask[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneMaskVisualization.ts b/packages/api/src/asset/room-visualization/IAssetPlaneMaskVisualization.ts new file mode 100644 index 0000000..66c5ae8 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneMaskVisualization.ts @@ -0,0 +1,7 @@ +import { IAssetPlaneTextureBitmap } from './IAssetPlaneTextureBitmap'; + +export interface IAssetPlaneMaskVisualization +{ + size?: number; + bitmaps?: IAssetPlaneTextureBitmap[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneMaterial.ts b/packages/api/src/asset/room-visualization/IAssetPlaneMaterial.ts new file mode 100644 index 0000000..59ae007 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneMaterial.ts @@ -0,0 +1,7 @@ +import { IAssetPlaneMaterialCellMatrix } from './IAssetPlaneMaterialCellMatrix'; + +export interface IAssetPlaneMaterial +{ + id?: string; + matrices?: IAssetPlaneMaterialCellMatrix[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCell.ts b/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCell.ts new file mode 100644 index 0000000..fafae27 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCell.ts @@ -0,0 +1,7 @@ +import { IAssetPlaneMaterialCellExtraItemData } from './IAssetPlaneMaterialCellExtraItemData'; + +export interface IAssetPlaneMaterialCell +{ + textureId?: string; + extraData?: IAssetPlaneMaterialCellExtraItemData; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellColumn.ts b/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellColumn.ts new file mode 100644 index 0000000..d2b36d3 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellColumn.ts @@ -0,0 +1,8 @@ +import { IAssetPlaneMaterialCell } from './IAssetPlaneMaterialCell'; + +export interface IAssetPlaneMaterialCellColumn +{ + repeatMode?: string; + width?: number; + cells?: IAssetPlaneMaterialCell[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellExtraItemData.ts b/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellExtraItemData.ts new file mode 100644 index 0000000..a49833f --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellExtraItemData.ts @@ -0,0 +1,6 @@ +export interface IAssetPlaneMaterialCellExtraItemData +{ + limitMax?: number; + extraItemTypes?: string[]; + offsets?: [number, number][]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellMatrix.ts b/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellMatrix.ts new file mode 100644 index 0000000..526cde2 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneMaterialCellMatrix.ts @@ -0,0 +1,12 @@ +import { IAssetPlaneMaterialCellColumn } from './IAssetPlaneMaterialCellColumn'; + +export interface IAssetPlaneMaterialCellMatrix +{ + repeatMode?: string; + align?: string; + normalMinX?: number; + normalMaxX?: number; + normalMinY?: number; + normalMaxY?: number; + columns?: IAssetPlaneMaterialCellColumn[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneTexture.ts b/packages/api/src/asset/room-visualization/IAssetPlaneTexture.ts new file mode 100644 index 0000000..fff62fa --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneTexture.ts @@ -0,0 +1,7 @@ +import { IAssetPlaneTextureBitmap } from './IAssetPlaneTextureBitmap'; + +export interface IAssetPlaneTexture +{ + id?: string; + bitmaps?: IAssetPlaneTextureBitmap[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneTextureBitmap.ts b/packages/api/src/asset/room-visualization/IAssetPlaneTextureBitmap.ts new file mode 100644 index 0000000..e1af985 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneTextureBitmap.ts @@ -0,0 +1,8 @@ +export interface IAssetPlaneTextureBitmap +{ + assetName?: string; + normalMinX?: number; + normalMaxX?: number; + normalMinY?: number; + normalMaxY?: number; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneVisualization.ts b/packages/api/src/asset/room-visualization/IAssetPlaneVisualization.ts new file mode 100644 index 0000000..db3b4de --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneVisualization.ts @@ -0,0 +1,10 @@ +import { IAssetPlaneVisualizationAnimatedLayer } from './IAssetPlaneVisualizationAnimatedLayer'; +import { IAssetPlaneVisualizationLayer } from './IAssetPlaneVisualizationLayer'; + +export interface IAssetPlaneVisualization +{ + size?: number; + horizontalAngle?: number; + verticalAngle?: number; + allLayers?: (IAssetPlaneVisualizationLayer | IAssetPlaneVisualizationAnimatedLayer)[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationAnimatedLayer.ts b/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationAnimatedLayer.ts new file mode 100644 index 0000000..4cd50c2 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationAnimatedLayer.ts @@ -0,0 +1,6 @@ +import { IAssetPlaneVisualizationAnimatedLayerItem } from './IAssetPlaneVisualizationAnimatedLayerItem'; + +export interface IAssetPlaneVisualizationAnimatedLayer +{ + items?: IAssetPlaneVisualizationAnimatedLayerItem[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationAnimatedLayerItem.ts b/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationAnimatedLayerItem.ts new file mode 100644 index 0000000..9ee426e --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationAnimatedLayerItem.ts @@ -0,0 +1,11 @@ +export interface IAssetPlaneVisualizationAnimatedLayerItem +{ + id?: number; + assetId?: string; + x?: string; + y?: string; + randomX?: string; + randomY?: string; + speedX?: number; + speedY?: number; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationData.ts b/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationData.ts new file mode 100644 index 0000000..4e48d53 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationData.ts @@ -0,0 +1,10 @@ +import { IAssetPlane } from './IAssetPlane'; +import { IAssetPlaneMaterial } from './IAssetPlaneMaterial'; +import { IAssetPlaneTexture } from './IAssetPlaneTexture'; + +export interface IAssetPlaneVisualizationData +{ + planes?: IAssetPlane[]; + materials?: IAssetPlaneMaterial[]; + textures?: IAssetPlaneTexture[]; +} diff --git a/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationLayer.ts b/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationLayer.ts new file mode 100644 index 0000000..e009893 --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetPlaneVisualizationLayer.ts @@ -0,0 +1,7 @@ +export interface IAssetPlaneVisualizationLayer +{ + materialId?: string; + color?: number; + offset?: number; + align?: string; +} diff --git a/packages/api/src/asset/room-visualization/IAssetRoomVisualizationData.ts b/packages/api/src/asset/room-visualization/IAssetRoomVisualizationData.ts new file mode 100644 index 0000000..e82ea8f --- /dev/null +++ b/packages/api/src/asset/room-visualization/IAssetRoomVisualizationData.ts @@ -0,0 +1,10 @@ +import { IAssetPlaneMaskData } from './IAssetPlaneMaskData'; +import { IAssetPlaneVisualizationData } from './IAssetPlaneVisualizationData'; + +export interface IAssetRoomVisualizationData +{ + floorData?: IAssetPlaneVisualizationData; + wallData?: IAssetPlaneVisualizationData; + landscapeData?: IAssetPlaneVisualizationData; + maskData?: IAssetPlaneMaskData; +} diff --git a/packages/api/src/asset/room-visualization/index.ts b/packages/api/src/asset/room-visualization/index.ts new file mode 100644 index 0000000..4d6face --- /dev/null +++ b/packages/api/src/asset/room-visualization/index.ts @@ -0,0 +1,17 @@ +export * from './IAssetPlane'; +export * from './IAssetPlaneMask'; +export * from './IAssetPlaneMaskData'; +export * from './IAssetPlaneMaskVisualization'; +export * from './IAssetPlaneMaterial'; +export * from './IAssetPlaneMaterialCell'; +export * from './IAssetPlaneMaterialCellColumn'; +export * from './IAssetPlaneMaterialCellExtraItemData'; +export * from './IAssetPlaneMaterialCellMatrix'; +export * from './IAssetPlaneTexture'; +export * from './IAssetPlaneTextureBitmap'; +export * from './IAssetPlaneVisualization'; +export * from './IAssetPlaneVisualizationAnimatedLayer'; +export * from './IAssetPlaneVisualizationAnimatedLayerItem'; +export * from './IAssetPlaneVisualizationData'; +export * from './IAssetPlaneVisualizationLayer'; +export * from './IAssetRoomVisualizationData'; diff --git a/packages/api/src/asset/spritesheet/ISpritesheetData.ts b/packages/api/src/asset/spritesheet/ISpritesheetData.ts new file mode 100644 index 0000000..3d96adc --- /dev/null +++ b/packages/api/src/asset/spritesheet/ISpritesheetData.ts @@ -0,0 +1,9 @@ +import { SpritesheetData } from 'pixi.js'; +import { ISpritesheetFrame } from './ISpritesheetFrame'; +import { ISpritesheetMeta } from './ISpritesheetMeta'; + +export interface ISpritesheetData extends SpritesheetData +{ + meta: ISpritesheetMeta; + frames: { [index: string]: ISpritesheetFrame }; +} diff --git a/packages/api/src/asset/spritesheet/ISpritesheetFrame.ts b/packages/api/src/asset/spritesheet/ISpritesheetFrame.ts new file mode 100644 index 0000000..0833b50 --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/spritesheet/ISpritesheetMeta.ts b/packages/api/src/asset/spritesheet/ISpritesheetMeta.ts new file mode 100644 index 0000000..3a74f7b --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/spritesheet/index.ts b/packages/api/src/asset/spritesheet/index.ts new file mode 100644 index 0000000..9c94e8b --- /dev/null +++ b/packages/api/src/asset/spritesheet/index.ts @@ -0,0 +1,3 @@ +export * from './ISpritesheetData'; +export * from './ISpritesheetFrame'; +export * from './ISpritesheetMeta'; diff --git a/packages/api/src/asset/visualization/IAssetVisualizationData.ts b/packages/api/src/asset/visualization/IAssetVisualizationData.ts new file mode 100644 index 0000000..e92f959 --- /dev/null +++ b/packages/api/src/asset/visualization/IAssetVisualizationData.ts @@ -0,0 +1,20 @@ +import { IAssetVisualAnimation } from './animation'; +import { IAssetColor } from './color'; +import { IAssetGesture } from './gestures'; +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 }; + defaultPosture?: string; + postures?: { defaultPosture?: string, postures?: IAssetPosture[] }; + gestures?: IAssetGesture[]; +} diff --git a/packages/api/src/asset/visualization/IAssetVisualizationDirection.ts b/packages/api/src/asset/visualization/IAssetVisualizationDirection.ts new file mode 100644 index 0000000..cc628f1 --- /dev/null +++ b/packages/api/src/asset/visualization/IAssetVisualizationDirection.ts @@ -0,0 +1,6 @@ +import { IAssetVisualizationLayer } from './IAssetVisualizationLayer'; + +export interface IAssetVisualizationDirection +{ + layers?: { [index: string]: IAssetVisualizationLayer }; +} diff --git a/packages/api/src/asset/visualization/IAssetVisualizationLayer.ts b/packages/api/src/asset/visualization/IAssetVisualizationLayer.ts new file mode 100644 index 0000000..61fcf56 --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/visualization/animation/IAssetVisualAnimation.ts b/packages/api/src/asset/visualization/animation/IAssetVisualAnimation.ts new file mode 100644 index 0000000..4e71438 --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/visualization/animation/IAssetVisualAnimationLayer.ts b/packages/api/src/asset/visualization/animation/IAssetVisualAnimationLayer.ts new file mode 100644 index 0000000..2a274ea --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/visualization/animation/IAssetVisualAnimationSequence.ts b/packages/api/src/asset/visualization/animation/IAssetVisualAnimationSequence.ts new file mode 100644 index 0000000..bb25104 --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/visualization/animation/IAssetVisualAnimationSequenceFrame.ts b/packages/api/src/asset/visualization/animation/IAssetVisualAnimationSequenceFrame.ts new file mode 100644 index 0000000..196631e --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/visualization/animation/IAssetVisualAnimationSequenceFrameOffset.ts b/packages/api/src/asset/visualization/animation/IAssetVisualAnimationSequenceFrameOffset.ts new file mode 100644 index 0000000..bc85461 --- /dev/null +++ b/packages/api/src/asset/visualization/animation/IAssetVisualAnimationSequenceFrameOffset.ts @@ -0,0 +1,6 @@ +export interface IAssetVisualAnimationSequenceFrameOffset +{ + direction?: number; + x?: number; + y?: number; +} diff --git a/packages/api/src/asset/visualization/animation/index.ts b/packages/api/src/asset/visualization/animation/index.ts new file mode 100644 index 0000000..19b332c --- /dev/null +++ b/packages/api/src/asset/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/packages/api/src/asset/visualization/color/IAssetColor.ts b/packages/api/src/asset/visualization/color/IAssetColor.ts new file mode 100644 index 0000000..29ebc75 --- /dev/null +++ b/packages/api/src/asset/visualization/color/IAssetColor.ts @@ -0,0 +1,6 @@ +import { IAssetColorLayer } from './IAssetColorLayer'; + +export interface IAssetColor +{ + layers?: { [index: string]: IAssetColorLayer }; +} diff --git a/packages/api/src/asset/visualization/color/IAssetColorLayer.ts b/packages/api/src/asset/visualization/color/IAssetColorLayer.ts new file mode 100644 index 0000000..7a1372e --- /dev/null +++ b/packages/api/src/asset/visualization/color/IAssetColorLayer.ts @@ -0,0 +1,4 @@ +export interface IAssetColorLayer +{ + color?: number; +} diff --git a/packages/api/src/asset/visualization/color/index.ts b/packages/api/src/asset/visualization/color/index.ts new file mode 100644 index 0000000..00aff50 --- /dev/null +++ b/packages/api/src/asset/visualization/color/index.ts @@ -0,0 +1,2 @@ +export * from './IAssetColor'; +export * from './IAssetColorLayer'; diff --git a/packages/api/src/asset/visualization/gestures/IAssetGesture.ts b/packages/api/src/asset/visualization/gestures/IAssetGesture.ts new file mode 100644 index 0000000..ddf3752 --- /dev/null +++ b/packages/api/src/asset/visualization/gestures/IAssetGesture.ts @@ -0,0 +1,5 @@ +export interface IAssetGesture +{ + id?: string; + animationId?: number; +} diff --git a/packages/api/src/asset/visualization/gestures/index.ts b/packages/api/src/asset/visualization/gestures/index.ts new file mode 100644 index 0000000..2c6e978 --- /dev/null +++ b/packages/api/src/asset/visualization/gestures/index.ts @@ -0,0 +1 @@ +export * from './IAssetGesture'; diff --git a/packages/api/src/asset/visualization/index.ts b/packages/api/src/asset/visualization/index.ts new file mode 100644 index 0000000..ec77223 --- /dev/null +++ b/packages/api/src/asset/visualization/index.ts @@ -0,0 +1,7 @@ +export * from './IAssetVisualizationData'; +export * from './IAssetVisualizationDirection'; +export * from './IAssetVisualizationLayer'; +export * from './animation'; +export * from './color'; +export * from './gestures'; +export * from './postures'; diff --git a/packages/api/src/asset/visualization/postures/IAssetPosture.ts b/packages/api/src/asset/visualization/postures/IAssetPosture.ts new file mode 100644 index 0000000..3313851 --- /dev/null +++ b/packages/api/src/asset/visualization/postures/IAssetPosture.ts @@ -0,0 +1,5 @@ +export interface IAssetPosture +{ + id?: string; + animationId?: number; +} diff --git a/packages/api/src/asset/visualization/postures/index.ts b/packages/api/src/asset/visualization/postures/index.ts new file mode 100644 index 0000000..c24c1b9 --- /dev/null +++ b/packages/api/src/asset/visualization/postures/index.ts @@ -0,0 +1 @@ +export * from './IAssetPosture'; diff --git a/packages/api/src/common/IDisposable.ts b/packages/api/src/common/IDisposable.ts new file mode 100644 index 0000000..b9f6040 --- /dev/null +++ b/packages/api/src/common/IDisposable.ts @@ -0,0 +1,5 @@ +export interface IDisposable +{ + dispose(): void; + disposed: boolean; +} \ No newline at end of file diff --git a/packages/api/src/common/IEventDispatcher.ts b/packages/api/src/common/IEventDispatcher.ts new file mode 100644 index 0000000..2e4ebdb --- /dev/null +++ b/packages/api/src/common/IEventDispatcher.ts @@ -0,0 +1,10 @@ +import { INitroEvent } from './INitroEvent'; + +export interface IEventDispatcher +{ + dispose(): void; + addEventListener(type: string, callback: (event: T) => void): void; + removeEventListener(type: string, callback: Function): void; + removeAllListeners(): void; + dispatchEvent(event: T): boolean; +} diff --git a/packages/api/src/common/ILinkEventTracker.ts b/packages/api/src/common/ILinkEventTracker.ts new file mode 100644 index 0000000..311567d --- /dev/null +++ b/packages/api/src/common/ILinkEventTracker.ts @@ -0,0 +1,5 @@ +export interface ILinkEventTracker +{ + linkReceived(link: string): void; + eventUrlPrefix: string; +} \ No newline at end of file diff --git a/packages/api/src/common/INitroEvent.ts b/packages/api/src/common/INitroEvent.ts new file mode 100644 index 0000000..e063ad8 --- /dev/null +++ b/packages/api/src/common/INitroEvent.ts @@ -0,0 +1,4 @@ +export interface INitroEvent +{ + type: string; +} diff --git a/packages/api/src/common/INitroManager.ts b/packages/api/src/common/INitroManager.ts new file mode 100644 index 0000000..22ac5f8 --- /dev/null +++ b/packages/api/src/common/INitroManager.ts @@ -0,0 +1,10 @@ +import { IDisposable } from './IDisposable'; +import { IEventDispatcher } from './IEventDispatcher'; + +export interface INitroManager extends IDisposable +{ + init(): void; + events: IEventDispatcher; + isLoaded: boolean; + isLoading: boolean; +} diff --git a/packages/api/src/common/IUpdateReceiver.ts b/packages/api/src/common/IUpdateReceiver.ts new file mode 100644 index 0000000..9bc3b4e --- /dev/null +++ b/packages/api/src/common/IUpdateReceiver.ts @@ -0,0 +1,6 @@ +import { Ticker } from 'pixi.js'; + +export interface IUpdateReceiver +{ + update(ticker: Ticker): void; +} diff --git a/packages/api/src/common/index.ts b/packages/api/src/common/index.ts new file mode 100644 index 0000000..856b24c --- /dev/null +++ b/packages/api/src/common/index.ts @@ -0,0 +1,6 @@ +export * from './IDisposable'; +export * from './IEventDispatcher'; +export * from './ILinkEventTracker'; +export * from './INitroEvent'; +export * from './INitroManager'; +export * from './IUpdateReceiver'; diff --git a/packages/api/src/communication/ICodec.ts b/packages/api/src/communication/ICodec.ts new file mode 100644 index 0000000..39c4b29 --- /dev/null +++ b/packages/api/src/communication/ICodec.ts @@ -0,0 +1,9 @@ +import { IBinaryWriter } from '../utils'; +import { IConnection } from './IConnection'; +import { IMessageDataWrapper } from './IMessageDataWrapper'; + +export interface ICodec +{ + encode(header: number, messages: any[]): IBinaryWriter; + decode(connection: IConnection): IMessageDataWrapper[]; +} diff --git a/packages/api/src/communication/ICommunicationManager.ts b/packages/api/src/communication/ICommunicationManager.ts new file mode 100644 index 0000000..7c15877 --- /dev/null +++ b/packages/api/src/communication/ICommunicationManager.ts @@ -0,0 +1,10 @@ +import { IConnection } from './IConnection'; +import { IMessageEvent } from './IMessageEvent'; + +export interface ICommunicationManager +{ + init(): Promise; + registerMessageEvent(event: IMessageEvent): IMessageEvent; + removeMessageEvent(event: IMessageEvent): void; + connection: IConnection; +} diff --git a/packages/api/src/communication/IConnection.ts b/packages/api/src/communication/IConnection.ts new file mode 100644 index 0000000..3139c22 --- /dev/null +++ b/packages/api/src/communication/IConnection.ts @@ -0,0 +1,17 @@ +import { IMessageComposer } from './IMessageComposer'; +import { IMessageConfiguration } from './IMessageConfiguration'; +import { IMessageEvent } from './IMessageEvent'; + +export interface IConnection +{ + init(socketUrl: string): void; + ready(): 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; +} diff --git a/packages/api/src/communication/IConnectionStateListener.ts b/packages/api/src/communication/IConnectionStateListener.ts new file mode 100644 index 0000000..d140fd0 --- /dev/null +++ b/packages/api/src/communication/IConnectionStateListener.ts @@ -0,0 +1,4 @@ +export interface IConnectionStateListener +{ + connectionInit(socketUrl: string): void; +} \ No newline at end of file diff --git a/packages/api/src/communication/IMessageComposer.ts b/packages/api/src/communication/IMessageComposer.ts new file mode 100644 index 0000000..eb09bc8 --- /dev/null +++ b/packages/api/src/communication/IMessageComposer.ts @@ -0,0 +1,5 @@ +export interface IMessageComposer +{ + dispose(): void; + getMessageArray(): T; +} \ No newline at end of file diff --git a/packages/api/src/communication/IMessageConfiguration.ts b/packages/api/src/communication/IMessageConfiguration.ts new file mode 100644 index 0000000..03efd30 --- /dev/null +++ b/packages/api/src/communication/IMessageConfiguration.ts @@ -0,0 +1,5 @@ +export interface IMessageConfiguration +{ + events: Map; + composers: Map; +} \ No newline at end of file diff --git a/packages/api/src/communication/IMessageDataWrapper.ts b/packages/api/src/communication/IMessageDataWrapper.ts new file mode 100644 index 0000000..0f1c39f --- /dev/null +++ b/packages/api/src/communication/IMessageDataWrapper.ts @@ -0,0 +1,15 @@ +import { IBinaryReader } from '../utils'; + +export interface IMessageDataWrapper +{ + readByte(): number; + readBytes(length: number): IBinaryReader; + readBoolean(): boolean; + readShort(): number; + readInt(): number; + readFloat(): number; + readDouble(): number; + readString(): string; + header: number; + bytesAvailable: boolean; +} diff --git a/packages/api/src/communication/IMessageEvent.ts b/packages/api/src/communication/IMessageEvent.ts new file mode 100644 index 0000000..5949015 --- /dev/null +++ b/packages/api/src/communication/IMessageEvent.ts @@ -0,0 +1,11 @@ +import { IConnection } from './IConnection'; +import { IMessageParser } from './IMessageParser'; + +export interface IMessageEvent +{ + dispose(): void; + callBack: Function; + parserClass: Function; + parser: IMessageParser; + connection: IConnection; +} diff --git a/packages/api/src/communication/IMessageParser.ts b/packages/api/src/communication/IMessageParser.ts new file mode 100644 index 0000000..f10a50d --- /dev/null +++ b/packages/api/src/communication/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/packages/api/src/communication/enums/ClientDeviceCategoryEnum.ts b/packages/api/src/communication/enums/ClientDeviceCategoryEnum.ts new file mode 100644 index 0000000..abd127f --- /dev/null +++ b/packages/api/src/communication/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/packages/api/src/communication/enums/ClientPlatformEnum.ts b/packages/api/src/communication/enums/ClientPlatformEnum.ts new file mode 100644 index 0000000..417b811 --- /dev/null +++ b/packages/api/src/communication/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/packages/api/src/communication/enums/WebSocketEventEnum.ts b/packages/api/src/communication/enums/WebSocketEventEnum.ts new file mode 100644 index 0000000..303b79c --- /dev/null +++ b/packages/api/src/communication/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/packages/api/src/communication/enums/index.ts b/packages/api/src/communication/enums/index.ts new file mode 100644 index 0000000..42a2270 --- /dev/null +++ b/packages/api/src/communication/enums/index.ts @@ -0,0 +1,3 @@ +export * from './ClientDeviceCategoryEnum'; +export * from './ClientPlatformEnum'; +export * from './WebSocketEventEnum'; diff --git a/packages/api/src/communication/index.ts b/packages/api/src/communication/index.ts new file mode 100644 index 0000000..01b0ed3 --- /dev/null +++ b/packages/api/src/communication/index.ts @@ -0,0 +1,10 @@ +export * from './ICodec'; +export * from './ICommunicationManager'; +export * from './IConnection'; +export * from './IConnectionStateListener'; +export * from './IMessageComposer'; +export * from './IMessageConfiguration'; +export * from './IMessageDataWrapper'; +export * from './IMessageEvent'; +export * from './IMessageParser'; +export * from './enums'; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts new file mode 100644 index 0000000..d545082 --- /dev/null +++ b/packages/api/src/index.ts @@ -0,0 +1,43 @@ +export * from './asset'; +export * from './asset/animation'; +export * from './asset/logic'; +export * from './asset/logic/model'; +export * from './asset/logic/particlesystem'; +export * from './asset/room-visualization'; +export * from './asset/spritesheet'; +export * from './asset/visualization'; +export * from './asset/visualization/animation'; +export * from './asset/visualization/color'; +export * from './asset/visualization/gestures'; +export * from './asset/visualization/postures'; +export * from './common'; +export * from './communication'; +export * from './communication/enums'; +export * from './nitro'; +export * from './nitro/avatar'; +export * from './nitro/avatar/actions'; +export * from './nitro/avatar/animation'; +export * from './nitro/avatar/enum'; +export * from './nitro/avatar/figuredata'; +export * from './nitro/avatar/structure'; +export * from './nitro/camera'; +export * from './nitro/enums'; +export * from './nitro/localization'; +export * from './nitro/room'; +export * from './nitro/room/enums'; +export * from './nitro/room/object'; +export * from './nitro/room/object/data'; +export * from './nitro/room/object/data/type'; +export * from './nitro/room/utils'; +export * from './nitro/session'; +export * from './nitro/session/enum'; +export * from './nitro/sound'; +export * from './room'; +export * from './room/object'; +export * from './room/object/enum'; +export * from './room/object/logic'; +export * from './room/object/visualization'; +export * from './room/renderer'; +export * from './ui'; +export * from './ui/enums'; +export * from './utils'; diff --git a/packages/api/src/nitro/avatar/IAvatarAssetDownloadLibrary.ts b/packages/api/src/nitro/avatar/IAvatarAssetDownloadLibrary.ts new file mode 100644 index 0000000..82e779a --- /dev/null +++ b/packages/api/src/nitro/avatar/IAvatarAssetDownloadLibrary.ts @@ -0,0 +1,6 @@ +export interface IAvatarAssetDownloadLibrary +{ + downloadAsset(): Promise; + readonly libraryName: string; + readonly isLoaded: boolean; +} diff --git a/packages/api/src/nitro/avatar/IAvatarEffectListener.ts b/packages/api/src/nitro/avatar/IAvatarEffectListener.ts new file mode 100644 index 0000000..a04ebc3 --- /dev/null +++ b/packages/api/src/nitro/avatar/IAvatarEffectListener.ts @@ -0,0 +1,4 @@ +export interface IAvatarEffectListener +{ + resetEffect(effect: number): void; +} diff --git a/packages/api/src/nitro/avatar/IAvatarFigureContainer.ts b/packages/api/src/nitro/avatar/IAvatarFigureContainer.ts new file mode 100644 index 0000000..6e11806 --- /dev/null +++ b/packages/api/src/nitro/avatar/IAvatarFigureContainer.ts @@ -0,0 +1,10 @@ +export interface IAvatarFigureContainer +{ + getPartTypeIds(): IterableIterator; + hasPartType(_arg_1: string): boolean; + getPartSetId(_arg_1: string): number; + getPartColorIds(_arg_1: string): number[]; + updatePart(_arg_1: string, _arg_2: number, _arg_3: number[]): void; + removePart(_arg_1: string): void; + getFigureString(): string; +} diff --git a/packages/api/src/nitro/avatar/IAvatarImage.ts b/packages/api/src/nitro/avatar/IAvatarImage.ts new file mode 100644 index 0000000..d8d5052 --- /dev/null +++ b/packages/api/src/nitro/avatar/IAvatarImage.ts @@ -0,0 +1,29 @@ +import { Container, Texture } from 'pixi.js'; +import { IAvatarFigureContainer } from './IAvatarFigureContainer'; +import { IAnimationLayerData, ISpriteDataContainer } from './animation'; +import { IPartColor } from './structure'; + +export interface IAvatarImage +{ + dispose(): void; + 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; + processAsTexture(setType: string, hightlight: boolean, texture?: Texture): Texture; + processAsImageUrl(setType: string): string; + processAsContainer(setType: string): Container; + getDirection(): number; + getFigure(): IAvatarFigureContainer; + getPartColor(_arg_1: string): IPartColor; + isAnimating(): boolean; + getCanvasOffsets(): number[]; + initActionAppends(): void; + endActionAppends(): void; + appendAction(_arg_1: string, ..._args: any[]): boolean; + isPlaceholder(): boolean; + animationHasResetOnToggle: boolean; + resetAnimationFrameCounter(): void; +} diff --git a/packages/api/src/nitro/avatar/IAvatarImageListener.ts b/packages/api/src/nitro/avatar/IAvatarImageListener.ts new file mode 100644 index 0000000..cc68c92 --- /dev/null +++ b/packages/api/src/nitro/avatar/IAvatarImageListener.ts @@ -0,0 +1,6 @@ +import { IDisposable } from '../../common'; + +export interface IAvatarImageListener extends IDisposable +{ + resetFigure(figure: string): void; +} diff --git a/packages/api/src/nitro/avatar/IAvatarRenderManager.ts b/packages/api/src/nitro/avatar/IAvatarRenderManager.ts new file mode 100644 index 0000000..a0e80ed --- /dev/null +++ b/packages/api/src/nitro/avatar/IAvatarRenderManager.ts @@ -0,0 +1,22 @@ +import { IAssetManager, IGraphicAsset } from '../../asset'; +import { IAvatarEffectListener } from './IAvatarEffectListener'; +import { IAvatarFigureContainer } from './IAvatarFigureContainer'; +import { IAvatarImage } from './IAvatarImage'; +import { IAvatarImageListener } from './IAvatarImageListener'; +import { IStructureData } from './structure'; + +export interface IAvatarRenderManager +{ + init(): Promise; + 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; + getMandatoryAvatarPartSetIds(k: string, _arg_2: number): string[]; + getAssetByName(name: string): IGraphicAsset; + assets: IAssetManager; + structureData: IStructureData; +} diff --git a/packages/api/src/nitro/avatar/IEffectAssetDownloadLibrary.ts b/packages/api/src/nitro/avatar/IEffectAssetDownloadLibrary.ts new file mode 100644 index 0000000..b76a32e --- /dev/null +++ b/packages/api/src/nitro/avatar/IEffectAssetDownloadLibrary.ts @@ -0,0 +1,9 @@ +import { IAssetAnimation } from '../../asset'; + +export interface IEffectAssetDownloadLibrary +{ + downloadAsset(): void; + readonly libraryName: string; + readonly animation: { [index: string]: IAssetAnimation }; + readonly isLoaded: boolean; +} diff --git a/packages/api/src/nitro/avatar/IOutfit.ts b/packages/api/src/nitro/avatar/IOutfit.ts new file mode 100644 index 0000000..e797d6f --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/avatar/actions/IActionDefinition.ts b/packages/api/src/nitro/avatar/actions/IActionDefinition.ts new file mode 100644 index 0000000..9c0e5f1 --- /dev/null +++ b/packages/api/src/nitro/avatar/actions/IActionDefinition.ts @@ -0,0 +1,19 @@ +export interface IActionDefinition +{ + id: string; + state: string; + precedence: number; + activePartSet: string; + isMain: boolean; + isDefault: boolean; + assetPartDefinition: string; + lay: string; + geometryType: string; + isAnimation: boolean; + startFromFrameZero: boolean; + isAnimated(_arg_1: string): boolean; + getPrevents(_arg_1: string): string[]; + getPreventHeadTurn(_arg_1: string): boolean; + setOffsets(_arg_1: string, _arg_2: number, _arg_3: []): void; + getOffsets(_arg_1: string, _arg_2: number): number[]; +} diff --git a/packages/api/src/nitro/avatar/actions/IActiveActionData.ts b/packages/api/src/nitro/avatar/actions/IActiveActionData.ts new file mode 100644 index 0000000..214c64f --- /dev/null +++ b/packages/api/src/nitro/avatar/actions/IActiveActionData.ts @@ -0,0 +1,11 @@ +import { IActionDefinition } from './IActionDefinition'; + +export interface IActiveActionData +{ + id: string; + actionType: string; + actionParameter: string; + startFrame: number; + definition: IActionDefinition; + overridingAction: string; +} diff --git a/packages/api/src/nitro/avatar/actions/index.ts b/packages/api/src/nitro/avatar/actions/index.ts new file mode 100644 index 0000000..9e191b0 --- /dev/null +++ b/packages/api/src/nitro/avatar/actions/index.ts @@ -0,0 +1,2 @@ +export * from './IActionDefinition'; +export * from './IActiveActionData'; diff --git a/packages/api/src/nitro/avatar/animation/IAnimation.ts b/packages/api/src/nitro/avatar/animation/IAnimation.ts new file mode 100644 index 0000000..2f53b72 --- /dev/null +++ b/packages/api/src/nitro/avatar/animation/IAnimation.ts @@ -0,0 +1,11 @@ +export interface IAnimation +{ + hasAvatarData(): boolean; + hasDirectionData(): boolean; + hasAddData(): boolean; + id: string; + spriteData: any; + removeData: any; + addData: any; + resetOnToggle: boolean; +} diff --git a/packages/api/src/nitro/avatar/animation/IAnimationLayerData.ts b/packages/api/src/nitro/avatar/animation/IAnimationLayerData.ts new file mode 100644 index 0000000..8bf9e86 --- /dev/null +++ b/packages/api/src/nitro/avatar/animation/IAnimationLayerData.ts @@ -0,0 +1,12 @@ +import { IActiveActionData } from '../actions'; + +export interface IAnimationLayerData +{ + id: string; + action: IActiveActionData; + animationFrame: number; + dx: number; + dy: number; + dz: number; + dd: number; +} diff --git a/packages/api/src/nitro/avatar/animation/IAnimationManager.ts b/packages/api/src/nitro/avatar/animation/IAnimationManager.ts new file mode 100644 index 0000000..2fff676 --- /dev/null +++ b/packages/api/src/nitro/avatar/animation/IAnimationManager.ts @@ -0,0 +1,9 @@ +import { IAnimation } from './IAnimation'; +import { IAnimationLayerData } from './IAnimationLayerData'; + +export interface IAnimationManager +{ + animations: Map; + getAnimation(_arg_1: string): IAnimation; + getLayerData(_arg_1: string, _arg_2: number, _arg_3: string): IAnimationLayerData; +} diff --git a/packages/api/src/nitro/avatar/animation/IAvatarDataContainer.ts b/packages/api/src/nitro/avatar/animation/IAvatarDataContainer.ts new file mode 100644 index 0000000..485f23a --- /dev/null +++ b/packages/api/src/nitro/avatar/animation/IAvatarDataContainer.ts @@ -0,0 +1,12 @@ +import { Filter } from 'pixi.js'; + +export interface IAvatarDataContainer +{ + ink: number; + colorTransform: Filter; + paletteIsGrayscale: boolean; + reds: number[]; + greens: number[]; + blues: number[]; + alphas: number[]; +} diff --git a/packages/api/src/nitro/avatar/animation/ISpriteDataContainer.ts b/packages/api/src/nitro/avatar/animation/ISpriteDataContainer.ts new file mode 100644 index 0000000..97df715 --- /dev/null +++ b/packages/api/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; + hasDirections: boolean; + hasStaticY: boolean; + getDirectionOffsetX(_arg_1: number): number; + getDirectionOffsetY(_arg_1: number): number; + getDirectionOffsetZ(_arg_1: number): number; +} diff --git a/packages/api/src/nitro/avatar/animation/index.ts b/packages/api/src/nitro/avatar/animation/index.ts new file mode 100644 index 0000000..c6ce58c --- /dev/null +++ b/packages/api/src/nitro/avatar/animation/index.ts @@ -0,0 +1,5 @@ +export * from './IAnimation'; +export * from './IAnimationLayerData'; +export * from './IAnimationManager'; +export * from './IAvatarDataContainer'; +export * from './ISpriteDataContainer'; diff --git a/packages/api/src/nitro/avatar/enum/AvatarAction.ts b/packages/api/src/nitro/avatar/enum/AvatarAction.ts new file mode 100644 index 0000000..2d7ac10 --- /dev/null +++ b/packages/api/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'; + } +} diff --git a/packages/api/src/nitro/avatar/enum/AvatarDirectionAngle.ts b/packages/api/src/nitro/avatar/enum/AvatarDirectionAngle.ts new file mode 100644 index 0000000..83f9288 --- /dev/null +++ b/packages/api/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]; + public static DIRECTION_IS_FLIPPED: boolean[] = [false, false, false, false, true, true, true, false]; + public static MIN_DIRECTION: number = 0; + public static MAX_DIRECTION: number = 7; +} diff --git a/packages/api/src/nitro/avatar/enum/AvatarEditorFigureCategory.ts b/packages/api/src/nitro/avatar/enum/AvatarEditorFigureCategory.ts new file mode 100644 index 0000000..02e1801 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/avatar/enum/AvatarEditorInstanceId.ts b/packages/api/src/nitro/avatar/enum/AvatarEditorInstanceId.ts new file mode 100644 index 0000000..82cfaae --- /dev/null +++ b/packages/api/src/nitro/avatar/enum/AvatarEditorInstanceId.ts @@ -0,0 +1,7 @@ +export class AvatarEditorInstanceId +{ + public static OWN_AVATAR_EDITOR: number = 0; + public static FURNITURE_AVATAR_EDITOR: number = 1; + public static BOT_EDITOR: number = 2; + public static DEV_TOOL_EDITOR: number = 3; +} diff --git a/packages/api/src/nitro/avatar/enum/AvatarEditorSideCategory.ts b/packages/api/src/nitro/avatar/enum/AvatarEditorSideCategory.ts new file mode 100644 index 0000000..8dfd979 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/avatar/enum/AvatarFigurePartType.ts b/packages/api/src/nitro/avatar/enum/AvatarFigurePartType.ts new file mode 100644 index 0000000..30bc564 --- /dev/null +++ b/packages/api/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 FIGURE_SETS: 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 ]; +} diff --git a/packages/api/src/nitro/avatar/enum/AvatarGuideStatus.ts b/packages/api/src/nitro/avatar/enum/AvatarGuideStatus.ts new file mode 100644 index 0000000..48a5b3c --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/avatar/enum/AvatarScaleType.ts b/packages/api/src/nitro/avatar/enum/AvatarScaleType.ts new file mode 100644 index 0000000..5933495 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/avatar/enum/AvatarSetType.ts b/packages/api/src/nitro/avatar/enum/AvatarSetType.ts new file mode 100644 index 0000000..38df0af --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/avatar/enum/GeometryType.ts b/packages/api/src/nitro/avatar/enum/GeometryType.ts new file mode 100644 index 0000000..402c05f --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/avatar/enum/RenderMode.ts b/packages/api/src/nitro/avatar/enum/RenderMode.ts new file mode 100644 index 0000000..ff9f877 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/avatar/enum/index.ts b/packages/api/src/nitro/avatar/enum/index.ts new file mode 100644 index 0000000..8ea559f --- /dev/null +++ b/packages/api/src/nitro/avatar/enum/index.ts @@ -0,0 +1,11 @@ +export * from './AvatarAction'; +export * from './AvatarDirectionAngle'; +export * from './AvatarEditorFigureCategory'; +export * from './AvatarEditorInstanceId'; +export * from './AvatarEditorSideCategory'; +export * from './AvatarFigurePartType'; +export * from './AvatarGuideStatus'; +export * from './AvatarScaleType'; +export * from './AvatarSetType'; +export * from './GeometryType'; +export * from './RenderMode'; diff --git a/packages/api/src/nitro/avatar/figuredata/IFigureData.ts b/packages/api/src/nitro/avatar/figuredata/IFigureData.ts new file mode 100644 index 0000000..86e7901 --- /dev/null +++ b/packages/api/src/nitro/avatar/figuredata/IFigureData.ts @@ -0,0 +1,8 @@ +import { IFigureDataPalette } from './IFigureDataPalette'; +import { IFigureDataSetType } from './IFigureDataSetType'; + +export interface IFigureData +{ + palettes?: IFigureDataPalette[]; + setTypes?: IFigureDataSetType[]; +} diff --git a/packages/api/src/nitro/avatar/figuredata/IFigureDataColor.ts b/packages/api/src/nitro/avatar/figuredata/IFigureDataColor.ts new file mode 100644 index 0000000..535dead --- /dev/null +++ b/packages/api/src/nitro/avatar/figuredata/IFigureDataColor.ts @@ -0,0 +1,8 @@ +export interface IFigureDataColor +{ + id?: number; + index?: number; + club?: number; + selectable?: boolean; + hexCode?: string; +} diff --git a/packages/api/src/nitro/avatar/figuredata/IFigureDataHiddenLayer.ts b/packages/api/src/nitro/avatar/figuredata/IFigureDataHiddenLayer.ts new file mode 100644 index 0000000..80f42e6 --- /dev/null +++ b/packages/api/src/nitro/avatar/figuredata/IFigureDataHiddenLayer.ts @@ -0,0 +1,4 @@ +export interface IFigureDataHiddenLayer +{ + partType?: string; +} diff --git a/packages/api/src/nitro/avatar/figuredata/IFigureDataPalette.ts b/packages/api/src/nitro/avatar/figuredata/IFigureDataPalette.ts new file mode 100644 index 0000000..f83fa06 --- /dev/null +++ b/packages/api/src/nitro/avatar/figuredata/IFigureDataPalette.ts @@ -0,0 +1,7 @@ +import { IFigureDataColor } from './IFigureDataColor'; + +export interface IFigureDataPalette +{ + id?: number; + colors?: IFigureDataColor[]; +} diff --git a/packages/api/src/nitro/avatar/figuredata/IFigureDataPart.ts b/packages/api/src/nitro/avatar/figuredata/IFigureDataPart.ts new file mode 100644 index 0000000..e57ef47 --- /dev/null +++ b/packages/api/src/nitro/avatar/figuredata/IFigureDataPart.ts @@ -0,0 +1,8 @@ +export interface IFigureDataPart +{ + id?: number; + type?: string; + colorable?: boolean; + index?: number; + colorindex?: number; +} diff --git a/packages/api/src/nitro/avatar/figuredata/IFigureDataSet.ts b/packages/api/src/nitro/avatar/figuredata/IFigureDataSet.ts new file mode 100644 index 0000000..f3c89d9 --- /dev/null +++ b/packages/api/src/nitro/avatar/figuredata/IFigureDataSet.ts @@ -0,0 +1,15 @@ +import { IFigureDataHiddenLayer } from './IFigureDataHiddenLayer'; +import { IFigureDataPart } from './IFigureDataPart'; + +export interface IFigureDataSet +{ + id?: number; + gender?: string; + club?: number; + colorable?: boolean; + selectable?: boolean; + preselectable?: boolean; + sellable?: boolean; + parts?: IFigureDataPart[]; + hiddenLayers?: IFigureDataHiddenLayer[]; +} diff --git a/packages/api/src/nitro/avatar/figuredata/IFigureDataSetType.ts b/packages/api/src/nitro/avatar/figuredata/IFigureDataSetType.ts new file mode 100644 index 0000000..d9a2d97 --- /dev/null +++ b/packages/api/src/nitro/avatar/figuredata/IFigureDataSetType.ts @@ -0,0 +1,12 @@ +import { IFigureDataSet } from './IFigureDataSet'; + +export interface IFigureDataSetType +{ + type?: string; + paletteId?: number; + mandatory_m_0?: boolean; + mandatory_f_0?: boolean; + mandatory_m_1?: boolean; + mandatory_f_1?: boolean; + sets?: IFigureDataSet[]; +} diff --git a/packages/api/src/nitro/avatar/figuredata/index.ts b/packages/api/src/nitro/avatar/figuredata/index.ts new file mode 100644 index 0000000..579987b --- /dev/null +++ b/packages/api/src/nitro/avatar/figuredata/index.ts @@ -0,0 +1,7 @@ +export * from './IFigureData'; +export * from './IFigureDataColor'; +export * from './IFigureDataHiddenLayer'; +export * from './IFigureDataPalette'; +export * from './IFigureDataPart'; +export * from './IFigureDataSet'; +export * from './IFigureDataSetType'; diff --git a/packages/api/src/nitro/avatar/index.ts b/packages/api/src/nitro/avatar/index.ts new file mode 100644 index 0000000..5c3213c --- /dev/null +++ b/packages/api/src/nitro/avatar/index.ts @@ -0,0 +1,13 @@ +export * from './IAvatarAssetDownloadLibrary'; +export * from './IAvatarEffectListener'; +export * from './IAvatarFigureContainer'; +export * from './IAvatarImage'; +export * from './IAvatarImageListener'; +export * from './IAvatarRenderManager'; +export * from './IEffectAssetDownloadLibrary'; +export * from './IOutfit'; +export * from './actions'; +export * from './animation'; +export * from './enum'; +export * from './figuredata'; +export * from './structure'; diff --git a/packages/api/src/nitro/avatar/structure/IFigurePart.ts b/packages/api/src/nitro/avatar/structure/IFigurePart.ts new file mode 100644 index 0000000..578725b --- /dev/null +++ b/packages/api/src/nitro/avatar/structure/IFigurePart.ts @@ -0,0 +1,9 @@ +export interface IFigurePart +{ + id: number; + type: string; + breed: number; + index: number; + colorLayerIndex: number; + paletteMap: number; +} diff --git a/packages/api/src/nitro/avatar/structure/IFigurePartSet.ts b/packages/api/src/nitro/avatar/structure/IFigurePartSet.ts new file mode 100644 index 0000000..7e1653e --- /dev/null +++ b/packages/api/src/nitro/avatar/structure/IFigurePartSet.ts @@ -0,0 +1,16 @@ +import { IFigurePart } from './IFigurePart'; + +export interface IFigurePartSet +{ + getPart(_arg_1: string, _arg_2: number): IFigurePart; + id: number; + type: string; + gender: string; + clubLevel: number; + isColorable: boolean; + isSelectable: boolean; + parts: IFigurePart[]; + hiddenLayers: string[]; + isPreSelectable: boolean; + isSellable: boolean; +} diff --git a/packages/api/src/nitro/avatar/structure/IFigureSetData.ts b/packages/api/src/nitro/avatar/structure/IFigureSetData.ts new file mode 100644 index 0000000..5ea24a6 --- /dev/null +++ b/packages/api/src/nitro/avatar/structure/IFigureSetData.ts @@ -0,0 +1,7 @@ +import { IFigureData } from '../figuredata'; + +export interface IFigureSetData +{ + parse(data: any): boolean; + appendJSON(data: IFigureData): boolean; +} diff --git a/packages/api/src/nitro/avatar/structure/IPalette.ts b/packages/api/src/nitro/avatar/structure/IPalette.ts new file mode 100644 index 0000000..8c5c0e2 --- /dev/null +++ b/packages/api/src/nitro/avatar/structure/IPalette.ts @@ -0,0 +1,9 @@ +import { IAdvancedMap } from '../../../utils'; +import { IPartColor } from './IPartColor'; + +export interface IPalette +{ + getColor(id: number): IPartColor; + id: number; + colors: IAdvancedMap; +} diff --git a/packages/api/src/nitro/avatar/structure/IPartColor.ts b/packages/api/src/nitro/avatar/structure/IPartColor.ts new file mode 100644 index 0000000..6978528 --- /dev/null +++ b/packages/api/src/nitro/avatar/structure/IPartColor.ts @@ -0,0 +1,8 @@ +export interface IPartColor +{ + id: number; + index: number; + clubLevel: number; + isSelectable: boolean; + rgb: number; +} diff --git a/packages/api/src/nitro/avatar/structure/ISetType.ts b/packages/api/src/nitro/avatar/structure/ISetType.ts new file mode 100644 index 0000000..9277a47 --- /dev/null +++ b/packages/api/src/nitro/avatar/structure/ISetType.ts @@ -0,0 +1,12 @@ +import { IAdvancedMap } from '../../../utils'; +import { IFigurePartSet } from './IFigurePartSet'; + +export interface ISetType +{ + getPartSet(_arg_1: number): IFigurePartSet; + isMandatory(_arg_1: string, _arg_2: number): boolean; + optionalFromClubLevel(_arg_1: string): number; + type: string; + paletteID: number; + partSets: IAdvancedMap; +} diff --git a/packages/api/src/nitro/avatar/structure/IStructureData.ts b/packages/api/src/nitro/avatar/structure/IStructureData.ts new file mode 100644 index 0000000..392e885 --- /dev/null +++ b/packages/api/src/nitro/avatar/structure/IStructureData.ts @@ -0,0 +1,12 @@ +import { IFigurePartSet } from './IFigurePartSet'; +import { IPalette } from './IPalette'; +import { ISetType } from './ISetType'; + +export interface IStructureData +{ + parse(data: any): boolean; + appendJSON(k: any): boolean; + getSetType(_arg_1: string): ISetType; + getPalette(_arg_1: number): IPalette; + getFigurePartSet(_arg_1: number): IFigurePartSet; +} diff --git a/packages/api/src/nitro/avatar/structure/index.ts b/packages/api/src/nitro/avatar/structure/index.ts new file mode 100644 index 0000000..4c63b05 --- /dev/null +++ b/packages/api/src/nitro/avatar/structure/index.ts @@ -0,0 +1,7 @@ +export * from './IFigurePart'; +export * from './IFigurePartSet'; +export * from './IFigureSetData'; +export * from './IPalette'; +export * from './IPartColor'; +export * from './ISetType'; +export * from './IStructureData'; diff --git a/packages/api/src/nitro/camera/IRoomCameraWidgetEffect.ts b/packages/api/src/nitro/camera/IRoomCameraWidgetEffect.ts new file mode 100644 index 0000000..43f29ff --- /dev/null +++ b/packages/api/src/nitro/camera/IRoomCameraWidgetEffect.ts @@ -0,0 +1,10 @@ +import { BLEND_MODES, ColorMatrix, Texture } from 'pixi.js'; + +export interface IRoomCameraWidgetEffect +{ + name: string; + minLevel: number; + texture: Texture; + colorMatrix: ColorMatrix; + blendMode: BLEND_MODES; +} diff --git a/packages/api/src/nitro/camera/IRoomCameraWidgetManager.ts b/packages/api/src/nitro/camera/IRoomCameraWidgetManager.ts new file mode 100644 index 0000000..bf557c0 --- /dev/null +++ b/packages/api/src/nitro/camera/IRoomCameraWidgetManager.ts @@ -0,0 +1,11 @@ +import { Texture } from 'pixi.js'; +import { IRoomCameraWidgetEffect } from './IRoomCameraWidgetEffect'; +import { IRoomCameraWidgetSelectedEffect } from './IRoomCameraWidgetSelectedEffect'; + +export interface IRoomCameraWidgetManager +{ + init(): Promise; + applyEffects(texture: Texture, selectedEffects: IRoomCameraWidgetSelectedEffect[], isZoomed: boolean): Promise; + effects: Map; + isLoaded: boolean; +} diff --git a/packages/api/src/nitro/camera/IRoomCameraWidgetSelectedEffect.ts b/packages/api/src/nitro/camera/IRoomCameraWidgetSelectedEffect.ts new file mode 100644 index 0000000..3bb3b2c --- /dev/null +++ b/packages/api/src/nitro/camera/IRoomCameraWidgetSelectedEffect.ts @@ -0,0 +1,7 @@ +import { IRoomCameraWidgetEffect } from './IRoomCameraWidgetEffect'; + +export interface IRoomCameraWidgetSelectedEffect +{ + effect: IRoomCameraWidgetEffect; + alpha: number; +} diff --git a/packages/api/src/nitro/camera/index.ts b/packages/api/src/nitro/camera/index.ts new file mode 100644 index 0000000..7c7db03 --- /dev/null +++ b/packages/api/src/nitro/camera/index.ts @@ -0,0 +1,3 @@ +export * from './IRoomCameraWidgetEffect'; +export * from './IRoomCameraWidgetManager'; +export * from './IRoomCameraWidgetSelectedEffect'; diff --git a/packages/api/src/nitro/enums/RelationshipStatusEnum.ts b/packages/api/src/nitro/enums/RelationshipStatusEnum.ts new file mode 100644 index 0000000..b64873c --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/enums/ToolbarIconEnum.ts b/packages/api/src/nitro/enums/ToolbarIconEnum.ts new file mode 100644 index 0000000..d389a95 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/enums/index.ts b/packages/api/src/nitro/enums/index.ts new file mode 100644 index 0000000..98a436c --- /dev/null +++ b/packages/api/src/nitro/enums/index.ts @@ -0,0 +1,2 @@ +export * from './RelationshipStatusEnum'; +export * from './ToolbarIconEnum'; diff --git a/packages/api/src/nitro/index.ts b/packages/api/src/nitro/index.ts new file mode 100644 index 0000000..dcbd7f6 --- /dev/null +++ b/packages/api/src/nitro/index.ts @@ -0,0 +1,18 @@ +export * from './avatar'; +export * from './avatar/actions'; +export * from './avatar/animation'; +export * from './avatar/enum'; +export * from './avatar/figuredata'; +export * from './avatar/structure'; +export * from './camera'; +export * from './enums'; +export * from './localization'; +export * from './room'; +export * from './room/enums'; +export * from './room/object'; +export * from './room/object/data'; +export * from './room/object/data/type'; +export * from './room/utils'; +export * from './session'; +export * from './session/enum'; +export * from './sound'; diff --git a/packages/api/src/nitro/localization/ILocalizationManager.ts b/packages/api/src/nitro/localization/ILocalizationManager.ts new file mode 100644 index 0000000..86070d0 --- /dev/null +++ b/packages/api/src/nitro/localization/ILocalizationManager.ts @@ -0,0 +1,16 @@ +export interface ILocalizationManager +{ + init(): Promise; + getRomanNumeral(number: number): string; + getPreviousLevelBadgeId(badgeName: string): string; + hasValue(key: string): boolean; + 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; + getBadgePointLimit(badge: string): number; + setBadgePointLimit(badge: string, point: number): void; +} diff --git a/packages/api/src/nitro/localization/index.ts b/packages/api/src/nitro/localization/index.ts new file mode 100644 index 0000000..3aee8f5 --- /dev/null +++ b/packages/api/src/nitro/localization/index.ts @@ -0,0 +1 @@ +export * from './ILocalizationManager'; diff --git a/packages/api/src/nitro/room/IGetImageListener.ts b/packages/api/src/nitro/room/IGetImageListener.ts new file mode 100644 index 0000000..54b585f --- /dev/null +++ b/packages/api/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; +} diff --git a/packages/api/src/nitro/room/IImageResult.ts b/packages/api/src/nitro/room/IImageResult.ts new file mode 100644 index 0000000..2d991a0 --- /dev/null +++ b/packages/api/src/nitro/room/IImageResult.ts @@ -0,0 +1,9 @@ +import { Texture } from 'pixi.js'; + +export interface IImageResult +{ + id: number; + data: Texture; + image: HTMLImageElement; + getImage(): Promise; +} diff --git a/packages/api/src/nitro/room/IPetColorResult.ts b/packages/api/src/nitro/room/IPetColorResult.ts new file mode 100644 index 0000000..f66417d --- /dev/null +++ b/packages/api/src/nitro/room/IPetColorResult.ts @@ -0,0 +1,10 @@ +export interface IPetColorResult +{ + readonly primaryColor: number; + readonly secondaryColor: number; + readonly breed: number; + readonly tag: string; + readonly id: string; + readonly isMaster: boolean; + readonly layerTags: string[]; +} diff --git a/packages/api/src/nitro/room/IRoomContentListener.ts b/packages/api/src/nitro/room/IRoomContentListener.ts new file mode 100644 index 0000000..375b146 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/room/IRoomContentLoader.ts b/packages/api/src/nitro/room/IRoomContentLoader.ts new file mode 100644 index 0000000..7e4c956 --- /dev/null +++ b/packages/api/src/nitro/room/IRoomContentLoader.ts @@ -0,0 +1,33 @@ +import { Texture } from 'pixi.js'; +import { IGraphicAssetCollection } from '../../asset'; +import { IEventDispatcher } from '../../common'; +import { IRoomObject } from '../../room'; +import { IFurnitureData } from '../session'; +import { IPetColorResult } from './IPetColorResult'; +import { IRoomContentListener } from './IRoomContentListener'; + +export interface IRoomContentLoader +{ + init(): Promise; + processFurnitureData(furnitureData: IFurnitureData[]): void; + downloadAsset(type: string): Promise; + isLoaderType(type: string): boolean; + getCollection(name: string): IGraphicAssetCollection; + getPlaceholderName(type: string): string; + getCategoryForType(type: string): number; + setRoomObjectRoomId(object: IRoomObject, roomId: string): void; + getFurnitureFloorNameForTypeId(typeId: number): string; + getFurnitureWallNameForTypeId(typeId: number, extra?: string): string; + getFurnitureFloorColorIndex(typeId: number): number; + getFurnitureWallColorIndex(typeId: number): number; + getImage(name: string): HTMLImageElement; + getAssetIconUrl(type: string, colorIndex: string): string; + addAssetToCollection(collectionName: string, assetName: string, texture: Texture, override?: boolean): boolean; + getPetNameForType(type: number): string; + downloadImage(id: number, type: string, param: string, events?: IEventDispatcher): boolean; + getRoomObjectAdUrl(type: string): string; + getPetColorResult(petIndex: number, paletteIndex: number): IPetColorResult; + getPetColorResultsForTag(petIndex: number, tagName: string): IPetColorResult[]; + setIconListener(listener: IRoomContentListener): void; + pets: { [index: string]: number }; +} diff --git a/packages/api/src/nitro/room/IRoomCreator.ts b/packages/api/src/nitro/room/IRoomCreator.ts new file mode 100644 index 0000000..e342bce --- /dev/null +++ b/packages/api/src/nitro/room/IRoomCreator.ts @@ -0,0 +1,51 @@ +import { IRoomInstance, IRoomObjectController } from '../../room'; +import { IVector3D } from '../../utils'; +import { IObjectData, IRoomMapData } from './object'; +import { IFurnitureStackingHeightMap, ILegacyWallGeometry } from './utils'; + +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: IRoomMapData): void; + setRoomSessionOwnUser(roomId: number, objectId: number): void; + setRoomInstanceModelName(roomId: number, name: string): void; + getFurnitureStackingHeightMap(roomId: number): IFurnitureStackingHeightMap; + setFurnitureStackingHeightMap(roomId: number, heightMap: IFurnitureStackingHeightMap): void; + getLegacyWallGeometry(roomId: number): ILegacyWallGeometry; + 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; + refreshTileObjectMap(k: number, _arg_2: string): void; + setRoomEngineGameMode(roomId: number, isPlaying: boolean): void; +} diff --git a/packages/api/src/nitro/room/IRoomEngine.ts b/packages/api/src/nitro/room/IRoomEngine.ts new file mode 100644 index 0000000..3aa3df4 --- /dev/null +++ b/packages/api/src/nitro/room/IRoomEngine.ts @@ -0,0 +1,89 @@ +import { Container, Point, Rectangle, RenderTexture, Texture } from 'pixi.js'; +import { IRoomGeometry, IRoomManager, IRoomObject, IRoomObjectController, IRoomRenderingCanvas } from '../../room'; +import { IVector3D } from '../../utils'; +import { IPetCustomPart } from '../session'; +import { IGetImageListener } from './IGetImageListener'; +import { IImageResult } from './IImageResult'; +import { IPetColorResult } from './IPetColorResult'; +import { IRoomObjectEventManager } from './IRoomObjectEventManager'; +import { IObjectData, IRoomMapData } from './object'; + +export interface IRoomEngine +{ + init(): Promise; + setActiveRoomId(roomId: number): void; + createRoomInstance(roomId: number, roomMap: IRoomMapData): void; + getRoomInstanceDisplay(roomId: number, id: number, width: number, height: number, scale: number): Container; + 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; + updateObjectRoomColor(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; + getRoomObjects(roomId: number, category: number): IRoomObject[]; + 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): IImageResult; + getFurnitureFloorIconUrl(typeId: number): string; + getFurnitureFloorIcon(typeId: number, listener: IGetImageListener, extras?: string, objectData?: IObjectData): IImageResult; + getFurnitureWallIconUrl(typeId: number, extra?: string): string; + getFurnitureWallIcon(typeId: number, listener: IGetImageListener, extras?: string): IImageResult; + 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): IImageResult; + getFurnitureWallImage(typeId: number, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor?: number, extras?: string, state?: number, frameCount?: number): IImageResult; + getRoomObjectImage(roomId: number, objectId: number, category: number, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor?: number): IImageResult; + getRoomObjectPetImage(typeId: number, paletteId: number, color: number, direction: IVector3D, scale: number, listener: IGetImageListener, headOnly?: boolean, bgColor?: number, customParts?: IPetCustomPart[], posture?: string): IImageResult; + getFurnitureFloorName(typeId: number): string; + getFurnitureWallName(typeId: number, extra?: string): string; + selectRoomObject(roomId: number, objectId: number, objectCategory: number): void; + setSelectedAvatar(roomId: number, objectId: number): void; + cancelRoomObjectInsert(): void; + getPetColorResult(petIndex: number, paletteIndex: number): IPetColorResult; + getPetColorResultsForTag(petIndex: number, tagName: string): IPetColorResult[]; + cancelRoomObjectPlacement(): void; + 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; + processRoomObjectOperation(objectId: number, category: number, operation: string): boolean; + modifyRoomObjectDataWithMap(objectId: number, category: number, operation: string, data: Map): boolean + modifyRoomObjectData(objectId: number, category: number, colorHex: string, data: 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; + createTextureFromRoom(roomId: number, canvasId?: number, bounds?: Rectangle): Texture; + saveTextureAsScreenshot(texture: RenderTexture, saveAsThumbnail?: boolean): Promise; + saveBase64AsScreenshot(base64: string, saveAsThumbnail?: boolean): void; + deleteRoomObject(objectId: number, objectCategory: number): boolean; + roomManager: IRoomManager; + objectEventHandler: IRoomObjectEventManager; + activeRoomId: number; + selectedAvatarId: number; + isDecorating: boolean; +} diff --git a/packages/api/src/nitro/room/IRoomEngineServices.ts b/packages/api/src/nitro/room/IRoomEngineServices.ts new file mode 100644 index 0000000..563467e --- /dev/null +++ b/packages/api/src/nitro/room/IRoomEngineServices.ts @@ -0,0 +1,41 @@ +import { IRoomInstance, IRoomObjectController, IRoomRenderingCanvas } from '../../room'; +import { IVector3D } from '../../utils'; +import { ISelectedRoomObjectData } from './ISelectedRoomObjectData'; +import { IObjectData } from './object'; +import { IFurnitureStackingHeightMap, ILegacyWallGeometry, ITileObjectMap } from './utils'; + +export interface IRoomEngineServices +{ + getRoomInstance(roomId: number): IRoomInstance; + getActiveRoomInstanceRenderingCanvas(): IRoomRenderingCanvas; + addRoomInstanceFloorHole(roomId: number, objectId: number): void; + removeRoomInstanceFloorHole(roomId: number, objectId: number): void; + getSelectedRoomObjectData(roomId: number): ISelectedRoomObjectData; + setSelectedRoomObjectData(roomId: number, data: ISelectedRoomObjectData): void; + getPlacedRoomObjectData(roomId: number): ISelectedRoomObjectData; + setPlacedRoomObjectData(roomId: number, data: ISelectedRoomObjectData): void; + getLegacyWallGeometry(roomId: number): ILegacyWallGeometry; + getFurnitureStackingHeightMap(roomId: number): IFurnitureStackingHeightMap; + 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; + setObjectMoverIconSprite(objectId: number, category: number, _arg_3: boolean, instanceData?: string, stuffData?: IObjectData, state?: number, frameNumber?: number, posture?: string): void; + setObjectMoverIconSpriteVisible(k: boolean): void; + updateMousePointer(type: string, objectId: number, objectType: string): void; + removeObjectMoverIconSprite(): void; + getRoomTileObjectMap(k: number): ITileObjectMap; + isPlayingGame(): boolean; + activeRoomId: number; + isDecorating: boolean; +} diff --git a/packages/api/src/nitro/room/IRoomObjectEventManager.ts b/packages/api/src/nitro/room/IRoomObjectEventManager.ts new file mode 100644 index 0000000..4f0cec3 --- /dev/null +++ b/packages/api/src/nitro/room/IRoomObjectEventManager.ts @@ -0,0 +1,6 @@ +import { IRoomObjectController } from '../../room'; + +export interface IRoomObjectEventManager +{ + getValidRoomObjectDirection(k: IRoomObjectController, _arg_2: boolean): number; +} diff --git a/packages/api/src/nitro/room/ISelectedRoomObjectData.ts b/packages/api/src/nitro/room/ISelectedRoomObjectData.ts new file mode 100644 index 0000000..bd46883 --- /dev/null +++ b/packages/api/src/nitro/room/ISelectedRoomObjectData.ts @@ -0,0 +1,18 @@ +import { IVector3D } from '../../utils'; +import { IObjectData } from './object'; + +export interface ISelectedRoomObjectData +{ + id: number; + category: number; + operation: string; + loc: IVector3D; + dir: IVector3D; + typeId: number; + instanceData: string; + stuffData: IObjectData; + state: number; + animFrame: number; + posture: string; + dispose: () => void; +} diff --git a/packages/api/src/nitro/room/enums/FriendFurniEngravingWidgetType.ts b/packages/api/src/nitro/room/enums/FriendFurniEngravingWidgetType.ts new file mode 100644 index 0000000..47a95f9 --- /dev/null +++ b/packages/api/src/nitro/room/enums/FriendFurniEngravingWidgetType.ts @@ -0,0 +1,8 @@ +export class FriendFurniEngravingWidgetType +{ + public static readonly LOVE_LOCK: number = 0; + public static readonly CARVE_A_TREE: number = 1; + public static readonly FRIENDS_PORTRAIT: number = 2; + public static readonly WILD_WEST_WANTED: number = 3; + public static readonly HABBOWEEN: number = 4; +} diff --git a/packages/api/src/nitro/room/enums/RoomObjectPlacementSource.ts b/packages/api/src/nitro/room/enums/RoomObjectPlacementSource.ts new file mode 100644 index 0000000..629bec4 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/room/enums/index.ts b/packages/api/src/nitro/room/enums/index.ts new file mode 100644 index 0000000..0ea238d --- /dev/null +++ b/packages/api/src/nitro/room/enums/index.ts @@ -0,0 +1,2 @@ +export * from './FriendFurniEngravingWidgetType'; +export * from './RoomObjectPlacementSource'; diff --git a/packages/api/src/nitro/room/index.ts b/packages/api/src/nitro/room/index.ts new file mode 100644 index 0000000..e10262d --- /dev/null +++ b/packages/api/src/nitro/room/index.ts @@ -0,0 +1,15 @@ +export * from './enums'; +export * from './IGetImageListener'; +export * from './IImageResult'; +export * from './IPetColorResult'; +export * from './IRoomContentListener'; +export * from './IRoomContentLoader'; +export * from './IRoomCreator'; +export * from './IRoomEngine'; +export * from './IRoomEngineServices'; +export * from './IRoomObjectEventManager'; +export * from './ISelectedRoomObjectData'; +export * from './object'; +export * from './object/data'; +export * from './object/data/type'; +export * from './utils'; diff --git a/packages/api/src/nitro/room/object/IPetFigureData.ts b/packages/api/src/nitro/room/object/IPetFigureData.ts new file mode 100644 index 0000000..d10bb50 --- /dev/null +++ b/packages/api/src/nitro/room/object/IPetFigureData.ts @@ -0,0 +1,12 @@ +import { IPetCustomPart } from '../../session'; + +export interface IPetFigureData +{ + readonly typeId: number; + readonly paletteId: number; + readonly color: string; + readonly breedId: number; + readonly figuredata: string; + readonly customParts: IPetCustomPart[]; + readonly customPartCount: number; +} diff --git a/packages/api/src/nitro/room/object/IRoomMapData.ts b/packages/api/src/nitro/room/object/IRoomMapData.ts new file mode 100644 index 0000000..1ebf36c --- /dev/null +++ b/packages/api/src/nitro/room/object/IRoomMapData.ts @@ -0,0 +1,11 @@ +export interface IRoomMapData +{ + width: number; + height: number; + wallHeight: number; + fixedWallsHeight: number; + tileMap: { height: number }[][]; + holeMap: { id: number, x: number, y: number, width: number, height: number }[]; + doors: { x: number, y: number, z: number, dir: number }[]; + dimensions: { minX: number, maxX: number, minY: number, maxY: number }; +} diff --git a/packages/api/src/nitro/room/object/RoomObjectCategory.ts b/packages/api/src/nitro/room/object/RoomObjectCategory.ts new file mode 100644 index 0000000..6e93273 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/room/object/RoomObjectLogicType.ts b/packages/api/src/nitro/room/object/RoomObjectLogicType.ts new file mode 100644 index 0000000..bb16bef --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/room/object/RoomObjectOperationType.ts b/packages/api/src/nitro/room/object/RoomObjectOperationType.ts new file mode 100644 index 0000000..61b8b83 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/room/object/RoomObjectType.ts b/packages/api/src/nitro/room/object/RoomObjectType.ts new file mode 100644 index 0000000..dbfc3c7 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/room/object/RoomObjectUserType.ts b/packages/api/src/nitro/room/object/RoomObjectUserType.ts new file mode 100644 index 0000000..e476a24 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/room/object/RoomObjectVariable.ts b/packages/api/src/nitro/room/object/RoomObjectVariable.ts new file mode 100644 index 0000000..3819ca5 --- /dev/null +++ b/packages/api/src/nitro/room/object/RoomObjectVariable.ts @@ -0,0 +1,144 @@ +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_EXPERIENCE_TIMESTAMP: string = 'figure_experience_timestamp'; + 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_CUSTOM_VARIABLES: string = 'furniture_custom_variables'; + 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_ASSET_NAME: string = 'furniture_guild_customized_asset_name'; + 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 FURNITURE_CLOTHING_BOY: string = 'furniture_clothing_boy'; + public static FURNITURE_CLOTHING_GIRL: string = 'furniture_clothing_girl'; + public static FURNITURE_PLANETSYSTEM_DATA: string = 'furniture_planetsystem_data'; + public static FURNITURE_FIREWORKS_DATA: string = 'furniture_fireworks_data'; + 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/packages/api/src/nitro/room/object/RoomObjectVisualizationType.ts b/packages/api/src/nitro/room/object/RoomObjectVisualizationType.ts new file mode 100644 index 0000000..0af0485 --- /dev/null +++ b/packages/api/src/nitro/room/object/RoomObjectVisualizationType.ts @@ -0,0 +1,40 @@ +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_ISOMETRIC_BB = 'furniture_isometric_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'; +} diff --git a/packages/api/src/nitro/room/object/data/IObjectData.ts b/packages/api/src/nitro/room/object/data/IObjectData.ts new file mode 100644 index 0000000..be56f1c --- /dev/null +++ b/packages/api/src/nitro/room/object/data/IObjectData.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../communication'; +import { IRoomObjectModel } from '../../../../room'; + +export interface IObjectData +{ + state: number; + isUnique: boolean; + uniqueNumber: number; + uniqueSeries: number; + rarityLevel: number; + flags: number; + parseWrapper(wrapper: IMessageDataWrapper): void; + initializeFromRoomObjectModel(model: IRoomObjectModel): void; + writeRoomObjectModel(model: IRoomObjectModel): void; + getLegacyString(): string; + compare(data: IObjectData): boolean; +} diff --git a/packages/api/src/nitro/room/object/data/ObjectDataBase.ts b/packages/api/src/nitro/room/object/data/ObjectDataBase.ts new file mode 100644 index 0000000..25ddfcc --- /dev/null +++ b/packages/api/src/nitro/room/object/data/ObjectDataBase.ts @@ -0,0 +1,99 @@ +import { IMessageDataWrapper } from '../../../../communication'; +import { IRoomObjectModel } from '../../../../room'; +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 set uniqueNumber(number: number) + { + this._uniqueNumber = number; + } + + public get uniqueSeries(): number + { + return this._uniqueSeries; + } + + public set uniqueSeries(series: number) + { + this._uniqueSeries = series; + } + + public get rarityLevel(): number + { + return -1; + } + + public get flags(): number + { + return this._flags; + } + + public set flags(flags: number) + { + this._flags = flags; + } +} diff --git a/packages/api/src/nitro/room/object/data/ObjectDataFactory.ts b/packages/api/src/nitro/room/object/data/ObjectDataFactory.ts new file mode 100644 index 0000000..b6f3e5d --- /dev/null +++ b/packages/api/src/nitro/room/object/data/ObjectDataFactory.ts @@ -0,0 +1,44 @@ +import { IObjectData } from './IObjectData'; +import { CrackableDataType, EmptyDataType, HighScoreDataType, LegacyDataType, MapDataType, NumberDataType, StringDataType, VoteDataType } from './type'; + +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; + } +} diff --git a/packages/api/src/nitro/room/object/data/ObjectDataFlags.ts b/packages/api/src/nitro/room/object/data/ObjectDataFlags.ts new file mode 100644 index 0000000..5d5a119 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/room/object/data/ObjectDataKey.ts b/packages/api/src/nitro/room/object/data/ObjectDataKey.ts new file mode 100644 index 0000000..eff1160 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/room/object/data/index.ts b/packages/api/src/nitro/room/object/data/index.ts new file mode 100644 index 0000000..64993e4 --- /dev/null +++ b/packages/api/src/nitro/room/object/data/index.ts @@ -0,0 +1,6 @@ +export * from './IObjectData'; +export * from './ObjectDataBase'; +export * from './ObjectDataFactory'; +export * from './ObjectDataFlags'; +export * from './ObjectDataKey'; +export * from './type'; diff --git a/packages/api/src/nitro/room/object/data/type/CrackableDataType.ts b/packages/api/src/nitro/room/object/data/type/CrackableDataType.ts new file mode 100644 index 0000000..8fd96fd --- /dev/null +++ b/packages/api/src/nitro/room/object/data/type/CrackableDataType.ts @@ -0,0 +1,74 @@ +import { IMessageDataWrapper } from '../../../../../communication'; +import { IRoomObjectModel } from '../../../../../room'; +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; + } +} diff --git a/packages/api/src/nitro/room/object/data/type/EmptyDataType.ts b/packages/api/src/nitro/room/object/data/type/EmptyDataType.ts new file mode 100644 index 0000000..62d9d03 --- /dev/null +++ b/packages/api/src/nitro/room/object/data/type/EmptyDataType.ts @@ -0,0 +1,39 @@ +import { IMessageDataWrapper } from '../../../../../communication'; +import { IRoomObjectModel } from '../../../../../room'; +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); + } +} diff --git a/packages/api/src/nitro/room/object/data/type/HighScoreData.ts b/packages/api/src/nitro/room/object/data/type/HighScoreData.ts new file mode 100644 index 0000000..cb18b33 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/room/object/data/type/HighScoreDataType.ts b/packages/api/src/nitro/room/object/data/type/HighScoreDataType.ts new file mode 100644 index 0000000..205c2e8 --- /dev/null +++ b/packages/api/src/nitro/room/object/data/type/HighScoreDataType.ts @@ -0,0 +1,131 @@ +import { IMessageDataWrapper } from '../../../../../communication'; +import { IRoomObjectModel } from '../../../../../room'; +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; + } + + public get clearType(): number + { + return this._clearType; + } + + public get scoreType(): number + { + return this._scoreType; + } +} diff --git a/packages/api/src/nitro/room/object/data/type/LegacyDataType.ts b/packages/api/src/nitro/room/object/data/type/LegacyDataType.ts new file mode 100644 index 0000000..29eb592 --- /dev/null +++ b/packages/api/src/nitro/room/object/data/type/LegacyDataType.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper } from '../../../../../communication'; +import { IRoomObjectModel } from '../../../../../room'; +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; + } +} diff --git a/packages/api/src/nitro/room/object/data/type/MapDataType.ts b/packages/api/src/nitro/room/object/data/type/MapDataType.ts new file mode 100644 index 0000000..4d45794 --- /dev/null +++ b/packages/api/src/nitro/room/object/data/type/MapDataType.ts @@ -0,0 +1,90 @@ +import { IMessageDataWrapper } from '../../../../../communication'; +import { IRoomObjectModel } from '../../../../../room'; +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) 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]; + } + + public get rarityLevel(): number + { + if(!this._data) return -1; + + const state = this._data[MapDataType.RARITY]; + + if(state === undefined || state === null) return -1; + + return parseInt(state); + } + + // TODO: How to get the keys? + public get data() + { + return this._data; + } + +} diff --git a/packages/api/src/nitro/room/object/data/type/NumberDataType.ts b/packages/api/src/nitro/room/object/data/type/NumberDataType.ts new file mode 100644 index 0000000..2790189 --- /dev/null +++ b/packages/api/src/nitro/room/object/data/type/NumberDataType.ts @@ -0,0 +1,91 @@ +import { IMessageDataWrapper } from '../../../../../communication'; +import { IRoomObjectModel } from '../../../../../room'; +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; + } +} diff --git a/packages/api/src/nitro/room/object/data/type/StringDataType.ts b/packages/api/src/nitro/room/object/data/type/StringDataType.ts new file mode 100644 index 0000000..7101854 --- /dev/null +++ b/packages/api/src/nitro/room/object/data/type/StringDataType.ts @@ -0,0 +1,90 @@ +import { IMessageDataWrapper } from '../../../../../communication'; +import { IRoomObjectModel } from '../../../../../room'; +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/packages/api/src/nitro/room/object/data/type/VoteDataType.ts b/packages/api/src/nitro/room/object/data/type/VoteDataType.ts new file mode 100644 index 0000000..5650361 --- /dev/null +++ b/packages/api/src/nitro/room/object/data/type/VoteDataType.ts @@ -0,0 +1,66 @@ +import { IMessageDataWrapper } from '../../../../../communication'; +import { IRoomObjectModel } from '../../../../../room'; +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; + } +} diff --git a/packages/api/src/nitro/room/object/data/type/index.ts b/packages/api/src/nitro/room/object/data/type/index.ts new file mode 100644 index 0000000..6f81bc5 --- /dev/null +++ b/packages/api/src/nitro/room/object/data/type/index.ts @@ -0,0 +1,9 @@ +export * from './CrackableDataType'; +export * from './EmptyDataType'; +export * from './HighScoreData'; +export * from './HighScoreDataType'; +export * from './LegacyDataType'; +export * from './MapDataType'; +export * from './NumberDataType'; +export * from './StringDataType'; +export * from './VoteDataType'; diff --git a/packages/api/src/nitro/room/object/index.ts b/packages/api/src/nitro/room/object/index.ts new file mode 100644 index 0000000..b2bff00 --- /dev/null +++ b/packages/api/src/nitro/room/object/index.ts @@ -0,0 +1,11 @@ +export * from './data'; +export * from './data/type'; +export * from './IPetFigureData'; +export * from './IRoomMapData'; +export * from './RoomObjectCategory'; +export * from './RoomObjectLogicType'; +export * from './RoomObjectOperationType'; +export * from './RoomObjectType'; +export * from './RoomObjectUserType'; +export * from './RoomObjectVariable'; +export * from './RoomObjectVisualizationType'; diff --git a/packages/api/src/nitro/room/utils/IFurnitureStackingHeightMap.ts b/packages/api/src/nitro/room/utils/IFurnitureStackingHeightMap.ts new file mode 100644 index 0000000..5427932 --- /dev/null +++ b/packages/api/src/nitro/room/utils/IFurnitureStackingHeightMap.ts @@ -0,0 +1,11 @@ +export interface IFurnitureStackingHeightMap +{ + dispose: () => void; + getTileHeight(x: number, y: number): number; + setTileHeight(x: number, y: number, height: number): void; + setStackingBlocked(x: number, y: number, isNotStackable: boolean): void; + setIsRoomTile(x: number, y: number, isRoomTile: boolean): void; + 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): boolean; + readonly width: number; + readonly height: number; +} diff --git a/packages/api/src/nitro/room/utils/ILegacyWallGeometry.ts b/packages/api/src/nitro/room/utils/ILegacyWallGeometry.ts new file mode 100644 index 0000000..e3aab44 --- /dev/null +++ b/packages/api/src/nitro/room/utils/ILegacyWallGeometry.ts @@ -0,0 +1,18 @@ +import { IVector3D } from '../../../utils'; + +export interface ILegacyWallGeometry +{ + dispose: () => void; + readonly disposed: boolean; + scale: number; + initialize(width: number, height: number, floorHeight: number): void; + setHeight(x: number, y: number, height: number): boolean; + getHeight(x: number, y: number): number; + getLocation(k: number, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: string): IVector3D; + getLocationOldFormat(k: number, _arg_2: number, _arg_3: string): IVector3D; + getOldLocation(k: IVector3D, _arg_2: number): [number, number, number, number, string]; + getOldLocationString(k: IVector3D, _arg_2: number): string; + getDirection(k: string): number; + getFloorAltitude(k: number, _arg_2: number): number; + isRoomTile(k: number, _arg_2: number): boolean; +} diff --git a/packages/api/src/nitro/room/utils/ITileObjectMap.ts b/packages/api/src/nitro/room/utils/ITileObjectMap.ts new file mode 100644 index 0000000..b7fda05 --- /dev/null +++ b/packages/api/src/nitro/room/utils/ITileObjectMap.ts @@ -0,0 +1,11 @@ +import { IRoomObject } from '../../../room'; + +export interface ITileObjectMap +{ + clear(): void; + populate(k: IRoomObject[]): void; + dispose(): void; + getObjectIntTile(k: number, _arg_2: number): IRoomObject; + setObjectInTile(k: number, _arg_2: number, _arg_3: IRoomObject): void; + addRoomObject(k: IRoomObject): void; +} diff --git a/packages/api/src/nitro/room/utils/ObjectRolling.ts b/packages/api/src/nitro/room/utils/ObjectRolling.ts new file mode 100644 index 0000000..93d2ca3 --- /dev/null +++ b/packages/api/src/nitro/room/utils/ObjectRolling.ts @@ -0,0 +1,40 @@ +import { IVector3D } from '../../../utils'; + +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; + } +} diff --git a/packages/api/src/nitro/room/utils/index.ts b/packages/api/src/nitro/room/utils/index.ts new file mode 100644 index 0000000..e8d1668 --- /dev/null +++ b/packages/api/src/nitro/room/utils/index.ts @@ -0,0 +1,4 @@ +export * from './IFurnitureStackingHeightMap'; +export * from './ILegacyWallGeometry'; +export * from './ITileObjectMap'; +export * from './ObjectRolling'; diff --git a/packages/api/src/nitro/session/BreedingPetInfo.ts b/packages/api/src/nitro/session/BreedingPetInfo.ts new file mode 100644 index 0000000..c3ff6c4 --- /dev/null +++ b/packages/api/src/nitro/session/BreedingPetInfo.ts @@ -0,0 +1,55 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class BreedingPetInfo +{ + private _webId: number; + private _name: string; + private _level: number; + private _figure: string; + private _owner: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._webId = wrapper.readInt(); + this._name = wrapper.readString(); + this._level = wrapper.readInt(); + this._figure = wrapper.readString(); + this._owner = wrapper.readString(); + } + + public dispose(): void + { + this._webId = 0; + this._name = ''; + this._level = 0; + this._figure = ''; + this._owner = ''; + } + + public get webId(): number + { + return this._webId; + } + + 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; + } +} diff --git a/packages/api/src/nitro/session/FurnitureType.ts b/packages/api/src/nitro/session/FurnitureType.ts new file mode 100644 index 0000000..7f8aff0 --- /dev/null +++ b/packages/api/src/nitro/session/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/packages/api/src/nitro/session/IFurnitureData.ts b/packages/api/src/nitro/session/IFurnitureData.ts new file mode 100644 index 0000000..0ebc9c7 --- /dev/null +++ b/packages/api/src/nitro/session/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/packages/api/src/nitro/session/IFurnitureDataListener.ts b/packages/api/src/nitro/session/IFurnitureDataListener.ts new file mode 100644 index 0000000..e94ec16 --- /dev/null +++ b/packages/api/src/nitro/session/IFurnitureDataListener.ts @@ -0,0 +1,4 @@ +export interface IFurnitureDataListener +{ + loadFurnitureData(): void; +} \ No newline at end of file diff --git a/packages/api/src/nitro/session/IGroupInformationManager.ts b/packages/api/src/nitro/session/IGroupInformationManager.ts new file mode 100644 index 0000000..4304483 --- /dev/null +++ b/packages/api/src/nitro/session/IGroupInformationManager.ts @@ -0,0 +1,5 @@ +export interface IGroupInformationManager +{ + init(): void; + getGroupBadge(groupId: number): string; +} diff --git a/packages/api/src/nitro/session/IIgnoredUsersManager.ts b/packages/api/src/nitro/session/IIgnoredUsersManager.ts new file mode 100644 index 0000000..aa065b3 --- /dev/null +++ b/packages/api/src/nitro/session/IIgnoredUsersManager.ts @@ -0,0 +1,9 @@ +export interface IIgnoredUsersManager +{ + init(): void; + requestIgnoredUsers(username: string): void; + ignoreUserId(id: number): void; + ignoreUser(name: string): void; + unignoreUser(name: string): void; + isIgnored(name: string): boolean; +} diff --git a/packages/api/src/nitro/session/IPetCustomPart.ts b/packages/api/src/nitro/session/IPetCustomPart.ts new file mode 100644 index 0000000..8d4f968 --- /dev/null +++ b/packages/api/src/nitro/session/IPetCustomPart.ts @@ -0,0 +1,6 @@ +export interface IPetCustomPart +{ + layerId: number; + partId: number; + paletteId: number; +} diff --git a/packages/api/src/nitro/session/IPollChoice.ts b/packages/api/src/nitro/session/IPollChoice.ts new file mode 100644 index 0000000..e645676 --- /dev/null +++ b/packages/api/src/nitro/session/IPollChoice.ts @@ -0,0 +1,6 @@ +export interface IPollChoice +{ + value: string; + choiceText: string; + choiceType: number; +} diff --git a/packages/api/src/nitro/session/IPollQuestion.ts b/packages/api/src/nitro/session/IPollQuestion.ts new file mode 100644 index 0000000..d85fd9f --- /dev/null +++ b/packages/api/src/nitro/session/IPollQuestion.ts @@ -0,0 +1,14 @@ +import { IPollChoice } from './IPollChoice'; + +export interface IPollQuestion +{ + questionId: number; + questionType: number; + sortOrder: number; + questionText: string; + questionCategory: number; + questionAnswerType: number; + questionAnswerCount: number; + children: IPollQuestion[]; + questionChoices: IPollChoice[]; +} diff --git a/packages/api/src/nitro/session/IProductData.ts b/packages/api/src/nitro/session/IProductData.ts new file mode 100644 index 0000000..95cf4d1 --- /dev/null +++ b/packages/api/src/nitro/session/IProductData.ts @@ -0,0 +1,6 @@ +export interface IProductData +{ + type: string; + name: string; + description: string; +} diff --git a/packages/api/src/nitro/session/IProductDataListener.ts b/packages/api/src/nitro/session/IProductDataListener.ts new file mode 100644 index 0000000..2d0c4eb --- /dev/null +++ b/packages/api/src/nitro/session/IProductDataListener.ts @@ -0,0 +1,6 @@ +import { IDisposable } from '../../common'; + +export interface IProductDataListener extends IDisposable +{ + loadProductData(): void; +} diff --git a/packages/api/src/nitro/session/IQuestion.ts b/packages/api/src/nitro/session/IQuestion.ts new file mode 100644 index 0000000..fdd1b3f --- /dev/null +++ b/packages/api/src/nitro/session/IQuestion.ts @@ -0,0 +1,12 @@ +export interface IQuestion +{ + id: number; + number: number; + type: number; + content: string; + selection_min?: number; + selections?: string[]; + selection_values?: string[]; + selection_count?: number; + selection_max?: number; +} diff --git a/packages/api/src/nitro/session/IRoomHandlerListener.ts b/packages/api/src/nitro/session/IRoomHandlerListener.ts new file mode 100644 index 0000000..affd923 --- /dev/null +++ b/packages/api/src/nitro/session/IRoomHandlerListener.ts @@ -0,0 +1,8 @@ +import { IRoomSession } from './IRoomSession'; + +export interface IRoomHandlerListener +{ + getSession(id: number): IRoomSession; + sessionUpdate(id: number, type: string): void; + sessionReinitialize(fromRoomId: number, toRoomId: number): void; +} diff --git a/packages/api/src/nitro/session/IRoomModerationSettings.ts b/packages/api/src/nitro/session/IRoomModerationSettings.ts new file mode 100644 index 0000000..bf9428c --- /dev/null +++ b/packages/api/src/nitro/session/IRoomModerationSettings.ts @@ -0,0 +1,6 @@ +export interface IRoomModerationSettings +{ + readonly allowMute: number; + readonly allowKick: number; + readonly allowBan: number; +} diff --git a/packages/api/src/nitro/session/IRoomPetData.ts b/packages/api/src/nitro/session/IRoomPetData.ts new file mode 100644 index 0000000..70dfbbc --- /dev/null +++ b/packages/api/src/nitro/session/IRoomPetData.ts @@ -0,0 +1,30 @@ +export interface IRoomPetData +{ + id: number; + level: number; + maximumLevel: number; + experience: number; + levelExperienceGoal: number; + energy: number; + maximumEnergy: number; + happyness: number; + maximumHappyness: number; + ownerId: number; + ownerName: string; + respect: number; + age: number; + unknownRarity: number; + saddle: boolean; + rider: boolean; + skillTresholds: number[]; + publiclyRideable: number; + breedable: boolean; + fullyGrown: boolean; + dead: boolean; + rarityLevel: number; + maximumTimeToLive: number; + remainingTimeToLive: number; + remainingGrowTime: number; + publiclyBreedable: boolean; + readonly adultLevel: number; +} diff --git a/packages/api/src/nitro/session/IRoomSession.ts b/packages/api/src/nitro/session/IRoomSession.ts new file mode 100644 index 0000000..371ac1e --- /dev/null +++ b/packages/api/src/nitro/session/IRoomSession.ts @@ -0,0 +1,64 @@ +import { IRoomModerationSettings } from './IRoomModerationSettings'; +import { IUserDataManager } from './IUserDataManager'; + +export interface IRoomSession +{ + openGift(objectId: number): 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; + sendPollStartMessage(pollId: number): void; + sendPollRejectMessage(pollId: number): void; + sendPollAnswerMessage(pollId: number, questionId: number, answers: string[]): void; + votePoll(counter: number): void; + sendPeerUsersClassificationMessage(userClassType: string): void; + sendRoomUsersClassificationMessage(userClassType: string): void; + updateMoodlightData(id: number, effectId: number, color: number, brightness: number, apply: boolean): void; + toggleMoodlightState(): void; + pickupPet(id: number): void; + pickupBot(id: number): void; + requestMoodlightSettings(): void; + mountPet(id: number): void; + dismountPet(id: number): void; + usePetProduct(itemId: number, petId: number): void; + removePetSaddle(id: number): void; + togglePetBreeding(id: number): void; + togglePetRiding(id: number): void; + useMultistateItem(id: number): void; + harvestPet(id: number): void; + compostPlant(id: number): void; + requestPetCommands(id: number): void; + sendScriptProceed(): void; + userDataManager: IUserDataManager; + roomId: number; + state: string; + tradeMode: number; + isPrivateRoom: boolean; + doorMode: number; + allowPets: boolean; + controllerLevel: number; + ownRoomIndex: number; + isGuildRoom: boolean; + isRoomOwner: boolean; + isDecorating: boolean; + isSpectator: boolean; + moderationSettings: IRoomModerationSettings; +} diff --git a/packages/api/src/nitro/session/IRoomSessionManager.ts b/packages/api/src/nitro/session/IRoomSessionManager.ts new file mode 100644 index 0000000..546df80 --- /dev/null +++ b/packages/api/src/nitro/session/IRoomSessionManager.ts @@ -0,0 +1,11 @@ +import { IRoomSession } from './IRoomSession'; + +export interface IRoomSessionManager +{ + init(): Promise; + getSession(id: number): IRoomSession; + createSession(roomId: number, password?: string): boolean; + startSession(session: IRoomSession): boolean; + removeSession(id: number, openLandingView?: boolean): void; + viewerSession: IRoomSession; +} diff --git a/packages/api/src/nitro/session/IRoomUserData.ts b/packages/api/src/nitro/session/IRoomUserData.ts new file mode 100644 index 0000000..09eaa57 --- /dev/null +++ b/packages/api/src/nitro/session/IRoomUserData.ts @@ -0,0 +1,26 @@ +export interface IRoomUserData +{ + readonly roomIndex: number; + activityPoints: number; + name: string; + type: number; + sex: string; + figure: string; + custom: string; + webID: number; + groupId: number; + groupName: string; + groupStatus: number; + ownerId: number; + ownerName: string; + rarityLevel: number; + hasSaddle: boolean; + isRiding: boolean; + canBreed: boolean; + canHarvest: boolean; + canRevive: boolean; + hasBreedingPermission: boolean; + petLevel: number; + botSkills: number[]; + isModerator: boolean; +} diff --git a/packages/api/src/nitro/session/ISessionDataManager.ts b/packages/api/src/nitro/session/ISessionDataManager.ts new file mode 100644 index 0000000..f9079c8 --- /dev/null +++ b/packages/api/src/nitro/session/ISessionDataManager.ts @@ -0,0 +1,56 @@ +import { Texture } from 'pixi.js'; +import { ICommunicationManager } from '../../communication'; +import { IFurnitureData } from './IFurnitureData'; +import { IGroupInformationManager } from './IGroupInformationManager'; +import { IIgnoredUsersManager } from './IIgnoredUsersManager'; +import { IProductData } from './IProductData'; + +export interface ISessionDataManager +{ + init(): Promise; + getAllFurnitureData(): IFurnitureData[]; + 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; + getUserTags(roomUnitId: number): string[]; + 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; + ignoreUser(name: string): void; + unignoreUser(name: string): void; + isUserIgnored(name: string): boolean; + getGroupBadge(groupId: number): string; + communication: ICommunicationManager; + userId: number; + userName: string; + figure: string; + gender: string; + realName: string; + ignoredUsersManager: IIgnoredUsersManager; + groupInformationManager: IGroupInformationManager; + respectsReceived: number; + respectsLeft: number; + respectsPetLeft: number; + canChangeName: boolean; + clubLevel: number; + securityLevel: number; + isAmbassador: boolean; + isNoob: boolean; + isRealNoob: boolean; + isSystemOpen: boolean; + isSystemShutdown: boolean; + isAuthenticHabbo: boolean; + isModerator: boolean; + isCameraFollowDisabled: boolean; + uiFlags: number; + tags: string[]; +} diff --git a/packages/api/src/nitro/session/IUserDataManager.ts b/packages/api/src/nitro/session/IUserDataManager.ts new file mode 100644 index 0000000..a16e793 --- /dev/null +++ b/packages/api/src/nitro/session/IUserDataManager.ts @@ -0,0 +1,23 @@ +import { IRoomUserData } from './IRoomUserData'; + +export interface IUserDataManager +{ + getUserData(webID: number): IRoomUserData; + getPetData(webID: number): IRoomUserData; + getBotData(webID: number): IRoomUserData; + getRentableBotData(webID: number): IRoomUserData; + getDataByType(webID: number, type: number): IRoomUserData; + getUserDataByIndex(roomIndex: number): IRoomUserData; + getUserDataByName(name: string): IRoomUserData; + updateUserData(data: IRoomUserData): void; + removeUserData(roomIndex: number): void; + getUserBadges(userId: number): string[]; + setUserBadges(userId: number, badges: string[]): void; + updateFigure(roomIndex: number, figure: string, sex: string, hasSaddle: boolean, isRiding: boolean): void; + updateName(roomIndex: number, name: string): void; + updateMotto(roomIndex: number, custom: string): void; + updateAchievementScore(roomIndex: number, score: number): void; + updatePetLevel(roomIndex: number, level: number): void; + updatePetBreedingStatus(roomIndex: number, canBreed: boolean, canHarvest: boolean, canRevive: boolean, hasBreedingPermission: boolean): void; + requestPetInfo(id: number): void; +} diff --git a/packages/api/src/nitro/session/PetBreedingResultData.ts b/packages/api/src/nitro/session/PetBreedingResultData.ts new file mode 100644 index 0000000..5b9514a --- /dev/null +++ b/packages/api/src/nitro/session/PetBreedingResultData.ts @@ -0,0 +1,58 @@ +import { IMessageDataWrapper, IPetBreedingResultData } from '@nitrots/api'; + +export class PetBreedingResultData implements IPetBreedingResultData +{ + private _stuffId: number; + private _classId: number; + private _productCode: string; + private _userId: number; + private _userName: string; + private _rarityLevel: number; + private _hasMutation: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + this._stuffId = wrapper.readInt(); + this._classId = wrapper.readInt(); + this._productCode = wrapper.readString(); + this._userId = wrapper.readInt(); + this._userName = wrapper.readString(); + this._rarityLevel = wrapper.readInt(); + this._hasMutation = wrapper.readBoolean(); + } + + public get stuffId(): number + { + return this._stuffId; + } + + public get classId(): number + { + return this._classId; + } + + public get productCode(): string + { + return this._productCode; + } + + public get userId(): number + { + return this._userId; + } + + public get userName(): string + { + return this._userName; + } + + public get rarityLevel(): number + { + return this._rarityLevel; + } + + public get hasMutation(): boolean + { + return this._hasMutation; + } +} diff --git a/packages/api/src/nitro/session/PetCustomPart.ts b/packages/api/src/nitro/session/PetCustomPart.ts new file mode 100644 index 0000000..9498e12 --- /dev/null +++ b/packages/api/src/nitro/session/PetCustomPart.ts @@ -0,0 +1,45 @@ +import { IPetCustomPart } from './IPetCustomPart'; + +export class PetCustomPart implements IPetCustomPart +{ + 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; + } +} diff --git a/packages/api/src/nitro/session/PetFigureData.ts b/packages/api/src/nitro/session/PetFigureData.ts new file mode 100644 index 0000000..ff586be --- /dev/null +++ b/packages/api/src/nitro/session/PetFigureData.ts @@ -0,0 +1,229 @@ +import { IPetCustomPart } from './IPetCustomPart'; +import { PetCustomPart } from './PetCustomPart'; + +export class PetFigureData +{ + private _typeId: number; + private _paletteId: number; + private _color: number; + private _headOnly: boolean; + + private _customParts: IPetCustomPart[]; + 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(): IPetCustomPart[] + { + return this._customParts; + } + + public getCustomPart(k: number): IPetCustomPart + { + 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; + } +} diff --git a/packages/api/src/nitro/session/RarityCategoryData.ts b/packages/api/src/nitro/session/RarityCategoryData.ts new file mode 100644 index 0000000..f9eb994 --- /dev/null +++ b/packages/api/src/nitro/session/RarityCategoryData.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class RarityCategoryData +{ + private _chance: number; + private _breeds: number[]; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._chance = wrapper.readInt(); + this._breeds = []; + + let totalCount = wrapper.readInt(); + + while(totalCount > 0) + { + this._breeds.push(wrapper.readInt()); + + totalCount--; + } + } + + public dispose(): void + { + this._chance = -1; + this._breeds = []; + } + + public get chance(): number + { + return this._chance; + } + + public get breeds(): number[] + { + return this._breeds; + } +} diff --git a/packages/api/src/nitro/session/enum/GenericErrorEnum.ts b/packages/api/src/nitro/session/enum/GenericErrorEnum.ts new file mode 100644 index 0000000..611139b --- /dev/null +++ b/packages/api/src/nitro/session/enum/GenericErrorEnum.ts @@ -0,0 +1,5 @@ +export class GenericErrorEnum +{ + public static KICKED_OUT_OF_ROOM: number = 4008; + public static STRIP_LOCKED_FOR_TRADING: number = -13001; +} diff --git a/packages/api/src/nitro/session/enum/NoobnessLevelEnum.ts b/packages/api/src/nitro/session/enum/NoobnessLevelEnum.ts new file mode 100644 index 0000000..c9aecaf --- /dev/null +++ b/packages/api/src/nitro/session/enum/NoobnessLevelEnum.ts @@ -0,0 +1,6 @@ +export class NoobnessLevelEnum +{ + public static OLD_IDENTITY: number = 0; + public static NEW_IDENTITY: number = 1; + public static REAL_NOOB: number = 2; +} diff --git a/packages/api/src/nitro/session/enum/PetType.ts b/packages/api/src/nitro/session/enum/PetType.ts new file mode 100644 index 0000000..9058b7b --- /dev/null +++ b/packages/api/src/nitro/session/enum/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/packages/api/src/nitro/session/enum/RoomControllerLevel.ts b/packages/api/src/nitro/session/enum/RoomControllerLevel.ts new file mode 100644 index 0000000..ecd6309 --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/session/enum/RoomTradingLevelEnum.ts b/packages/api/src/nitro/session/enum/RoomTradingLevelEnum.ts new file mode 100644 index 0000000..be0b1e4 --- /dev/null +++ b/packages/api/src/nitro/session/enum/RoomTradingLevelEnum.ts @@ -0,0 +1,22 @@ +export class RoomTradingLevelEnum +{ + public static NO_TRADING: number = 0; + public static ROOM_CONTROLLER_REQUIRED: number = 1; + public static FREE_TRADING: number = 2; + + + public static getLocalizationKey(k: number): string + { + switch(k) + { + case RoomTradingLevelEnum.FREE_TRADING: + return '${trading.mode.free}'; + case RoomTradingLevelEnum.ROOM_CONTROLLER_REQUIRED: + return '${trading.mode.controller}'; + case RoomTradingLevelEnum.NO_TRADING: + return '${trading.mode.not.allowed}'; + } + + return ''; + } +} diff --git a/packages/api/src/nitro/session/enum/SecurityLevel.ts b/packages/api/src/nitro/session/enum/SecurityLevel.ts new file mode 100644 index 0000000..9b3011e --- /dev/null +++ b/packages/api/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/packages/api/src/nitro/session/enum/index.ts b/packages/api/src/nitro/session/enum/index.ts new file mode 100644 index 0000000..4d97ae9 --- /dev/null +++ b/packages/api/src/nitro/session/enum/index.ts @@ -0,0 +1,6 @@ +export * from './GenericErrorEnum'; +export * from './NoobnessLevelEnum'; +export * from './PetType'; +export * from './RoomControllerLevel'; +export * from './RoomTradingLevelEnum'; +export * from './SecurityLevel'; diff --git a/packages/api/src/nitro/session/index.ts b/packages/api/src/nitro/session/index.ts new file mode 100644 index 0000000..1fe774d --- /dev/null +++ b/packages/api/src/nitro/session/index.ts @@ -0,0 +1,25 @@ +export * from './BreedingPetInfo'; +export * from './FurnitureType'; +export * from './IFurnitureData'; +export * from './IFurnitureDataListener'; +export * from './IGroupInformationManager'; +export * from './IIgnoredUsersManager'; +export * from './IPetCustomPart'; +export * from './IPollChoice'; +export * from './IPollQuestion'; +export * from './IProductData'; +export * from './IProductDataListener'; +export * from './IQuestion'; +export * from './IRoomHandlerListener'; +export * from './IRoomModerationSettings'; +export * from './IRoomPetData'; +export * from './IRoomSession'; +export * from './IRoomSessionManager'; +export * from './IRoomUserData'; +export * from './ISessionDataManager'; +export * from './IUserDataManager'; +export * from './PetBreedingResultData'; +export * from './PetCustomPart'; +export * from './PetFigureData'; +export * from './RarityCategoryData'; +export * from './enum'; diff --git a/packages/api/src/nitro/sound/IMusicController.ts b/packages/api/src/nitro/sound/IMusicController.ts new file mode 100644 index 0000000..8166f15 --- /dev/null +++ b/packages/api/src/nitro/sound/IMusicController.ts @@ -0,0 +1,25 @@ +import { IAdvancedMap } from '../../utils'; +import { IPlaylistController } from './IPlaylistController'; +import { ISongInfo } from './ISongInfo'; + +export interface IMusicController +{ + getRoomItemPlaylist(_arg_1?: number): IPlaylistController; + getSongDiskInventorySize(): number; + getSongDiskInventoryDiskId(_arg_1: number): number; + getSongDiskInventorySongId(_arg_1: number): number; + getSongInfo(songId: number): ISongInfo; + getSongIdPlayingAtPriority(_arg_1: number): number; + playSong(songId: number, priority: number, startPos?: number, playLength?: number, fadeInSeconds?: number, fadeOutSeconds?: number): boolean; + stop(priority: number): void; + addSongInfoRequest(_arg_1: number): void; + requestSongInfoWithoutSamples(_arg_1: number): void; + requestUserSongDisks(): void; + onSongLoaded(_arg_1: number): void; + updateVolume(_arg_1: number): void; + samplesUnloaded(_arg_1: number[]): void; + get samplesIdsInUse(): number[]; + get songDiskInventory(): IAdvancedMap + init(): void; + dispose(): void; +} diff --git a/packages/api/src/nitro/sound/IPlaylistController.ts b/packages/api/src/nitro/sound/IPlaylistController.ts new file mode 100644 index 0000000..3466544 --- /dev/null +++ b/packages/api/src/nitro/sound/IPlaylistController.ts @@ -0,0 +1,16 @@ +import { ISongInfo } from './ISongInfo'; + +export interface IPlaylistController +{ + init(): void; + dispose(): void; + stopPlaying(): void; + getEntry(index: number): ISongInfo; + requestPlayList(): void; + get priority(): number; + get length(): number; + get playPosition(): number; + get currentSongId(): number; + get isPlaying(): boolean; + get entries(): ISongInfo[]; +} diff --git a/packages/api/src/nitro/sound/ISongInfo.ts b/packages/api/src/nitro/sound/ISongInfo.ts new file mode 100644 index 0000000..475b75d --- /dev/null +++ b/packages/api/src/nitro/sound/ISongInfo.ts @@ -0,0 +1,12 @@ +export interface ISongInfo +{ + //get loaded():boolean; + get id():number; + get diskId():number; + set diskId(id: number); + get length():number; + get name():string; + get creator():string; + get songData():string; + //get soundObject():IHabboSound; +} diff --git a/packages/api/src/nitro/sound/ISoundManager.ts b/packages/api/src/nitro/sound/ISoundManager.ts new file mode 100644 index 0000000..87714b5 --- /dev/null +++ b/packages/api/src/nitro/sound/ISoundManager.ts @@ -0,0 +1,8 @@ +import { IMusicController } from './IMusicController'; + +export interface ISoundManager +{ + init(): Promise; + musicController: IMusicController; + traxVolume: number; +} diff --git a/packages/api/src/nitro/sound/index.ts b/packages/api/src/nitro/sound/index.ts new file mode 100644 index 0000000..be4bfe4 --- /dev/null +++ b/packages/api/src/nitro/sound/index.ts @@ -0,0 +1,4 @@ +export * from './IMusicController'; +export * from './IPlaylistController'; +export * from './ISongInfo'; +export * from './ISoundManager'; diff --git a/packages/api/src/room/IPetBreedingResultData.ts b/packages/api/src/room/IPetBreedingResultData.ts new file mode 100644 index 0000000..b3f8985 --- /dev/null +++ b/packages/api/src/room/IPetBreedingResultData.ts @@ -0,0 +1,10 @@ +export interface IPetBreedingResultData +{ + readonly stuffId: number; + readonly classId: number; + readonly productCode: string; + readonly userId: number; + readonly userName: string; + readonly rarityLevel: number; + readonly hasMutation: boolean; +} diff --git a/packages/api/src/room/IRoomGeometry.ts b/packages/api/src/room/IRoomGeometry.ts new file mode 100644 index 0000000..c4e32c8 --- /dev/null +++ b/packages/api/src/room/IRoomGeometry.ts @@ -0,0 +1,21 @@ +import { Point } from 'pixi.js'; +import { IVector3D } from '../utils'; + +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; +} diff --git a/packages/api/src/room/IRoomInstance.ts b/packages/api/src/room/IRoomInstance.ts new file mode 100644 index 0000000..367ccef --- /dev/null +++ b/packages/api/src/room/IRoomInstance.ts @@ -0,0 +1,27 @@ +import { IRoomInstanceContainer } from './IRoomInstanceContainer'; +import { IRoomObjectManager } from './IRoomObjectManager'; +import { IRoomObject, IRoomObjectModel } from './object'; +import { IRoomRendererBase } from './renderer'; + +export interface IRoomInstance +{ + dispose(): void; + 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; +} diff --git a/packages/api/src/room/IRoomInstanceContainer.ts b/packages/api/src/room/IRoomInstanceContainer.ts new file mode 100644 index 0000000..efe5184 --- /dev/null +++ b/packages/api/src/room/IRoomInstanceContainer.ts @@ -0,0 +1,8 @@ +import { IRoomObjectManager } from './IRoomObjectManager'; +import { IRoomObject } from './object'; + +export interface IRoomInstanceContainer +{ + createRoomObjectAndInitalize(roomId: string, objectId: number, type: string, category: number): IRoomObject; + createRoomObjectManager(category: number): IRoomObjectManager; +} diff --git a/packages/api/src/room/IRoomManager.ts b/packages/api/src/room/IRoomManager.ts new file mode 100644 index 0000000..019a1a2 --- /dev/null +++ b/packages/api/src/room/IRoomManager.ts @@ -0,0 +1,16 @@ +import { IRoomInstance } from './IRoomInstance'; +import { IRoomManagerListener } from './IRoomManagerListener'; +import { IRoomObject } from './object'; + +export interface IRoomManager +{ + init(listener: IRoomManagerListener): Promise; + 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; + update(time: number, update?: boolean): void; + rooms: Map; +} diff --git a/packages/api/src/room/IRoomManagerListener.ts b/packages/api/src/room/IRoomManagerListener.ts new file mode 100644 index 0000000..aa46e8d --- /dev/null +++ b/packages/api/src/room/IRoomManagerListener.ts @@ -0,0 +1,5 @@ +export interface IRoomManagerListener +{ + objectInitialized(roomId: string, objectId: number, category: number): void; + initalizeTemporaryObjectsByType(type: string, _arg_2: boolean): void; +} diff --git a/packages/api/src/room/IRoomObjectManager.ts b/packages/api/src/room/IRoomObjectManager.ts new file mode 100644 index 0000000..9e0ea3b --- /dev/null +++ b/packages/api/src/room/IRoomObjectManager.ts @@ -0,0 +1,14 @@ +import { IAdvancedMap } from '../utils'; +import { IRoomObjectController } from './object'; + +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: IAdvancedMap; + totalObjects: number; +} diff --git a/packages/api/src/room/IRoomObjectUpdateMessage.ts b/packages/api/src/room/IRoomObjectUpdateMessage.ts new file mode 100644 index 0000000..2125e30 --- /dev/null +++ b/packages/api/src/room/IRoomObjectUpdateMessage.ts @@ -0,0 +1,7 @@ +import { IVector3D } from '../utils/IVector3D'; + +export interface IRoomObjectUpdateMessage +{ + readonly location: IVector3D; + readonly direction: IVector3D; +} diff --git a/packages/api/src/room/IRoomSpriteMouseEvent.ts b/packages/api/src/room/IRoomSpriteMouseEvent.ts new file mode 100644 index 0000000..c942d6c --- /dev/null +++ b/packages/api/src/room/IRoomSpriteMouseEvent.ts @@ -0,0 +1,17 @@ +export interface IRoomSpriteMouseEvent +{ + readonly type: string; + readonly eventId: string; + readonly canvasId: string; + readonly spriteTag: string; + readonly screenX: number; + readonly screenY: number; + readonly localX: number; + readonly localY: number; + readonly ctrlKey: boolean; + readonly altKey: boolean; + readonly shiftKey: boolean; + readonly buttonDown: boolean; + spriteOffsetX: number; + spriteOffsetY: number; +} diff --git a/packages/api/src/room/RoomObjectSpriteData.ts b/packages/api/src/room/RoomObjectSpriteData.ts new file mode 100644 index 0000000..768cae2 --- /dev/null +++ b/packages/api/src/room/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/packages/api/src/room/index.ts b/packages/api/src/room/index.ts new file mode 100644 index 0000000..31d8d76 --- /dev/null +++ b/packages/api/src/room/index.ts @@ -0,0 +1,15 @@ +export * from './IPetBreedingResultData'; +export * from './IRoomGeometry'; +export * from './IRoomInstance'; +export * from './IRoomInstanceContainer'; +export * from './IRoomManager'; +export * from './IRoomManagerListener'; +export * from './IRoomObjectManager'; +export * from './IRoomObjectUpdateMessage'; +export * from './IRoomSpriteMouseEvent'; +export * from './RoomObjectSpriteData'; +export * from './object'; +export * from './object/enum'; +export * from './object/logic'; +export * from './object/visualization'; +export * from './renderer'; diff --git a/packages/api/src/room/object/IRoomObject.ts b/packages/api/src/room/object/IRoomObject.ts new file mode 100644 index 0000000..de5674d --- /dev/null +++ b/packages/api/src/room/object/IRoomObject.ts @@ -0,0 +1,22 @@ +import { IVector3D } from '../../utils'; +import { IRoomObjectModel } from './IRoomObjectModel'; +import { IRoomObjectMouseHandler } from './logic'; +import { IRoomObjectVisualization } from './visualization'; + +export interface IRoomObject +{ + dispose(): void; + 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; +} diff --git a/packages/api/src/room/object/IRoomObjectController.ts b/packages/api/src/room/object/IRoomObjectController.ts new file mode 100644 index 0000000..c522a26 --- /dev/null +++ b/packages/api/src/room/object/IRoomObjectController.ts @@ -0,0 +1,18 @@ +import { IVector3D } from '../../utils'; +import { IRoomObjectUpdateMessage } from '../IRoomObjectUpdateMessage'; +import { IRoomObject } from './IRoomObject'; +import { IRoomObjectEventHandler } from './logic'; +import { IRoomObjectGraphicVisualization } from './visualization'; + +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: IRoomObjectUpdateMessage): void; + tearDown(): void; + isReady: boolean; + logic: IRoomObjectEventHandler; +} diff --git a/packages/api/src/room/object/IRoomObjectModel.ts b/packages/api/src/room/object/IRoomObjectModel.ts new file mode 100644 index 0000000..64291ed --- /dev/null +++ b/packages/api/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/packages/api/src/room/object/IRoomObjectModelController.ts b/packages/api/src/room/object/IRoomObjectModelController.ts new file mode 100644 index 0000000..2dc6fbc --- /dev/null +++ b/packages/api/src/room/object/IRoomObjectModelController.ts @@ -0,0 +1,11 @@ +import { IAdvancedMap } from '../../utils'; +import { IRoomObjectModel } from './IRoomObjectModel'; + +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: IAdvancedMap, _arg_3: boolean): void; +} diff --git a/packages/api/src/room/object/enum/AlphaTolerance.ts b/packages/api/src/room/object/enum/AlphaTolerance.ts new file mode 100644 index 0000000..94b695e --- /dev/null +++ b/packages/api/src/room/object/enum/AlphaTolerance.ts @@ -0,0 +1,6 @@ +export class AlphaTolerance +{ + public static MATCH_ALL_PIXELS: number = -1; + public static MATCH_OPAQUE_PIXELS: number = 128; + public static MATCH_NOTHING: number = 256; +} diff --git a/packages/api/src/room/object/enum/RoomObjectSpriteType.ts b/packages/api/src/room/object/enum/RoomObjectSpriteType.ts new file mode 100644 index 0000000..ec4f953 --- /dev/null +++ b/packages/api/src/room/object/enum/RoomObjectSpriteType.ts @@ -0,0 +1,7 @@ +export class RoomObjectSpriteType +{ + public static DEFAULT: number = 1; + public static ROOM_PLANE: number = 2; + public static AVATAR: number = 3; + public static AVATAR_OWN: number = 4; +} diff --git a/packages/api/src/room/object/enum/index.ts b/packages/api/src/room/object/enum/index.ts new file mode 100644 index 0000000..b648257 --- /dev/null +++ b/packages/api/src/room/object/enum/index.ts @@ -0,0 +1,2 @@ +export * from './AlphaTolerance'; +export * from './RoomObjectSpriteType'; diff --git a/packages/api/src/room/object/index.ts b/packages/api/src/room/object/index.ts new file mode 100644 index 0000000..7d028eb --- /dev/null +++ b/packages/api/src/room/object/index.ts @@ -0,0 +1,7 @@ +export * from './enum'; +export * from './IRoomObject'; +export * from './IRoomObjectController'; +export * from './IRoomObjectModel'; +export * from './IRoomObjectModelController'; +export * from './logic'; +export * from './visualization'; diff --git a/packages/api/src/room/object/logic/IRoomObjectEventHandler.ts b/packages/api/src/room/object/logic/IRoomObjectEventHandler.ts new file mode 100644 index 0000000..8fab317 --- /dev/null +++ b/packages/api/src/room/object/logic/IRoomObjectEventHandler.ts @@ -0,0 +1,20 @@ +import { IEventDispatcher } from '../../../common'; +import { IRoomObjectUpdateMessage } from '../../IRoomObjectUpdateMessage'; +import { IRoomObjectController } from '../IRoomObjectController'; +import { IRoomObjectMouseHandler } from './IRoomObjectMouseHandler'; + +export interface IRoomObjectEventHandler extends IRoomObjectMouseHandler +{ + initialize(data: unknown): void; + dispose(): void; + update(totalTimeRunning: number): void; + processUpdateMessage(message: IRoomObjectUpdateMessage): void; + getEventTypes(): string[]; + useObject(): void; + setObject(object: IRoomObjectController): void; + tearDown(): void; + object: IRoomObjectController; + eventDispatcher: IEventDispatcher; + widget: string; + contextMenu: string; +} diff --git a/packages/api/src/room/object/logic/IRoomObjectLogicFactory.ts b/packages/api/src/room/object/logic/IRoomObjectLogicFactory.ts new file mode 100644 index 0000000..d65ed55 --- /dev/null +++ b/packages/api/src/room/object/logic/IRoomObjectLogicFactory.ts @@ -0,0 +1,10 @@ +import { IEventDispatcher, INitroEvent } from '../../../common'; +import { IRoomObjectEventHandler } from './IRoomObjectEventHandler'; + +export interface IRoomObjectLogicFactory +{ + getLogic(type: string): IRoomObjectEventHandler; + registerEventFunction(func: (event: INitroEvent) => void): void; + removeEventFunction(func: (event: INitroEvent) => void): void; + events: IEventDispatcher; +} diff --git a/packages/api/src/room/object/logic/IRoomObjectMouseHandler.ts b/packages/api/src/room/object/logic/IRoomObjectMouseHandler.ts new file mode 100644 index 0000000..4240c56 --- /dev/null +++ b/packages/api/src/room/object/logic/IRoomObjectMouseHandler.ts @@ -0,0 +1,7 @@ +import { IRoomGeometry } from '../../IRoomGeometry'; +import { IRoomSpriteMouseEvent } from '../../IRoomSpriteMouseEvent'; + +export interface IRoomObjectMouseHandler +{ + mouseEvent(event: IRoomSpriteMouseEvent, geometry: IRoomGeometry): void; +} diff --git a/packages/api/src/room/object/logic/index.ts b/packages/api/src/room/object/logic/index.ts new file mode 100644 index 0000000..5892efe --- /dev/null +++ b/packages/api/src/room/object/logic/index.ts @@ -0,0 +1,3 @@ +export * from './IRoomObjectEventHandler'; +export * from './IRoomObjectLogicFactory'; +export * from './IRoomObjectMouseHandler'; diff --git a/packages/api/src/room/object/visualization/IPlaneDrawingData.ts b/packages/api/src/room/object/visualization/IPlaneDrawingData.ts new file mode 100644 index 0000000..8a67219 --- /dev/null +++ b/packages/api/src/room/object/visualization/IPlaneDrawingData.ts @@ -0,0 +1,14 @@ +import { Point } from 'pixi.js'; + +export interface IPlaneDrawingData +{ + isBottomAligned(): boolean; + z: number; + cornerPoints: Point[]; + color: number; + maskAssetNames: string[]; + maskAssetLocations: Point[]; + maskAssetFlipHs: boolean[]; + maskAssetFlipVs: boolean[]; + assetNameColumns: string[][]; +} diff --git a/packages/api/src/room/object/visualization/IPlaneVisualization.ts b/packages/api/src/room/object/visualization/IPlaneVisualization.ts new file mode 100644 index 0000000..65b5de2 --- /dev/null +++ b/packages/api/src/room/object/visualization/IPlaneVisualization.ts @@ -0,0 +1,6 @@ +import { IRoomPlane } from './IRoomPlane'; + +export interface IPlaneVisualization +{ + planes: IRoomPlane[]; +} diff --git a/packages/api/src/room/object/visualization/IRoomObjectGraphicVisualization.ts b/packages/api/src/room/object/visualization/IRoomObjectGraphicVisualization.ts new file mode 100644 index 0000000..8fb20d2 --- /dev/null +++ b/packages/api/src/room/object/visualization/IRoomObjectGraphicVisualization.ts @@ -0,0 +1,7 @@ +import { IGraphicAssetCollection } from '../../../asset'; +import { IRoomObjectVisualization } from './IRoomObjectVisualization'; + +export interface IRoomObjectGraphicVisualization extends IRoomObjectVisualization +{ + asset: IGraphicAssetCollection; +} diff --git a/packages/api/src/room/object/visualization/IRoomObjectSprite.ts b/packages/api/src/room/object/visualization/IRoomObjectSprite.ts new file mode 100644 index 0000000..6490044 --- /dev/null +++ b/packages/api/src/room/object/visualization/IRoomObjectSprite.ts @@ -0,0 +1,32 @@ +import { BLEND_MODES, Filter, Texture } from 'pixi.js'; + +export interface IRoomObjectSprite +{ + dispose(): void; + increaseUpdateCounter(): void; + id: number; + name: string; + type: string; + spriteType: number; + texture: Texture; + width: number; + height: number; + offsetX: number; + offsetY: number; + flipH: boolean; + flipV: boolean; + direction: number; + alpha: number; + blendMode: BLEND_MODES; + color: number; + relativeDepth: number; + varyingDepth: boolean; + libraryAssetName: string; + clickHandling: boolean; + visible: boolean; + tag: string; + posture: string; + alphaTolerance: number; + filters: Filter[]; + updateCounter: number; +} diff --git a/packages/api/src/room/object/visualization/IRoomObjectSpriteVisualization.ts b/packages/api/src/room/object/visualization/IRoomObjectSpriteVisualization.ts new file mode 100644 index 0000000..e3dd4cd --- /dev/null +++ b/packages/api/src/room/object/visualization/IRoomObjectSpriteVisualization.ts @@ -0,0 +1,12 @@ +import { RoomObjectSpriteData } from '../../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; +} diff --git a/packages/api/src/room/object/visualization/IRoomObjectVisualization.ts b/packages/api/src/room/object/visualization/IRoomObjectVisualization.ts new file mode 100644 index 0000000..9ea0228 --- /dev/null +++ b/packages/api/src/room/object/visualization/IRoomObjectVisualization.ts @@ -0,0 +1,17 @@ +import { Rectangle, Texture } from 'pixi.js'; +import { IRoomGeometry } from '../../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(): Texture; + instanceId: number; + object: IRoomObject; + image: Texture; + updateSpriteCounter: number; +} diff --git a/packages/api/src/room/object/visualization/IRoomObjectVisualizationData.ts b/packages/api/src/room/object/visualization/IRoomObjectVisualizationData.ts new file mode 100644 index 0000000..4337029 --- /dev/null +++ b/packages/api/src/room/object/visualization/IRoomObjectVisualizationData.ts @@ -0,0 +1,7 @@ +import { IAssetData } from '../../../asset'; + +export interface IObjectVisualizationData +{ + initialize(asset: IAssetData): boolean; + dispose(): void; +} diff --git a/packages/api/src/room/object/visualization/IRoomObjectVisualizationFactory.ts b/packages/api/src/room/object/visualization/IRoomObjectVisualizationFactory.ts new file mode 100644 index 0000000..a28adae --- /dev/null +++ b/packages/api/src/room/object/visualization/IRoomObjectVisualizationFactory.ts @@ -0,0 +1,9 @@ +import { IAssetData } from '../../../asset'; +import { IRoomObjectGraphicVisualization } from './IRoomObjectGraphicVisualization'; +import { IObjectVisualizationData } from './IRoomObjectVisualizationData'; + +export interface IRoomObjectVisualizationFactory +{ + getVisualization(type: string): IRoomObjectGraphicVisualization; + getVisualizationData(type: string, visualization: string, asset: IAssetData): IObjectVisualizationData; +} diff --git a/packages/api/src/room/object/visualization/IRoomPlane.ts b/packages/api/src/room/object/visualization/IRoomPlane.ts new file mode 100644 index 0000000..1cc6bc6 --- /dev/null +++ b/packages/api/src/room/object/visualization/IRoomPlane.ts @@ -0,0 +1,10 @@ +import { IVector3D } from '../../../utils'; + +export interface IRoomPlane +{ + uniqueId: number; + location: IVector3D; + leftSide: IVector3D; + rightSide: IVector3D; + color: number; +} diff --git a/packages/api/src/room/object/visualization/ISortableSprite.ts b/packages/api/src/room/object/visualization/ISortableSprite.ts new file mode 100644 index 0000000..b4c0e75 --- /dev/null +++ b/packages/api/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/packages/api/src/room/object/visualization/index.ts b/packages/api/src/room/object/visualization/index.ts new file mode 100644 index 0000000..681f37e --- /dev/null +++ b/packages/api/src/room/object/visualization/index.ts @@ -0,0 +1,10 @@ +export * from './IPlaneDrawingData'; +export * from './IPlaneVisualization'; +export * from './IRoomObjectGraphicVisualization'; +export * from './IRoomObjectSprite'; +export * from './IRoomObjectSpriteVisualization'; +export * from './IRoomObjectVisualization'; +export * from './IRoomObjectVisualizationData'; +export * from './IRoomObjectVisualizationFactory'; +export * from './IRoomPlane'; +export * from './ISortableSprite'; diff --git a/packages/api/src/room/renderer/IRoomCanvasMouseListener.ts b/packages/api/src/room/renderer/IRoomCanvasMouseListener.ts new file mode 100644 index 0000000..bcd97ff --- /dev/null +++ b/packages/api/src/room/renderer/IRoomCanvasMouseListener.ts @@ -0,0 +1,8 @@ +import { IRoomGeometry } from '../IRoomGeometry'; +import { IRoomSpriteMouseEvent } from '../IRoomSpriteMouseEvent'; +import { IRoomObject } from '../object'; + +export interface IRoomCanvasMouseListener +{ + processRoomCanvasMouseEvent(event: IRoomSpriteMouseEvent, object: IRoomObject, geometry: IRoomGeometry): void +} diff --git a/packages/api/src/room/renderer/IRoomRenderer.ts b/packages/api/src/room/renderer/IRoomRenderer.ts new file mode 100644 index 0000000..4477917 --- /dev/null +++ b/packages/api/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/packages/api/src/room/renderer/IRoomRendererBase.ts b/packages/api/src/room/renderer/IRoomRendererBase.ts new file mode 100644 index 0000000..2c00706 --- /dev/null +++ b/packages/api/src/room/renderer/IRoomRendererBase.ts @@ -0,0 +1,10 @@ +import { IRoomObject } from '../object'; + +export interface IRoomRendererBase +{ + addObject(object: IRoomObject): void; + removeObject(object: IRoomObject): void; + dispose(): void; + reset(): void; + update(time: number, update?: boolean): void; +} diff --git a/packages/api/src/room/renderer/IRoomRenderingCanvas.ts b/packages/api/src/room/renderer/IRoomRenderingCanvas.ts new file mode 100644 index 0000000..65a24b6 --- /dev/null +++ b/packages/api/src/room/renderer/IRoomRenderingCanvas.ts @@ -0,0 +1,36 @@ +import { Container, Point, Texture } from 'pixi.js'; +import { IRoomGeometry } from '../IRoomGeometry'; +import { RoomObjectSpriteData } from '../RoomObjectSpriteData'; +import { ISortableSprite } from '../object'; +import { IRoomCanvasMouseListener } from './IRoomCanvasMouseListener'; + +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; + skipSpriteVisibilityChecking(): void; + resumeSpriteVisibilityChecking(): void; + getPlaneSortableSprites(): ISortableSprite[]; + handleMouseEvent(x: number, y: number, type: string, altKey: boolean, ctrlKey: boolean, shiftKey: boolean, buttonDown: boolean): boolean; + getSortableSpriteList(): RoomObjectSpriteData[]; + getDisplayAsTexture(): Texture; + moveLeft(): void; + moveRight(): void; + moveUp(): void; + moveDown(): void; + id: number; + geometry: IRoomGeometry; + master: Container; + display: Container; + screenOffsetX: number; + screenOffsetY: number; + scale: number; + width: number; + height: number; + canvasUpdated: boolean; +} diff --git a/packages/api/src/room/renderer/IRoomSpriteCanvasContainer.ts b/packages/api/src/room/renderer/IRoomSpriteCanvasContainer.ts new file mode 100644 index 0000000..be65859 --- /dev/null +++ b/packages/api/src/room/renderer/IRoomSpriteCanvasContainer.ts @@ -0,0 +1,8 @@ +import { IRoomObject } from '../object'; + +export interface IRoomSpriteCanvasContainer +{ + getRoomObject(instanceId: number): IRoomObject; + objects: Map; + roomObjectVariableAccurateZ: string; +} diff --git a/packages/api/src/room/renderer/index.ts b/packages/api/src/room/renderer/index.ts new file mode 100644 index 0000000..82ea268 --- /dev/null +++ b/packages/api/src/room/renderer/index.ts @@ -0,0 +1,5 @@ +export * from './IRoomCanvasMouseListener'; +export * from './IRoomRenderer'; +export * from './IRoomRendererBase'; +export * from './IRoomRenderingCanvas'; +export * from './IRoomSpriteCanvasContainer'; diff --git a/packages/api/src/ui/MouseEventType.ts b/packages/api/src/ui/MouseEventType.ts new file mode 100644 index 0000000..b5c5f84 --- /dev/null +++ b/packages/api/src/ui/MouseEventType.ts @@ -0,0 +1,12 @@ +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_DOWN_LONG: string = 'mousedown_long'; + public static MOUSE_UP: string = 'mouseup'; + public static ROLL_OVER: string = 'mouseover'; + public static ROLL_OUT: string = 'mouseout'; + public static RIGHT_CLICK: string = 'contextmenu'; +} diff --git a/packages/api/src/ui/TouchEventType.ts b/packages/api/src/ui/TouchEventType.ts new file mode 100644 index 0000000..3f6eec9 --- /dev/null +++ b/packages/api/src/ui/TouchEventType.ts @@ -0,0 +1,8 @@ +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'; + public static TOUCH_LONG: string = 'touchlong'; +} diff --git a/packages/api/src/ui/enums/AvatarExpressionEnum.ts b/packages/api/src/ui/enums/AvatarExpressionEnum.ts new file mode 100644 index 0000000..389f8d4 --- /dev/null +++ b/packages/api/src/ui/enums/AvatarExpressionEnum.ts @@ -0,0 +1,28 @@ +export class AvatarExpressionEnum +{ + public static NONE: AvatarExpressionEnum = new AvatarExpressionEnum(0); + public static WAVE: AvatarExpressionEnum = new AvatarExpressionEnum(1); + public static BLOW: AvatarExpressionEnum = new AvatarExpressionEnum(2); + public static LAUGH: AvatarExpressionEnum = new AvatarExpressionEnum(3); + public static CRY: AvatarExpressionEnum = new AvatarExpressionEnum(4); + public static IDLE: AvatarExpressionEnum = new AvatarExpressionEnum(5); + public static JUMP: AvatarExpressionEnum = new AvatarExpressionEnum(6); + public static RESPECT: AvatarExpressionEnum = new AvatarExpressionEnum(7); + + private _ordinal: number; + + constructor(k: number) + { + this._ordinal = k; + } + + public get ordinal(): number + { + return this._ordinal; + } + + public equals(k: AvatarExpressionEnum): boolean + { + return (k) && (k._ordinal == this._ordinal); + } +} diff --git a/packages/api/src/ui/enums/ContextMenuEnum.ts b/packages/api/src/ui/enums/ContextMenuEnum.ts new file mode 100644 index 0000000..7c53378 --- /dev/null +++ b/packages/api/src/ui/enums/ContextMenuEnum.ts @@ -0,0 +1,12 @@ +export class ContextMenuEnum +{ + public static DUMMY: string = 'DUMMY'; + public static FRIEND_FURNITURE: string = 'FRIEND_FURNITURE'; + public static MONSTERPLANT_SEED: string = 'MONSTERPLANT_SEED'; + public static MYSTERY_BOX: string = 'MYSTERY_BOX'; + public static EFFECT_BOX: string = 'EFFECT_BOX'; + public static MYSTERY_TROPHY: string = 'MYSTERY_TROPHY'; + public static RANDOM_TELEPORT: string = 'RANDOM_TELEPORT'; + public static PURCHASABLE_CLOTHING: string = 'PURCHASABLE_CLOTHING'; + public static GENERIC_USABLE: string = 'GENERIC_USABLE'; +} diff --git a/packages/api/src/ui/enums/FriendWidgetEngravingWidgetTypeEnum.ts b/packages/api/src/ui/enums/FriendWidgetEngravingWidgetTypeEnum.ts new file mode 100644 index 0000000..4417687 --- /dev/null +++ b/packages/api/src/ui/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/packages/api/src/ui/enums/RoomWidgetEnum.ts b/packages/api/src/ui/enums/RoomWidgetEnum.ts new file mode 100644 index 0000000..4b746b5 --- /dev/null +++ b/packages/api/src/ui/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/packages/api/src/ui/enums/RoomWidgetEnumItemExtradataParameter.ts b/packages/api/src/ui/enums/RoomWidgetEnumItemExtradataParameter.ts new file mode 100644 index 0000000..d252e69 --- /dev/null +++ b/packages/api/src/ui/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/packages/api/src/ui/enums/RoomWidgetFurniInfoUsagePolicyEnum.ts b/packages/api/src/ui/enums/RoomWidgetFurniInfoUsagePolicyEnum.ts new file mode 100644 index 0000000..523205c --- /dev/null +++ b/packages/api/src/ui/enums/RoomWidgetFurniInfoUsagePolicyEnum.ts @@ -0,0 +1,6 @@ +export class RoomWidgetFurniInfoUsagePolicyEnum +{ + public static NOBODY: number = 0; + public static CONTROLLER: number = 1; + public static EVERYBODY: number = 2; +} diff --git a/packages/api/src/ui/enums/SystemChatStyleEnum.ts b/packages/api/src/ui/enums/SystemChatStyleEnum.ts new file mode 100644 index 0000000..15e3428 --- /dev/null +++ b/packages/api/src/ui/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/packages/api/src/ui/enums/index.ts b/packages/api/src/ui/enums/index.ts new file mode 100644 index 0000000..48f242d --- /dev/null +++ b/packages/api/src/ui/enums/index.ts @@ -0,0 +1,7 @@ +export * from './AvatarExpressionEnum'; +export * from './ContextMenuEnum'; +export * from './FriendWidgetEngravingWidgetTypeEnum'; +export * from './RoomWidgetEnum'; +export * from './RoomWidgetEnumItemExtradataParameter'; +export * from './RoomWidgetFurniInfoUsagePolicyEnum'; +export * from './SystemChatStyleEnum'; diff --git a/packages/api/src/ui/index.ts b/packages/api/src/ui/index.ts new file mode 100644 index 0000000..d803ec8 --- /dev/null +++ b/packages/api/src/ui/index.ts @@ -0,0 +1,3 @@ +export * from './MouseEventType'; +export * from './TouchEventType'; +export * from './enums'; diff --git a/packages/api/src/utils/IAdvancedMap.ts b/packages/api/src/utils/IAdvancedMap.ts new file mode 100644 index 0000000..f10c570 --- /dev/null +++ b/packages/api/src/utils/IAdvancedMap.ts @@ -0,0 +1,22 @@ +import { IDisposable } from '../common'; + +export interface IAdvancedMap extends IDisposable +{ + dispose(): void; + reset(): void; + unshift(key: T, value: U): boolean; + add(key: T, value: U): boolean; + remove(key: T): U; + getWithIndex(index: number): U; + getKey(index: number): T; + getKeys(): T[]; + hasKey(key: T): boolean; + getValue(key: T): U; + getValues(): U[]; + hasValue(value: U): boolean; + indexOf(value: U): number; + concatenate(newValues: IAdvancedMap): void; + clone(): IAdvancedMap; + readonly length: number; + readonly disposed: boolean +} diff --git a/packages/api/src/utils/IBinaryReader.ts b/packages/api/src/utils/IBinaryReader.ts new file mode 100644 index 0000000..6ad2657 --- /dev/null +++ b/packages/api/src/utils/IBinaryReader.ts @@ -0,0 +1,12 @@ +export interface IBinaryReader +{ + readBytes(length: number): IBinaryReader; + readByte(): number; + readShort(): number; + readInt(): number; + readFloat(): number; + readDouble(): number; + remaining(): number; + toString(encoding?: string): string; + toArrayBuffer(): ArrayBuffer; +} diff --git a/packages/api/src/utils/IBinaryWriter.ts b/packages/api/src/utils/IBinaryWriter.ts new file mode 100644 index 0000000..f3135c0 --- /dev/null +++ b/packages/api/src/utils/IBinaryWriter.ts @@ -0,0 +1,11 @@ +export interface IBinaryWriter +{ + writeByte(byte: number): IBinaryWriter; + writeBytes(bytes: ArrayBuffer | number[]): IBinaryWriter; + writeShort(short: number): IBinaryWriter; + writeInt(integer: number): IBinaryWriter; + writeString(string: string, includeLength?: boolean): IBinaryWriter; + getBuffer(): ArrayBuffer; + position: number; + toString(encoding?: string): string; +} diff --git a/packages/api/src/utils/IVector3D.ts b/packages/api/src/utils/IVector3D.ts new file mode 100644 index 0000000..467e26e --- /dev/null +++ b/packages/api/src/utils/IVector3D.ts @@ -0,0 +1,16 @@ +export interface IVector3D +{ + assign(vector: IVector3D): void; + add(vector: IVector3D): void; + subtract(vector: IVector3D): void; + multiply(amount: number): void; + divide(amount: number): void; + negate(): void; + dotProduct(vector: IVector3D): number; + crossProduct(vector: IVector3D): IVector3D; + normalize(): void; + x: number; + y: number; + z: number; + length: number; +} diff --git a/packages/api/src/utils/index.ts b/packages/api/src/utils/index.ts new file mode 100644 index 0000000..15828e4 --- /dev/null +++ b/packages/api/src/utils/index.ts @@ -0,0 +1,4 @@ +export * from './IAdvancedMap'; +export * from './IBinaryReader'; +export * from './IBinaryWriter'; +export * from './IVector3D'; diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/api/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/assets/.eslintrc.json b/packages/assets/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/assets/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/assets/.gitignore b/packages/assets/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/assets/.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/packages/assets/index.ts b/packages/assets/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/assets/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/assets/package.json b/packages/assets/package.json new file mode 100644 index 0000000..586612d --- /dev/null +++ b/packages/assets/package.json @@ -0,0 +1,25 @@ +{ + "name": "@nitrots/assets", + "description": "Nitro assets module", + "version": "1.0.0", + "type": "module", + "publishConfig": { + "access": "public" + }, + "license": "GPL-3.0", + "scripts": { + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "@nitrots/utils": "1.0.0", + "pixi.js": "^8.0.4", + "@pixi/gif": "^3.0.0" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/assets/src/AssetManager.ts b/packages/assets/src/AssetManager.ts new file mode 100644 index 0000000..06953fe --- /dev/null +++ b/packages/assets/src/AssetManager.ts @@ -0,0 +1,151 @@ +import { IAssetData, IAssetManager, IGraphicAsset, IGraphicAssetCollection } from '@nitrots/api'; +import { NitroBundle, NitroLogger } from '@nitrots/utils'; +import '@pixi/gif'; +import { Assets, Spritesheet, SpritesheetData, Texture } from 'pixi.js'; +import { GraphicAssetCollection } from './GraphicAssetCollection'; + +export class AssetManager implements IAssetManager +{ + private _textures: Map = new Map(); + private _collections: Map = new Map(); + + public getTexture(name: string): Texture + { + if(!name) return null; + + return this._textures.get(name); + } + + public setTexture(name: string, texture: Texture): void + { + if(!name || !texture) return; + + texture.label = name; + + 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; + } + + NitroLogger.warn(`AssetManager: Asset not found: ${name}`); + + return null; + } + + public addAssetToCollection(collectionName: string, assetName: string, texture: Texture, override: boolean = true): boolean + { + const collection = this.getCollection(collectionName); + + if(!collection) return false; + + return collection.addAsset(assetName, texture, override, 0, 0, false, false); + } + + public getCollection(name: string): IGraphicAssetCollection + { + if(!name) return null; + + return this._collections.get(name); + } + + public createCollection(data: IAssetData, spritesheet: Spritesheet): IGraphicAssetCollection + { + if(!data) return null; + + const collection = new GraphicAssetCollection(data, spritesheet); + + for(const [name, texture] of collection.textures.entries()) this.setTexture(name, texture); + + this._collections.set(collection.name, collection); + + return collection; + } + + public async downloadAssets(urls: string[]): Promise + { + if(!urls || !urls.length) return Promise.resolve(true); + + try + { + await Promise.all(urls.map(url => this.downloadAsset(url))); + + return true; + } + + catch (err) + { + NitroLogger.error(err); + } + + return false; + } + + public async downloadAsset(url: string): Promise + { + try + { + if(!url || !url.length) return false; + + if(url.endsWith('.png') || url.endsWith('.jpg') || url.endsWith('.jpeg') || url.endsWith('.gif')) + { + const texture = await Assets.load(url); + + this.setTexture(url, texture); + + return true; + } + + const response = await fetch(url); + + if(response.status !== 200 || !response.headers.has('Content-Type') || response.headers.get('Content-Type') !== 'application/octet-stream') return false; + + const buffer = await response.arrayBuffer(); + const nitroBundle = await NitroBundle.from(buffer); + + await this.processAsset(nitroBundle.texture, nitroBundle.jsonFile as IAssetData); + + return true; + } + + catch (err) + { + NitroLogger.error(err); + + return false; + } + } + + private async processAsset(texture: Texture, data: IAssetData): Promise + { + let spritesheet: Spritesheet = null; + + if(texture && data?.spritesheet && Object.keys(data.spritesheet).length) + { + spritesheet = new Spritesheet(texture, data.spritesheet); + + await spritesheet.parse(); + + spritesheet.textureSource.label = data.name ?? null; + } + + this.createCollection(data, spritesheet); + } + + public get collections(): Map + { + return this._collections; + } +} diff --git a/packages/assets/src/GetAssetManager.ts b/packages/assets/src/GetAssetManager.ts new file mode 100644 index 0000000..257ceea --- /dev/null +++ b/packages/assets/src/GetAssetManager.ts @@ -0,0 +1,5 @@ +import { AssetManager } from './AssetManager'; + +const assetManager = new AssetManager(); + +export const GetAssetManager = () => assetManager; diff --git a/packages/assets/src/GraphicAsset.ts b/packages/assets/src/GraphicAsset.ts new file mode 100644 index 0000000..1b6aa18 --- /dev/null +++ b/packages/assets/src/GraphicAsset.ts @@ -0,0 +1,140 @@ +import { Rectangle, Texture } from 'pixi.js'; +import { IGraphicAsset } from '../../api/src/asset/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; + } +} diff --git a/packages/assets/src/GraphicAssetCollection.ts b/packages/assets/src/GraphicAssetCollection.ts new file mode 100644 index 0000000..e38dc97 --- /dev/null +++ b/packages/assets/src/GraphicAssetCollection.ts @@ -0,0 +1,372 @@ +import { IAsset, IAssetData, IAssetPalette, IGraphicAsset, IGraphicAssetCollection, IGraphicAssetPalette } from '@nitrots/api'; +import { Dict, Spritesheet, Texture, TextureSource } from 'pixi.js'; +import { GraphicAsset } from './GraphicAsset'; +import { GraphicAssetPalette } from './GraphicAssetPalette'; + +export class GraphicAssetCollection implements IGraphicAssetCollection +{ + private static PALETTE_ASSET_DISPOSE_THRESHOLD: number = 10; + + private _referenceCount: number; + + private _name: string; + private _textureSource: TextureSource; + 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._textureSource = ((spritesheet && spritesheet.textureSource) || null); + 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 static removeFileExtension(name: string): string + { + return (name.substring(0, name.lastIndexOf('.')) || name); + } + + public dispose(): void + { + if(this._palettes) 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++; + } + + public removeReference(): void + { + this._referenceCount--; + + if(this._referenceCount <= 0) + { + this._referenceCount = 0; + + 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 getTexture(name: string): Texture + { + return this._textures.get(name); + } + + 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): IGraphicAssetPalette + { + if(!name) return null; + + return this._palettes.get(name); + } + + 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.source = texture.source; + + //@ts-ignore + existingTexture.frame = texture.frame; + + //@ts-ignore + 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: Dict): void + { + if(!textures) return; + + for(const name in textures) + { + const texture = textures[name]; + + if(!texture) continue; + + this._textures.set(GraphicAssetCollection.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 name(): string + { + return this._name; + } + + public get textureSource(): TextureSource + { + return this._textureSource; + } + + public get data(): IAssetData + { + return this._data; + } + + public get textures(): Map + { + return this._textures; + } + + public get assets(): Map + { + return this._assets; + } +} diff --git a/packages/assets/src/GraphicAssetPalette.ts b/packages/assets/src/GraphicAssetPalette.ts new file mode 100644 index 0000000..57652fd --- /dev/null +++ b/packages/assets/src/GraphicAssetPalette.ts @@ -0,0 +1,57 @@ +import { IGraphicAssetPalette } from '@nitrots/api'; +import { GetRenderer } from '@nitrots/utils'; +import { Texture } from 'pixi.js'; + +export class GraphicAssetPalette implements IGraphicAssetPalette +{ + 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 applyPalette(texture: Texture): Texture + { + const canvas = GetRenderer().texture.generateCanvas(texture); + const ctx = canvas.getContext('2d'); + const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + + for(let i = 0; i < imageData.data.length; i += 4) + { + let paletteColor = this._palette[imageData.data[i + 1]]; + + if(paletteColor === undefined) paletteColor = [0, 0, 0]; + + imageData.data[i] = paletteColor[0]; + imageData.data[i + 1] = paletteColor[1]; + imageData.data[i + 2] = paletteColor[2]; + } + + ctx.putImageData(imageData, 0, 0); + + const newTexture = Texture.from(canvas); + + //@ts-ignore + newTexture.source.hitMap = imageData.data; + + return newTexture; + } + + public get primaryColor(): number + { + return this._primaryColor; + } + + public get secondaryColor(): number + { + return this._secondaryColor; + } +} diff --git a/packages/assets/src/index.ts b/packages/assets/src/index.ts new file mode 100644 index 0000000..a21d9b4 --- /dev/null +++ b/packages/assets/src/index.ts @@ -0,0 +1,5 @@ +export * from './AssetManager'; +export * from './GetAssetManager'; +export * from './GraphicAsset'; +export * from './GraphicAssetCollection'; +export * from './GraphicAssetPalette'; diff --git a/packages/assets/tsconfig.json b/packages/assets/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/assets/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/avatar/.eslintrc.json b/packages/avatar/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/avatar/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/avatar/.gitignore b/packages/avatar/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/avatar/.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/packages/avatar/index.ts b/packages/avatar/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/avatar/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/avatar/package.json b/packages/avatar/package.json new file mode 100644 index 0000000..63549d6 --- /dev/null +++ b/packages/avatar/package.json @@ -0,0 +1,22 @@ +{ + "name": "@nitrots/avatar", + "description": "Nitro communication module", + "version": "1.0.0", + "type": "module", + "license": "GPL-3.0", + "scripts": { + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/assets": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "@nitrots/events": "1.0.0", + "@nitrots/utils": "1.0.0" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/avatar/src/AvatarAssetDownloadLibrary.ts b/packages/avatar/src/AvatarAssetDownloadLibrary.ts new file mode 100644 index 0000000..504b59b --- /dev/null +++ b/packages/avatar/src/AvatarAssetDownloadLibrary.ts @@ -0,0 +1,65 @@ +import { IAssetManager, IAvatarAssetDownloadLibrary } from '@nitrots/api'; +import { AvatarRenderLibraryEvent, GetEventDispatcher, NitroEventType } from '@nitrots/events'; + +export class AvatarAssetDownloadLibrary implements IAvatarAssetDownloadLibrary +{ + private static NOT_LOADED: number = 0; + private static LOADING: number = 1; + private static LOADED: number = 2; + + private _state: number = AvatarAssetDownloadLibrary.NOT_LOADED; + private _libraryName: string; + private _revision: string; + private _downloadUrl: string; + private _assetManager: IAssetManager; + + constructor(libraryName: string, revision: string, downloadUrl: string, assetManager: IAssetManager) + { + this._libraryName = libraryName; + this._revision = revision; + this._downloadUrl = downloadUrl; + this._assetManager = assetManager; + + this._downloadUrl = this._downloadUrl.replace(/%libname%/gi, this._libraryName); + this._downloadUrl = this._downloadUrl.replace(/%revision%/gi, this._revision); + + this.checkIsLoaded(); + } + + public async downloadAsset(): Promise + { + if(!this._assetManager || (this._state === AvatarAssetDownloadLibrary.LOADING) || (this._state === AvatarAssetDownloadLibrary.LOADED)) return; + + if(!this.checkIsLoaded()) + { + this._state = AvatarAssetDownloadLibrary.LOADING; + + const status = await this._assetManager.downloadAsset(this._downloadUrl); + + if(!status) throw new Error('Could not download asset'); + } + + if(this.checkIsLoaded()) GetEventDispatcher().dispatchEvent(new AvatarRenderLibraryEvent(NitroEventType.AVATAR_ASSET_DOWNLOADED, this)); + } + + private checkIsLoaded(): boolean + { + const asset = this._assetManager.getCollection(this._libraryName); + + if(!asset) return false; + + this._state = AvatarAssetDownloadLibrary.LOADED; + + return true; + } + + public get libraryName(): string + { + return this._libraryName; + } + + public get isLoaded(): boolean + { + return (this._state === AvatarAssetDownloadLibrary.LOADED); + } +} diff --git a/packages/avatar/src/AvatarAssetDownloadManager.ts b/packages/avatar/src/AvatarAssetDownloadManager.ts new file mode 100644 index 0000000..a11f073 --- /dev/null +++ b/packages/avatar/src/AvatarAssetDownloadManager.ts @@ -0,0 +1,246 @@ +import { IAssetManager, IAvatarFigureContainer, IAvatarImageListener } from '@nitrots/api'; +import { GetConfiguration } from '@nitrots/configuration'; +import { AvatarRenderLibraryEvent, GetEventDispatcher, NitroEvent, NitroEventType } from '@nitrots/events'; +import { AvatarAssetDownloadLibrary } from './AvatarAssetDownloadLibrary'; +import { AvatarStructure } from './AvatarStructure'; + +export class AvatarAssetDownloadManager +{ + private _assets: IAssetManager; + private _structure: AvatarStructure; + + private _missingMandatoryLibs: string[] = []; + private _figureMap: Map = new Map(); + private _figureListeners: Map = new Map(); + private _incompleteFigures: Map = new Map(); + private _currentDownloads: AvatarAssetDownloadLibrary[] = []; + private _libraryNames: string[] = []; + + constructor(assets: IAssetManager, structure: AvatarStructure) + { + this._assets = assets; + this._structure = structure; + } + + public async init(): Promise + { + this._missingMandatoryLibs = GetConfiguration().getValue('avatar.mandatory.libraries'); + + const url = GetConfiguration().getValue('avatar.figuremap.url'); + + if(!url || !url.length) throw new Error('Invalid figure map url'); + + const response = await fetch(url); + + if(response.status !== 200) throw new Error('Invalid figure map file'); + + const responseData = await response.json(); + + this.processFigureMap(responseData.libraries); + + GetEventDispatcher().addEventListener(NitroEventType.AVATAR_ASSET_DOWNLOADED, (event: AvatarRenderLibraryEvent) => this.onLibraryLoaded(event)); + + await this.processMissingLibraries(); + } + + private processFigureMap(data: any): void + { + if(!data) return; + + const downloadUrl = GetConfiguration().getValue('avatar.asset.url'); + + for(const library of data) + { + if(!library) continue; + + const libraryName = (library.id as string); + const revision = (library.revision || ''); + + if(this._libraryNames.indexOf(libraryName) >= 0) continue; + + this._libraryNames.push(libraryName); + + const downloadLibrary = new AvatarAssetDownloadLibrary(libraryName, revision, downloadUrl, this._assets); + + 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 async processMissingLibraries(): Promise + { + const promises: Promise[] = []; + + this._missingMandatoryLibs.forEach(value => + { + const libraries = this._figureMap.get(value); + + if(libraries) for(const library of libraries) promises.push(library.downloadAsset()); + }); + + this._missingMandatoryLibs = []; + + await Promise.all(promises); + } + + 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); + + GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.AVATAR_ASSET_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 isAvatarFigureContainerReady(container: IAvatarFigureContainer): boolean + { + return !this.getAvatarFigurePendingLibraries(container).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.getPartTypeIds(); + + for(const key of setKeys) + { + const set = figureData.getSetType(key); + + if(!set) continue; + + const figurePartSet = set.getPartSet(container.getPartSetId(key)); + + if(!figurePartSet) continue; + + for(const part of figurePartSet.parts) + { + 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 + { + const figure = container.getFigureString(); + 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; + + library.downloadAsset(); + } + } + else + { + if(listener && !listener.disposed) listener.resetFigure(figure); + } + } +} diff --git a/packages/avatar/src/AvatarFigureContainer.ts b/packages/avatar/src/AvatarFigureContainer.ts new file mode 100644 index 0000000..7bfa63b --- /dev/null +++ b/packages/avatar/src/AvatarFigureContainer.ts @@ -0,0 +1,116 @@ +import { IAvatarFigureContainer } from '@nitrots/api'; + +export class AvatarFigureContainer implements IAvatarFigureContainer +{ + private _parts: Map>; + + constructor(figure: string) + { + this._parts = new Map(); + + this.parseFigure(figure); + } + + public getPartTypeIds(): IterableIterator + { + return this.partSets().keys(); + } + + public hasPartType(k: string): boolean + { + return !!this.partSets().get(k); + } + + public getPartSetId(k: string): number + { + const existing = this.partSets().get(k); + + if(!existing) return 0; + + return existing.get('setid'); + } + + public getPartColorIds(k: string): number[] + { + const existing = this.partSets().get(k); + + if(!existing) return null; + + return existing.get('colorids'); + } + + public updatePart(setType: string, partSetId: number, colorIds: number[]): void + { + const set: Map = new Map(); + + set.set('type', setType); + set.set('setid', partSetId); + set.set('colorids', colorIds); + + const existingSets = this.partSets(); + + existingSets.delete(setType); + existingSets.set(setType, set); + } + + public removePart(k: string): void + { + this.partSets().delete(k); + } + + public getFigureString(): 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.getPartColorIds(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.updatePart(type, setId, colors); + } + } + } +} diff --git a/packages/avatar/src/AvatarImage.ts b/packages/avatar/src/AvatarImage.ts new file mode 100644 index 0000000..f23bfd7 --- /dev/null +++ b/packages/avatar/src/AvatarImage.ts @@ -0,0 +1,764 @@ +import { AvatarAction, AvatarDirectionAngle, AvatarScaleType, AvatarSetType, IActiveActionData, IAnimationLayerData, IAvatarDataContainer, IAvatarEffectListener, IAvatarFigureContainer, IAvatarImage, IPartColor, ISpriteDataContainer } from '@nitrots/api'; +import { GetRenderer, GetTexturePool, GetTickerTime, PaletteMapFilter, TextureUtils } from '@nitrots/utils'; +import { ColorMatrixFilter, Container, RenderTexture, Sprite, Texture } from 'pixi.js'; +import { AvatarFigureContainer } from './AvatarFigureContainer'; +import { AvatarStructure } from './AvatarStructure'; +import { EffectAssetDownloadManager } from './EffectAssetDownloadManager'; +import { ActiveActionData } from './actions'; +import { AssetAliasCollection } from './alias'; +import { AvatarImageCache } from './cache'; +import { AvatarCanvas } from './structure'; + +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 _mainDirection: number; + protected _headDirection: number; + protected _mainAction: IActiveActionData; + protected _disposed: boolean = false; + protected _canvasOffsets: number[] = []; + protected _cache: AvatarImageCache; + protected _avatarSpriteData: IAvatarDataContainer; + protected _actions: ActiveActionData[] = []; + protected _activeTexture: Texture = null; + + private _defaultAction: IActiveActionData = null; + private _frameCounter: number = 0; + private _directionOffset: number = 0; + private _changes: boolean = true; + private _sprites: ISpriteDataContainer[]; + private _isAnimating: boolean = false; + private _animationHasResetOnToggle: boolean = false; + private _actionsSorted: boolean = false; + private _sortedActions: IActiveActionData[]; + private _lastActionsString: string = null; + private _currentActionsString: string = null; + private _effectIdInUse: number = -1; + private _animationFrameCount: number = -1; + private _cachedBodyParts: string[] = []; + private _cachedBodyPartsDirection: number = -1; + private _cachedBodyPartsGeometryType: string = null; + private _cachedBodyPartsAvatarSet: string = null; + + constructor( + private _structure: AvatarStructure, + private _assets: AssetAliasCollection, + private _figure: AvatarFigureContainer, + private _scale: string, + private _effectManager: EffectAssetDownloadManager, + private _effectListener: IAvatarEffectListener = null) + { + if(!this._figure) this._figure = new AvatarFigureContainer('hr-893-45.hd-180-2.ch-210-66.lg-270-82.sh-300-91.wa-2007-.ri-1-'); + if(!this._scale) this._scale = AvatarScaleType.LARGE; + + this._cache = new AvatarImageCache(this._structure, this, this._assets, this._scale); + this.setDirection(AvatarImage.DEFAULT_AVATAR_SET, AvatarImage.DEFAULT_DIRECTION); + this._defaultAction = new ActiveActionData(AvatarAction.POSTURE_STAND); + this._defaultAction.definition = this._structure.getActionDefinition(AvatarImage.DEFAULT_ACTION); + this.resetActions(); + this._animationFrameCount = 0; + } + + 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._activeTexture) + { + GetTexturePool().putTexture(this._activeTexture); + + this._activeTexture = null; + } + + if(this._cache) + { + this._cache.dispose(); + this._cache = 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.getPartColor(this._figure, k); + } + + public setDirection(avatarPart: string, direction: number): void + { + direction += this._directionOffset; + + if(direction < AvatarDirectionAngle.MIN_DIRECTION) + { + direction = AvatarDirectionAngle.MAX_DIRECTION + (direction + 1); + } + else if(direction > AvatarDirectionAngle.MAX_DIRECTION) + { + direction -= (AvatarDirectionAngle.MAX_DIRECTION + 1); + } + + if(this._structure.isMainAvatarSet(avatarPart)) this._mainDirection = direction; + + // Special handling for head direction, including prevention checks for turning + if(avatarPart === AvatarSetType.HEAD || avatarPart === AvatarSetType.FULL) + { + if(avatarPart === AvatarSetType.HEAD && this.isHeadTurnPreventedByAction()) direction = this._mainDirection; + + this._headDirection = direction; + } + + this._cache.setDirection(avatarPart, direction); + 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.getBodyPartData(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 getBodyParts(avatarSet: string, geometryType: string, direction: number): string[] + { + const shouldUpdateCache = direction !== this._cachedBodyPartsDirection || geometryType !== this._cachedBodyPartsGeometryType || avatarSet !== this._cachedBodyPartsAvatarSet; + + if(shouldUpdateCache) + { + this._cachedBodyPartsDirection = direction; + this._cachedBodyPartsGeometryType = geometryType; + this._cachedBodyPartsAvatarSet = avatarSet; + + this._cachedBodyParts = this._structure.getBodyParts(avatarSet, geometryType, direction); + } + + return this._cachedBodyParts; + } + + private buildAvatarContainer(avatarCanvas: AvatarCanvas, setType: string): Container + { + const bodyParts = this.getBodyParts(setType, this._mainAction.definition.geometryType, this._mainDirection); + const container = new Container(); + + let partCount = (bodyParts.length - 1); + + while(partCount >= 0) + { + const set = bodyParts[partCount]; + const part = this._cache.getImageContainer(set, this._frameCounter); + + if(part) + { + const partCacheContainer = part.image; + + if(partCacheContainer) + { + const partContainer = new Container(); + + partContainer.addChild(partCacheContainer); + + const point = part.regPoint.clone(); + + point.x += avatarCanvas.offset.x; + point.y += avatarCanvas.offset.y; + + point.x += avatarCanvas.regPoint.x; + point.y += avatarCanvas.regPoint.y; + + partContainer.position.set(point.x, point.y); + + container.addChild(partContainer); + } + } + + partCount--; + } + + container.filters = []; + + if(this._avatarSpriteData) + { + if(this._avatarSpriteData.colorTransform) + { + if(container.filters === undefined || container.filters === null) container.filters = [ this._avatarSpriteData.colorTransform ]; + else if(Array.isArray(container.filters)) container.filters = [ ...container.filters, this._avatarSpriteData.colorTransform ]; + else container.filters = [ container.filters, this._avatarSpriteData.colorTransform ]; + } + + if(this._avatarSpriteData.paletteIsGrayscale) + { + this.convertToGrayscale(container); + + const paletteMapFilter = new PaletteMapFilter({ + palette: this._avatarSpriteData.reds, + channel: PaletteMapFilter.CHANNEL_RED + }); + + if(container.filters === undefined || container.filters === null) container.filters = [ paletteMapFilter ]; + else if(Array.isArray(container.filters)) container.filters = [ ...container.filters, paletteMapFilter ]; + else container.filters = [ container.filters, paletteMapFilter ]; + } + } + + return container; + } + + public processAsTexture(setType: string, hightlight: boolean): Texture + { + if(!this._changes) return this._activeTexture; + + if(!this._mainAction) return null; + + if(!this._actionsSorted) this.endActionAppends(); + + const avatarCanvas = this._structure.getCanvas(this._scale, this._mainAction.definition.geometryType); + + if(!avatarCanvas) return null; + + const container = this.buildAvatarContainer(avatarCanvas, setType); + + if(this._activeTexture && ((this._activeTexture.width !== avatarCanvas.width) || (this._activeTexture.height !== avatarCanvas.height))) + { + GetTexturePool().putTexture(this._activeTexture); + + this._activeTexture = null; + } + + if(!this._activeTexture) this._activeTexture = GetTexturePool().getTexture(avatarCanvas.width, avatarCanvas.height); + + if(!this._activeTexture) return null; + + GetRenderer().render({ + target: this._activeTexture, + container: container, + clear: true + }); + + container.destroy(); + + //@ts-ignore + this._activeTexture.source.hitMap = null; + + this._changes = false; + + return this._activeTexture; + } + + public processAsImageUrl(setType: string, scale: number = 1): string + { + const texture = this.processAsTexture(setType, false); + const canvas = GetRenderer().texture.generateCanvas(texture); + + const url = canvas.toDataURL('image/png'); + + return url; + } + + public processAsContainer(setType: string): Container + { + if(!this._mainAction) return null; + + if(!this._actionsSorted) this.endActionAppends(); + + const avatarCanvas = this._structure.getCanvas(this._scale, this._mainAction.definition.geometryType); + + if(!avatarCanvas) return null; + + return this.buildAvatarContainer(avatarCanvas, setType); + } + + public applyPalette(texture: RenderTexture, reds: number[] = [], greens: number[] = [], blues: number[] = []): RenderTexture + { + const textureCanvas = TextureUtils.generateCanvas(texture); + 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) + { + if(reds.length == 256) + { + let paletteColor = reds[data[i]]; + if(paletteColor === undefined) paletteColor = 0; + + data[i] = ((paletteColor >> 16) & 0xFF); + data[i + 1] = ((paletteColor >> 8) & 0xFF); + data[i + 2] = (paletteColor & 0xFF); + } + + if(greens.length == 256) + { + let paletteColor = greens[data[i + 1]]; + if(paletteColor === undefined) paletteColor = 0; + + data[i] = ((paletteColor >> 16) & 0xFF); + data[i + 1] = ((paletteColor >> 8) & 0xFF); + data[i + 2] = (paletteColor & 0xFF); + } + if(blues.length == 256) + { + let paletteColor = greens[data[i + 2]]; + if(paletteColor === undefined) paletteColor = 0; + + data[i] = ((paletteColor >> 16) & 0xFF); + data[i + 1] = ((paletteColor >> 8) & 0xFF); + data[i + 2] = (paletteColor & 0xFF); + } + } + + textureCtx.putImageData(textureImageData, 0, 0); + + const newTexture = new Sprite(Texture.from(textureCanvas)); + + TextureUtils.writeToTexture(newTexture, texture, true); + + return texture; + } + + public getDirection(): number + { + return this._mainDirection; + } + + public initActionAppends(): void + { + this._actions = []; + this._actionsSorted = false; + this._currentActionsString = ''; + } + + public endActionAppends(): void + { + if(!this.sortActions()) return; + + for(const k of this._sortedActions) + { + if(k.actionType === AvatarAction.EFFECT) + { + if(!this._effectManager.isAvatarEffectReady(parseInt(k.actionParameter))) this._effectManager.downloadAvatarEffect(parseInt(k.actionParameter), 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: + case AvatarAction.POSTURE_WALK: + case AvatarAction.POSTURE_STAND: + 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: + if((_local_3 === AvatarAction.POSTURE_LAY) || (_local_3 === AvatarAction.POSTURE_LAY) || (_local_3 === AvatarAction.POSTURE_LAY)) + { + if(_local_3 === AvatarAction.POSTURE_LAY) + { + if(this._mainDirection == 0) + { + this.setDirection(AvatarSetType.FULL, 4); + } + else + { + this.setDirection(AvatarSetType.FULL, 2); + } + } + } + + 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: + 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: + if(_local_3 === AvatarAction.EFFECT) + { + if((((((_local_3 === '33') || (_local_3 === '34')) || (_local_3 === '35')) || (_local_3 === '36')) || (_local_3 === '38')) || (_local_3 === '39')) + { + // + } + } + + this.addActionData(k, _local_3); + break; + case AvatarAction.CARRY_OBJECT: + case AvatarAction.USE_OBJECT: { + const _local_4 = this._structure.getActionDefinitionWithState(k); + if(_local_4) _local_3 = _local_4.getParameterValue(_local_3); + this.addActionData(k, _local_3); + break; + } + } + + return true; + } + + protected addActionData(actionType: string, actionParameter: string = ''): void + { + if(!this._actions) this._actions = []; + + const actionExists = this._actions.some(action => + action.actionType === actionType && action.actionParameter === actionParameter + ); + + if(!actionExists) this._actions.push(new ActiveActionData(actionType, actionParameter, 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.removeDynamicItems(this); + this._mainAction = this._defaultAction; + this._mainAction.definition = this._defaultAction.definition; + this.resetBodyPartCache(this._defaultAction); + return true; + } + + private isHeadTurnPreventedByAction(): boolean + { + if(!this._sortedActions) return false; + + for(const action of this._sortedActions) + { + const actionDefinition = this._structure.getActionDefinitionWithState(action.actionType); + + if(actionDefinition != null && actionDefinition.getPreventHeadTurn(action.actionParameter)) return true; + } + + return false; + } + + private sortActions(): boolean + { + let hasChanges = false; + let hasEffectAction = false; + let effectChanged = false; + + this._currentActionsString = ''; + this._sortedActions = this._structure.sortActions(this._actions); + this._animationFrameCount = this._structure.maxFrames(this._sortedActions); + + if(!this._sortedActions) + { + this._canvasOffsets = [0, 0, 0]; + + if(this._lastActionsString !== '') + { + hasChanges = true; + + this._lastActionsString = ''; + } + } + else + { + this._canvasOffsets = this._structure.getCanvasOffsets(this._sortedActions, this._scale, this._mainDirection); + + for(const action of this._sortedActions) + { + this._currentActionsString += action.actionType + action.actionParameter; + + if(action.actionType === AvatarAction.EFFECT) + { + const effectId = parseInt(action.actionParameter); + + if(this._effectIdInUse !== effectId) effectChanged = true; + + this._effectIdInUse = effectId; + + hasEffectAction = true; + } + } + + if(!hasEffectAction) + { + if(this._effectIdInUse > -1) effectChanged = true; + + this._effectIdInUse = -1; + } + + if(effectChanged) this._cache.disposeInactiveActions(); + + if(this._lastActionsString != this._currentActionsString) + { + hasChanges = true; + + this._lastActionsString = this._currentActionsString; + } + } + + this._actionsSorted = true; + + return hasChanges; + } + + private setActionsToParts(): void + { + if(!this._sortedActions) return; + + const currentTime = GetTickerTime(); + const actionTypes: string[] = []; + + for(const action of this._sortedActions) actionTypes.push(action.actionType); + + for(const action of this._sortedActions) + { + if(action && action.definition && action.definition.isAnimation) + { + const animation = this._structure.getAnimation(`${action.definition.state}.${action.actionParameter}`); + + if(animation && animation.hasOverriddenActions()) + { + const overriddenActionNames = animation.overriddenActionNames(); + + if(overriddenActionNames) + { + for(const overriddenActionName of overriddenActionNames) + { + if(actionTypes.includes(overriddenActionName)) action.overridingAction = animation.overridingAction(overriddenActionName); + } + } + } + + if(animation && animation.resetOnToggle) this._animationHasResetOnToggle = true; + } + } + + for(const action of this._sortedActions) + { + if(action && action.definition) + { + if(action.definition.isAnimation && action.actionParameter === '') action.actionParameter = '1'; + + this.setActionToParts(action, currentTime); + + if(action.definition.isAnimation) + { + this._isAnimating = action.definition.isAnimated(action.actionParameter); + + const animation = this._structure.getAnimation(`${action.definition.state}.${action.actionParameter}`); + + if(animation) + { + this._sprites = [...this._sprites, ...animation.spriteData]; + + if(animation.hasDirectionData()) this._directionOffset = animation.directionData.offset; + + if(animation.hasAvatarData()) this._avatarSpriteData = animation.avatarData; + } + } + } + } + } + + private setActionToParts(action: IActiveActionData, currentTime: number): void + { + if(!action || !action.definition || action.definition.assetPartDefinition === '') return; + + if(action.definition.isMain) + { + this._mainAction = action; + this._cache.setGeometryType(action.definition.geometryType); + } + + this._cache.setAction(action, currentTime); + + this._changes = true; + } + + private resetBodyPartCache(action: IActiveActionData): void + { + if(!action || action.definition.assetPartDefinition === '') return; + + if(action.definition.isMain) + { + this._mainAction = action; + this._cache.setGeometryType(action.definition.geometryType); + } + + this._cache.resetBodyPartCache(action); + + this._changes = true; + } + + private convertToGrayscale(container: Container, channel: string = 'CHANNELS_EQUAL'): Container + { + let redWeight = 0.33; + let greenWeight = 0.33; + let blueWeight = 0.33; + + switch(channel) + { + case AvatarImage.CHANNELS_UNIQUE: + redWeight = 0.3; + greenWeight = 0.59; + blueWeight = 0.11; + break; + case AvatarImage.CHANNELS_RED: + redWeight = 1; + greenWeight = 0; + blueWeight = 0; + break; + case AvatarImage.CHANNELS_GREEN: + redWeight = 0; + greenWeight = 1; + blueWeight = 0; + break; + case AvatarImage.CHANNELS_BLUE: + redWeight = 0; + greenWeight = 0; + blueWeight = 1; + break; + case AvatarImage.CHANNELS_DESATURATED: + redWeight = 0.3086; + greenWeight = 0.6094; + blueWeight = 0.082; + break; + } + + const filter = new ColorMatrixFilter(); + + filter.matrix = [ + redWeight, greenWeight, blueWeight, 0, 0, // Red channel + redWeight, greenWeight, blueWeight, 0, 0, // Green channel + redWeight, greenWeight, blueWeight, 0, 0, // Blue channel + 0, 0, 0, 1, 0 // Alpha channel + ]; + + if(container.filters === undefined || container.filters === null) container.filters = [ filter ]; + else if(Array.isArray(container.filters)) container.filters = [ ...container.filters, filter ]; + else container.filters = [ container.filters, filter ]; + + return container; + } + + public isPlaceholder(): boolean + { + return false; + } + + public get animationHasResetOnToggle(): boolean + { + return this._animationHasResetOnToggle; + } + + 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/packages/avatar/src/AvatarImageBodyPartContainer.ts b/packages/avatar/src/AvatarImageBodyPartContainer.ts new file mode 100644 index 0000000..605ac12 --- /dev/null +++ b/packages/avatar/src/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.cleanPoints(); + } + + public dispose(): void + { + if(this._image) + { + this._image.destroy({ + children: true + }); + } + + this._image = null; + this._regPoint = null; + this._offset = null; + } + + private cleanPoints(): 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 setRegPoint(k: Point): void + { + this._regPoint = k; + + this.cleanPoints(); + } + + 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 regPoint(): 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.cleanPoints(); + } + + public get isCacheable(): boolean + { + return this._isCacheable; + } +} diff --git a/packages/avatar/src/AvatarImagePartContainer.ts b/packages/avatar/src/AvatarImagePartContainer.ts new file mode 100644 index 0000000..d891543 --- /dev/null +++ b/packages/avatar/src/AvatarImagePartContainer.ts @@ -0,0 +1,133 @@ +import { IActionDefinition, IPartColor } from '@nitrots/api'; +import { AvatarAnimationFrame } from './structure'; + +export class AvatarImagePartContainer +{ + private _bodyPartId: string; + private _partType: string; + private _flippedPartType: string; + private _partId: string; + private _color: IPartColor; + private _frames: AvatarAnimationFrame[]; + private _action: IActionDefinition; + private _isColorable: boolean; + private _isBlendable: boolean; + private _paletteMapId: number; + + constructor(bodyPartId: string, partType: string, partId: string, partColor: IPartColor, frames: AvatarAnimationFrame[], action: IActionDefinition, isColorable: boolean, paletteMapId: number, flippedPartType: string = '', isBlendable: boolean = false, _arg_11: number = 1) + { + this._bodyPartId = bodyPartId; + this._partType = partType; + this._partId = partId; + this._color = partColor; + this._frames = frames; + this._action = action; + this._isColorable = isColorable; + this._paletteMapId = paletteMapId; + this._flippedPartType = flippedPartType; + this._isBlendable = isBlendable; + + if(this._partType === 'ey') this._isColorable = false; + } + + public getFrameIndex(k: number): number + { + if(!this._frames || !this._frames.length) return 0; + + const frameNumber = (k % this._frames.length); + + if(this._frames[frameNumber] instanceof AvatarAnimationFrame) + { + return this._frames[frameNumber].number; + } + + return frameNumber; + } + + public getFrameDefinition(k: number): AvatarAnimationFrame + { + const frameNumber = (k % this._frames.length); + + if(this._frames && (this._frames.length > frameNumber)) + { + if(this._frames[frameNumber] instanceof AvatarAnimationFrame) + { + return this._frames[frameNumber]; + } + } + + return null; + } + + public getCacheableKey(k: number): string + { + const frameNumber = (k % this._frames.length); + + if(this._frames && (this._frames.length > frameNumber)) + { + if(this._frames[frameNumber] instanceof AvatarAnimationFrame) + { + const frame = this._frames[frameNumber]; + + return (this.partId + ':' + frame.assetPartDefinition + ':' + frame.number); + } + } + + return (this.partId + ':' + frameNumber); + } + + public get bodyPartId(): string + { + return this._bodyPartId; + } + + public get partType(): string + { + return this._partType; + } + + public get partId(): 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 paletteMapId(): number + { + return this._paletteMapId; + } + + public get flippedPartType(): string + { + return this._flippedPartType; + } + + public get isBlendable(): boolean + { + return this._isBlendable; + } + + public toString(): string + { + return [this._bodyPartId, this._partType, this._partId].join(':'); + } +} diff --git a/packages/avatar/src/AvatarRenderManager.ts b/packages/avatar/src/AvatarRenderManager.ts new file mode 100644 index 0000000..8c3d9e7 --- /dev/null +++ b/packages/avatar/src/AvatarRenderManager.ts @@ -0,0 +1,292 @@ +import { AvatarSetType, IAssetManager, IAvatarEffectListener, IAvatarFigureContainer, IAvatarImage, IAvatarImageListener, IAvatarRenderManager, IFigureData, IFigurePartSet, IGraphicAsset, IStructureData } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { GetConfiguration } from '@nitrots/configuration'; +import { GetEventDispatcher, NitroEventType } from '@nitrots/events'; +import { AvatarAssetDownloadManager } from './AvatarAssetDownloadManager'; +import { AvatarFigureContainer } from './AvatarFigureContainer'; +import { AvatarImage } from './AvatarImage'; +import { AvatarStructure } from './AvatarStructure'; +import { EffectAssetDownloadManager } from './EffectAssetDownloadManager'; +import { FigureDataContainer } from './FigureDataContainer'; +import { PlaceHolderAvatarImage } from './PlaceHolderAvatarImage'; +import { AssetAliasCollection } from './alias'; +import { HabboAvatarAnimations } from './data/HabboAvatarAnimations'; +import { HabboAvatarGeometry } from './data/HabboAvatarGeometry'; +import { HabboAvatarPartSets } from './data/HabboAvatarPartSets'; + +export class AvatarRenderManager implements IAvatarRenderManager +{ + private static DEFAULT_FIGURE: string = 'hd-99999-99999'; + + private _structure: AvatarStructure = new AvatarStructure(this); + private _aliasCollection: AssetAliasCollection = new AssetAliasCollection(this, GetAssetManager()); + private _avatarAssetDownloadManager: AvatarAssetDownloadManager = new AvatarAssetDownloadManager(GetAssetManager(), this._structure); + private _effectAssetDownloadManager: EffectAssetDownloadManager = new EffectAssetDownloadManager(GetAssetManager(), this._structure); + + private _placeHolderFigure: AvatarFigureContainer = new AvatarFigureContainer(AvatarRenderManager.DEFAULT_FIGURE); + + public async init(): Promise + { + this._structure?.initGeometry(HabboAvatarGeometry.geometry); + this._structure?.initPartSets(HabboAvatarPartSets.partSets); + + await this.loadActions(); + + this._structure?.initAnimation(HabboAvatarAnimations.animations); + await this.loadFigureData(); + + this._aliasCollection.init(); + + GetEventDispatcher().addEventListener(NitroEventType.AVATAR_ASSET_LOADED, () => this._aliasCollection.reset()); + GetEventDispatcher().addEventListener(NitroEventType.AVATAR_EFFECT_LOADED, () => this._aliasCollection.reset()); + + await this._avatarAssetDownloadManager.init(); + await this._effectAssetDownloadManager.init(); + } + + private async loadActions(): Promise + { + const defaultActions = GetConfiguration().getValue('avatar.default.actions'); + + if(defaultActions) this._structure.initActions(GetAssetManager(), defaultActions); + + const url = GetConfiguration().getValue('avatar.actions.url'); + + if(!url || !url.length) throw new Error('Invalid avatar action url'); + + const response = await fetch(url); + + if(response.status !== 200) throw new Error('Invalid avatar action file'); + + this._structure.updateActions(await response.json()); + } + + private async loadFigureData(): Promise + { + const defaultFigureData = GetConfiguration().getValue('avatar.default.figuredata'); + + if(defaultFigureData) this._structure?.initFigureData(defaultFigureData); + + const url = GetConfiguration().getValue('avatar.figuredata.url'); + + if(!url || !url.length) throw new Error('Invalid figure data url'); + + const response = await fetch(url); + + if(response.status !== 200) throw new Error('Invalid figure data file'); + + this._structure.figureData.appendJSON(await response.json()); + + this._structure.init(); + } + + 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); + } + + 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.getMandatorySetTypeIds(gender, 2); + + if(typeIds) + { + const figureData = this._structure.figureData; + + for(const id of typeIds) + { + if(!container.hasPartType(id)) + { + const figurePartSet = this._structure.getDefaultPartSet(id, gender); + + if(figurePartSet) + { + container.updatePart(id, figurePartSet.id, [0]); + + isValid = true; + } + } + else + { + const setType = figureData.getSetType(id); + + if(setType) + { + const figurePartSet = setType.getPartSet(container.getPartSetId(id)); + + if(!figurePartSet) + { + const partSet = this._structure.getDefaultPartSet(id, gender); + + if(partSet) + { + container.updatePart(id, partSet.id, [0]); + + isValid = true; + } + } + } + } + } + } + + return !(isValid); + } + + public getFigureClubLevel(container: IAvatarFigureContainer, gender: string, searchParts: string[] = null): number + { + if(!this._structure) return 0; + + const figureData = this._structure.figureData; + const parts = Array.from(container.getPartTypeIds()); + + let clubLevel = 0; + + for(const part of parts) + { + const set = figureData.getSetType(part); + + if(!set) continue; + + const setId = container.getPartSetId(part); + const partSet = set.getPartSet(setId); + + if(partSet) + { + clubLevel = Math.max(partSet.clubLevel, clubLevel); + + const palette = figureData.getPalette(set.paletteID); + const colors = container.getPartColorIds(part); + + for(const colorId of colors) + { + const color = palette.getColor(colorId); + + if(!color) continue; + + clubLevel = Math.max(color.clubLevel, clubLevel); + } + } + } + + if(!searchParts) searchParts = this._structure.getBodyPartsUnordered(AvatarSetType.FULL); + + for(const part of searchParts) + { + const set = figureData.getSetType(part); + + if(!set) continue; + + if(parts.indexOf(part) === -1) clubLevel = Math.max(set.optionalFromClubLevel(gender), clubLevel); + } + + return clubLevel; + } + + public isValidFigureSetForGender(setId: number, gender: string): boolean + { + const structure = this.structureData; + const partSet = structure.getFigurePartSet(setId); + + return !!(partSet && ((partSet.gender.toUpperCase() === 'U') || (partSet.gender.toUpperCase() === gender.toUpperCase()))); + } + + public getFigureStringWithFigureIds(figure: string, gender: string, _arg_3: number[]): string + { + const container = new FigureDataContainer(); + + container.loadAvatarData(figure, gender); + + const partSets: IFigurePartSet[] = this.resolveFigureSets(_arg_3); + + for(const partSet of partSets) + { + container.savePartData(partSet.type, partSet.id, container.getColourIds(partSet.type)); + } + + return container.getFigureString(); + } + + private resolveFigureSets(setIds: number[]): IFigurePartSet[] + { + const structure = this.structureData; + const partSets: IFigurePartSet[] = []; + + for(const setId of setIds) + { + const partSet = structure.getFigurePartSet(setId); + + if(partSet) partSets.push(partSet); + } + + return partSets; + } + + public getMandatoryAvatarPartSetIds(k: string, _arg_2: number): string[] + { + if(!this._structure) return null; + + return this._structure.getMandatorySetTypeIds(k, _arg_2); + } + + public getAssetByName(name: string): IGraphicAsset + { + return this._aliasCollection.getAsset(name); + } + + public get assets(): IAssetManager + { + return GetAssetManager(); + } + + 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/packages/avatar/src/AvatarStructure.ts b/packages/avatar/src/AvatarStructure.ts new file mode 100644 index 0000000..4d841d4 --- /dev/null +++ b/packages/avatar/src/AvatarStructure.ts @@ -0,0 +1,619 @@ +import { AvatarDirectionAngle, IActionDefinition, IActiveActionData, IAssetAnimation, IAssetManager, IAvatarFigureContainer, IAvatarImage, IAvatarRenderManager, IFigureData, IFigurePartSet, IPartColor, IStructureData } from '@nitrots/api'; +import { Point } from 'pixi.js'; +import { AvatarImagePartContainer } from './AvatarImagePartContainer'; +import { AvatarRenderManager } from './AvatarRenderManager'; +import { ActionDefinition, AvatarActionManager } from './actions'; +import { Animation, AnimationManager, AvatarAnimationLayerData } from './animation'; +import { AvatarModelGeometry } from './geometry'; +import { AnimationAction, AvatarAnimationData, AvatarAnimationFrame, AvatarCanvas, FigureSetData, PartSetsData } from './structure'; + +export class AvatarStructure +{ + private _renderManager: AvatarRenderManager; + private _geometry: AvatarModelGeometry; + private _figureData: FigureSetData; + private _partSetsData: PartSetsData; + private _animationData: AvatarAnimationData; + private _animationManager: AnimationManager; + private _mandatorySetTypeIds: { [index: string]: { [index: number]: string[] } }; + private _actionManager: AvatarActionManager; + private _defaultAction: IActionDefinition; + + constructor(renderManager: AvatarRenderManager) + { + this._renderManager = renderManager; + this._geometry = null; + this._figureData = new FigureSetData(); + this._partSetsData = new PartSetsData(); + this._animationData = new AvatarAnimationData(); + this._animationManager = new AnimationManager(); + this._mandatorySetTypeIds = {}; + this._actionManager = null; + this._defaultAction = null; + } + + public init(): void + { + + } + + public initGeometry(k: any): void + { + if(!k) return; + + this._geometry = new AvatarModelGeometry(k); + } + + public initActions(k: IAssetManager, _arg_2: any): void + { + if(!_arg_2) return; + + this._actionManager = new AvatarActionManager(k, _arg_2); + this._defaultAction = this._actionManager.getDefaultAction(); + } + + public updateActions(data: any): void + { + this._actionManager.updateActions(data); + + this._defaultAction = this._actionManager.getDefaultAction(); + } + + public initPartSets(k: any): boolean + { + if(!k) return false; + + if(this._partSetsData.parse(k)) + { + this._partSetsData.getPartDefinition('ri').appendToFigure = true; + this._partSetsData.getPartDefinition('li').appendToFigure = true; + + return true; + } + + return false; + } + + public initAnimation(k: any): boolean + { + if(!k) return false; + + return this._animationData.parse(k); + } + + public initFigureData(k: IFigureData): boolean + { + if(!k) return false; + + return this._figureData.parse(k); + } + + public injectFigureData(data: IFigureData): void + { + this._figureData.injectJSON(data); + } + + public registerAnimations(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.registerAnimation(this, animationData.animations); + } + + index++; + } + } + + public registerAnimation(data: { [index: string]: IAssetAnimation }): void + { + this._animationManager.registerAnimation(this, data); + } + + public getPartColor(k: IAvatarFigureContainer, _arg_2: string, _arg_3: number = 0): IPartColor + { + const _local_4 = k.getPartColorIds(_arg_2); + + if((!(_local_4)) || (_local_4.length < _arg_3)) return null; + + const _local_5 = this._figureData.getSetType(_arg_2); + + if(_local_5 == null) return null; + + const _local_6 = this._figureData.getPalette(_local_5.paletteID); + + if(!_local_6) return null; + + return _local_6.getColor(_local_4[_arg_3]); + } + + public getBodyPartData(animation: string, frameCount: number, spriteId: string): AvatarAnimationLayerData + { + return this._animationManager.getLayerData(animation, frameCount, spriteId) as AvatarAnimationLayerData; + } + + public getAnimation(k: string): Animation + { + return this._animationManager.getAnimation(k) as Animation; + } + + public getActionDefinition(k: string): ActionDefinition + { + return this._actionManager.getActionDefinition(k); + } + + public getActionDefinitionWithState(k: string): ActionDefinition + { + return this._actionManager.getActionDefinitionWithState(k); + } + + public isMainAvatarSet(k: string): boolean + { + return this._geometry.isMainAvatarSet(k); + } + + public sortActions(k: IActiveActionData[]): IActiveActionData[] + { + return this._actionManager.sortActions(k); + } + + public maxFrames(k: IActiveActionData[]): number + { + let _local_2 = 0; + + for(const _local_3 of k) + { + _local_2 = Math.max(_local_2, this._animationData.getFrameCount(_local_3.definition)); + } + return _local_2; + } + + public getMandatorySetTypeIds(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.getMandatorySetTypeIds(k, _arg_2); + + return this._mandatorySetTypeIds[k][_arg_2]; + } + + public getDefaultPartSet(k: string, _arg_2: string): IFigurePartSet + { + return this._figureData.getDefaultPartSet(k, _arg_2); + } + + public getCanvasOffsets(k: IActiveActionData[], _arg_2: string, _arg_3: number): number[] + { + return this._actionManager.getCanvasOffsets(k, _arg_2, _arg_3); + } + + public getCanvas(k: string, _arg_2: string): AvatarCanvas + { + return this._geometry.getCanvas(k, _arg_2); + } + + public removeDynamicItems(k: IAvatarImage): void + { + this._geometry.removeDynamicItems(k); + } + + public getActiveBodyPartIds(k: IActiveActionData, _arg_2: IAvatarImage): string[] + { + let _local_3: string[] = []; + + const _local_4: string[] = []; + const _local_5 = k.definition.geometryType; + + if(k.definition.isAnimation) + { + const _local_7 = ((k.definition.state + '.') + k.actionParameter); + const _local_8 = this._animationManager.getAnimation(_local_7); + + if(_local_8) + { + _local_3 = _local_8.getAnimatedBodyPartIds(0, k.overridingAction); + + if(_local_8.hasAddData()) + { + 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.addData) + { + const _local_6 = this._geometry.getBodyPart(_local_5, _local_13.align); + + if(_local_6) + { + _local_11.id = _local_13.id; + _local_6.addPart(_local_11, _arg_2); + + _local_12.setType = _local_13.id; + + const _local_10 = this._partSetsData.addPartDefinition(_local_12); + _local_10.appendToFigure = true; + + if(_local_13.base === '') _local_10.staticId = 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.getBodyPart(_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.getActiveParts(k.definition); + + for(const _local_14 of _local_3) + { + const _local_6 = this._geometry.getBodyPartOfItem(_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 getBodyPartsUnordered(k: string): string[] + { + return this._geometry.getBodyPartIdsInAvatarSet(k); + } + + public getBodyParts(k: string, _arg_2: string, _arg_3: number): string[] + { + const _local_4 = AvatarDirectionAngle.DIRECTION_TO_ANGLE[_arg_3]; + + return this._geometry.getBodyPartsAtAngle(k, _local_4, _arg_2); + } + + public getFrameBodyPartOffset(k: IActiveActionData, _arg_2: number, _arg_3: number, _arg_4: string): Point + { + const _local_5 = this._animationData.getAction(k.definition); + + if(_local_5) return _local_5.getFrameBodyPartOffset(_arg_2, _arg_3, _arg_4); + + return AnimationAction.DEFAULT_OFFSET; + } + + public getParts(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: AvatarAnimationFrame[] = []; + let _local_36: IPartColor = null; + + if(!_arg_3 == null) return []; + + const _local_9 = this._partSetsData.getActiveParts(_arg_3.definition); + const _local_11: AvatarImagePartContainer[] = []; + let _local_14: any[] = [0]; + const _local_15 = this._animationData.getAction(_arg_3.definition); + + if(_arg_3.definition.isAnimation) + { + const _local_24 = ((_arg_3.definition.state + '.') + _arg_3.actionParameter); + const _local_10 = this._animationManager.getAnimation(_local_24); + + if(_local_10) + { + _local_14 = this.getPopulatedArray(_local_10.frameCount(_arg_3.overridingAction)); + + for(const _local_25 of _local_10.getAnimatedBodyPartIds(0, _arg_3.overridingAction)) + { + if(_local_25 === k) + { + const _local_26 = this._geometry.getBodyPart(_arg_4, _local_25); + + if(_local_26) + { + for(const _local_27 of _local_26.getDynamicParts(_arg_7)) + { + _local_9.push(_local_27.id); + } + } + } + } + } + } + + const _local_16 = this._geometry.getParts(_arg_4, k, _arg_5, _local_9, _arg_7); + const _local_21 = _arg_2.getPartTypeIds(); + + 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.getPartColorIds(_local_17); + const _local_30 = this._figureData.getSetType(_local_17); + + + + if(_local_30) + { + const _local_31 = this._figureData.getPalette(_local_30.paletteID); + + if(_local_31) + { + const _local_32 = _local_30.getPartSet(_local_28); + + if(_local_32) + { + removes = removes.concat(_local_32.hiddenLayers); + + for(const _local_33 of _local_32.parts) + { + if(_local_16.indexOf(_local_33.type) > -1) + { + if(_local_15) + { + const _local_19 = _local_15.getPart(_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.definition; + + if(_local_9.indexOf(_local_33.type) === -1) _local_34 = this._defaultAction; + + const _local_13 = this._partSetsData.getPartDefinition(_local_33.type); + + let _local_35 = (!_local_13) ? _local_33.type : _local_13.flippedSetType; + + if(!_local_35 || (_local_35 === '')) _local_35 = _local_33.type; + + if(_local_29 && (_local_29.length > (_local_33.colorLayerIndex - 1))) + { + _local_36 = _local_31.getColor(_local_29[(_local_33.colorLayerIndex - 1)]); + } + + const _local_37 = (_local_33.colorLayerIndex > 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.partType === _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.getPart(_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.definition, (!(_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.getBodyPartOfItem(_arg_4, _local_12, _arg_7); + + if(k !== _local_44.id) + { + // + } + else + { + const _local_13 = this._partSetsData.getPartDefinition(_local_12); + + let _local_45 = false; + let _local_46 = 1; + + if(_local_13.appendToFigure) + { + let _local_47 = '1'; + + if(_arg_3.actionParameter !== '') + { + _local_47 = _arg_3.actionParameter; + } + + if(_local_13.hasStaticId()) + { + _local_47 = _local_13.staticId.toString(); + } + + if(_local_10 != null) + { + const _local_48 = _local_10.getAddData(_local_12); + + if(_local_48) + { + _local_45 = _local_48.isBlended; + _local_46 = _local_48.blend; + } + } + + if(_local_15) + { + const _local_19 = _local_15.getPart(_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.definition, false, -1, _local_12, _local_45, _local_46); + + _local_22.push(_local_18); + } + } + } + } + } + } + + return _local_22; + } + + private getPopulatedArray(k: number): number[] + { + const _local_2: number[] = []; + + let index = 0; + + while(index < k) + { + _local_2.push(index); + + index++; + } + + return _local_2; + } + + public getItemIds(): string[] + { + if(this._actionManager) + { + const k = this._actionManager.getActionDefinition('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/packages/avatar/src/EffectAssetDownloadLibrary.ts b/packages/avatar/src/EffectAssetDownloadLibrary.ts new file mode 100644 index 0000000..26adf0a --- /dev/null +++ b/packages/avatar/src/EffectAssetDownloadLibrary.ts @@ -0,0 +1,75 @@ +import { IAssetAnimation, IAssetManager, IEffectAssetDownloadLibrary } from '@nitrots/api'; +import { AvatarRenderEffectLibraryEvent, GetEventDispatcher, NitroEventType } from '@nitrots/events'; + +export class EffectAssetDownloadLibrary implements IEffectAssetDownloadLibrary +{ + 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 = EffectAssetDownloadLibrary.NOT_LOADED; + private _libraryName: string; + private _revision: string; + private _downloadUrl: string; + private _assetManager: IAssetManager; + private _animation: { [index: string]: IAssetAnimation } = null; + + constructor(libraryName: string, revision: string, downloadUrl: string, assetManager: IAssetManager) + { + this._libraryName = libraryName; + this._revision = revision; + this._downloadUrl = downloadUrl; + this._assetManager = assetManager; + + this._downloadUrl = this._downloadUrl.replace(/%libname%/gi, this._libraryName); + this._downloadUrl = this._downloadUrl.replace(/%revision%/gi, this._revision); + + this.checkIsLoaded(); + } + + public async downloadAsset(): Promise + { + if(!this._assetManager || (this._state === EffectAssetDownloadLibrary.LOADING) || (this._state === EffectAssetDownloadLibrary.LOADED)) return; + + if(!this.checkIsLoaded()) + { + this._state = EffectAssetDownloadLibrary.LOADING; + + const status = await this._assetManager.downloadAsset(this._downloadUrl); + + if(!status) throw new Error('Could not download asset'); + } + + if(this.checkIsLoaded()) GetEventDispatcher().dispatchEvent(new AvatarRenderEffectLibraryEvent(NitroEventType.AVATAR_EFFECT_DOWNLOADED, this)); + } + + private checkIsLoaded(): boolean + { + const asset = this._assetManager.getCollection(this._libraryName); + + if(!asset) return false; + + this._state = EffectAssetDownloadLibrary.LOADED; + + this._animation = asset.data.animations; + + return true; + } + + 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/packages/avatar/src/EffectAssetDownloadManager.ts b/packages/avatar/src/EffectAssetDownloadManager.ts new file mode 100644 index 0000000..33e8afd --- /dev/null +++ b/packages/avatar/src/EffectAssetDownloadManager.ts @@ -0,0 +1,206 @@ +import { IAssetManager, IAvatarEffectListener } from '@nitrots/api'; +import { GetConfiguration } from '@nitrots/configuration'; +import { AvatarRenderEffectLibraryEvent, GetEventDispatcher, NitroEvent, NitroEventType } from '@nitrots/events'; +import { AvatarStructure } from './AvatarStructure'; +import { EffectAssetDownloadLibrary } from './EffectAssetDownloadLibrary'; + +export class EffectAssetDownloadManager +{ + private _assets: IAssetManager; + private _structure: AvatarStructure; + + private _missingMandatoryLibs: string[] = []; + private _effectMap: Map = new Map(); + private _effectListeners: Map = new Map(); + private _incompleteEffects: Map = new Map(); + private _currentDownloads: EffectAssetDownloadLibrary[] = []; + private _libraryNames: string[] = []; + + constructor(assets: IAssetManager, structure: AvatarStructure) + { + this._assets = assets; + this._structure = structure; + } + + public async init(): Promise + { + this._missingMandatoryLibs = GetConfiguration().getValue('avatar.mandatory.effect.libraries'); + + const url = GetConfiguration().getValue('avatar.effectmap.url'); + + if(!url || !url.length) throw new Error('Invalid effect map url'); + + const response = await fetch(url); + + if(response.status !== 200) throw new Error('Invalid effect map file'); + + const responseData = await response.json(); + + this.processEffectMap(responseData.effects); + + GetEventDispatcher().addEventListener(NitroEventType.AVATAR_EFFECT_DOWNLOADED, (event: AvatarRenderEffectLibraryEvent) => this.onLibraryLoaded(event)); + + await this.processMissingLibraries(); + } + + private processEffectMap(data: any): void + { + if(!data) return; + + const downloadUrl = GetConfiguration().getValue('avatar.asset.effect.url'); + + for(const effect of data) + { + if(!effect) continue; + + const id = (effect.id as string); + const libraryName = (effect.lib as string); + const revision = (effect.revision || ''); + + if(this._libraryNames.indexOf(libraryName) >= 0) continue; + + this._libraryNames.push(libraryName); + + const downloadLibrary = new EffectAssetDownloadLibrary(libraryName, revision, downloadUrl, this._assets); + + let existing = this._effectMap.get(id); + + if(!existing) existing = []; + + existing.push(downloadLibrary); + + this._effectMap.set(id, existing); + } + } + + private async processMissingLibraries(): Promise + { + const promises: Promise[] = []; + + this._missingMandatoryLibs.forEach(value => + { + const libraries = this._effectMap.get(value); + + if(libraries) for(const library of libraries) promises.push(library.downloadAsset()); + }); + + this._missingMandatoryLibs = []; + + await Promise.all(promises); + } + + private onLibraryLoaded(event: AvatarRenderEffectLibraryEvent): void + { + if(!event || !event.library) return; + + const loadedEffects: string[] = []; + + this._structure.registerAnimation(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); + + GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.AVATAR_EFFECT_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 isAvatarEffectReady(effect: number): boolean + { + return !this.getAvatarEffectPendingLibraries(effect).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; + } + + public downloadAvatarEffect(id: number, listener: IAvatarEffectListener): void + { + 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; + + library.downloadAsset(); + } + } + else + { + if(listener && !listener.disposed) listener.resetEffect(id); + } + } +} diff --git a/packages/avatar/src/FigureDataContainer.ts b/packages/avatar/src/FigureDataContainer.ts new file mode 100644 index 0000000..71dd487 --- /dev/null +++ b/packages/avatar/src/FigureDataContainer.ts @@ -0,0 +1,241 @@ +export class FigureDataContainer +{ + private static MALE: string = 'M'; + private static FEMALE: string = 'F'; + private static UNISEX: string = 'U'; + private static SCALE: string = 'h'; + private static STD: string = 'std'; + private static DEFAULT_FRAME: string = '0'; + private static HD: string = 'hd'; + private static HAIR: string = 'hr'; + private static HAT: string = 'ha'; + private static HEAD_ACCESSORIES: string = 'he'; + private static EYE_ACCESSORIES: string = 'ea'; + private static FACE_ACCESSORIES: string = 'fa'; + private static JACKET: string = 'cc'; + private static SHIRT: string = 'ch'; + private static CHEST_ACCESSORIES: string = 'ca'; + private static CHEST_PRINTS: string = 'cp'; + private static TROUSERS: string = 'lg'; + private static SHOES: string = 'sh'; + private static TROUSER_ACCESSORIES: string = 'wa'; + private static BLOCKED_FX_TYPES: 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 loadAvatarData(figure: string, gender: string): void + { + this._data = new Map(); + this._colors = new Map(); + this._gender = gender; + + this.parseFigureString(figure); + } + + public dispose(): void + { + this._data = null; + this._colors = null; + this._isDisposed = true; + } + + public get disposed(): boolean + { + return this._isDisposed; + } + + private parseFigureString(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.savePartSetId(part, setId, false); + this.savePartSetColourId(part, colors, false); + } + } + } + + public hasSetType(k: string): boolean + { + return !!this._data.get(k); + } + + public getPartSetId(k: string): number + { + if(this.hasSetType(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 getFigureString(): 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 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 FigureDataContainer.HD: + case FigureDataContainer.HAIR: + case FigureDataContainer.HAT: + case FigureDataContainer.HEAD_ACCESSORIES: + case FigureDataContainer.EYE_ACCESSORIES: + case FigureDataContainer.FACE_ACCESSORIES: + case FigureDataContainer.SHIRT: + case FigureDataContainer.JACKET: + case FigureDataContainer.CHEST_ACCESSORIES: + case FigureDataContainer.CHEST_PRINTS: + case FigureDataContainer.TROUSERS: + case FigureDataContainer.SHOES: + case FigureDataContainer.TROUSER_ACCESSORIES: + 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.HAIR: + case FigureDataContainer.HAT: + case FigureDataContainer.HEAD_ACCESSORIES: + case FigureDataContainer.EYE_ACCESSORIES: + case FigureDataContainer.FACE_ACCESSORIES: + case FigureDataContainer.SHIRT: + case FigureDataContainer.JACKET: + case FigureDataContainer.CHEST_ACCESSORIES: + case FigureDataContainer.CHEST_PRINTS: + case FigureDataContainer.TROUSERS: + case FigureDataContainer.SHOES: + case FigureDataContainer.TROUSER_ACCESSORIES: + 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; + } +} diff --git a/packages/avatar/src/GetAvatarRenderManager.ts b/packages/avatar/src/GetAvatarRenderManager.ts new file mode 100644 index 0000000..c6cef25 --- /dev/null +++ b/packages/avatar/src/GetAvatarRenderManager.ts @@ -0,0 +1,5 @@ +import { AvatarRenderManager } from './AvatarRenderManager'; + +const avatarRenderManager = new AvatarRenderManager(); + +export const GetAvatarRenderManager = () => avatarRenderManager; diff --git a/packages/avatar/src/PlaceHolderAvatarImage.ts b/packages/avatar/src/PlaceHolderAvatarImage.ts new file mode 100644 index 0000000..1a56373 --- /dev/null +++ b/packages/avatar/src/PlaceHolderAvatarImage.ts @@ -0,0 +1,18 @@ +import { AssetAliasCollection } from './alias'; +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; + } +} diff --git a/packages/avatar/src/actions/ActionDefinition.ts b/packages/avatar/src/actions/ActionDefinition.ts new file mode 100644 index 0000000..0f16d70 --- /dev/null +++ b/packages/avatar/src/actions/ActionDefinition.ts @@ -0,0 +1,220 @@ +import { IActionDefinition } from '@nitrots/api'; +import { ActionType } from './ActionType'; + +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 = new Map(); + private _params: Map = new Map(); + private _defaultParameterValue: string = ''; + private _canvasOffsets: Map> = new 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; + + 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 setOffsets(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 getOffsets(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 getParameterValue(id: string): string + { + if(!id) return ''; + + const existing = this._params.get(id); + + if(!existing) return this._defaultParameterValue; + + return existing; + } + + public getPrevents(type: string): string[] + { + return this._prevents.concat(this.getTypePrevents(type)); + } + + private getTypePrevents(type: string): string[] + { + if(!type) return []; + + const existing = this._types.get(parseInt(type)); + + if(!existing) return []; + + return existing.prevents; + } + + public getPreventHeadTurn(k: string): boolean + { + if(!k) return this._preventHeadTurn; + + const type = this.getType(k); + + if(!type) return this._preventHeadTurn; + + return type.preventHeadTurn; + } + + public isAnimated(k: string): boolean + { + if(!k) return true; + + const type = this.getType(k); + + if(!type) return true; + + return type.isAnimated; + } + + 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 assetPartDefinition(): string + { + return this._assetPartDefinition; + } + + public get lay(): string + { + return this._lay; + } + + public get geometryType(): string + { + return this._geometryType; + } + + public get isMain(): boolean + { + return this._isMain; + } + + public get isDefault(): boolean + { + return this._isDefault; + } + + public get isAnimation(): boolean + { + return this._isAnimation; + } + + public get startFromFrameZero(): 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; + } +} diff --git a/packages/avatar/src/actions/ActionType.ts b/packages/avatar/src/actions/ActionType.ts new file mode 100644 index 0000000..d6d0312 --- /dev/null +++ b/packages/avatar/src/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 preventHeadTurn(): boolean + { + return this._preventHeadTurn; + } + + public get isAnimated(): boolean + { + return this._isAnimated; + } +} diff --git a/packages/avatar/src/actions/ActiveActionData.ts b/packages/avatar/src/actions/ActiveActionData.ts new file mode 100644 index 0000000..7578e20 --- /dev/null +++ b/packages/avatar/src/actions/ActiveActionData.ts @@ -0,0 +1,73 @@ +import { IActionDefinition, IActiveActionData } from '@nitrots/api'; + +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 actionType(): string + { + return this._actionType; + } + + public get actionParameter(): string + { + return this._actionParameter; + } + + public set actionParameter(parameter: string) + { + this._actionParameter = parameter; + } + + public get definition(): IActionDefinition + { + return this._definition; + } + + public set definition(definition: IActionDefinition) + { + this._definition = definition; + } + + public get startFrame(): number + { + return this._startFrame; + } + + public get overridingAction(): string + { + return this._overridingAction; + } + + public set overridingAction(action: string) + { + this._overridingAction = action; + } +} diff --git a/packages/avatar/src/actions/AvatarActionManager.ts b/packages/avatar/src/actions/AvatarActionManager.ts new file mode 100644 index 0000000..eee1eef --- /dev/null +++ b/packages/avatar/src/actions/AvatarActionManager.ts @@ -0,0 +1,186 @@ +import { IActiveActionData, IAssetManager } from '@nitrots/api'; +import { ActionDefinition } from './ActionDefinition'; + +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.updateActions(data); + } + + public updateActions(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.parseActionOffsets(data.actionOffsets); + } + + private parseActionOffsets(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.setOffsets(size, direction, [x, y, z]); + } + } + } + + public getActionDefinition(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 getActionDefinitionWithState(state: string): ActionDefinition + { + const existing = this._actions.get(state); + + if(!existing) return null; + + return existing; + } + + public getDefaultAction(): ActionDefinition + { + if(this._defaultAction) return this._defaultAction; + + for(const action of this._actions.values()) + { + if(!action || !action.isDefault) continue; + + this._defaultAction = action; + + return action; + } + + return null; + } + + public getCanvasOffsets(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.actionType); + const offsets = action && action.getOffsets(_arg_2, _arg_3); + + if(offsets) canvasOffsets = offsets; + } + + return canvasOffsets; + } + + public sortActions(actions: IActiveActionData[]): IActiveActionData[] + { + if(!actions) return null; + + actions = this.filterActions(actions); + + const validatedActions: IActiveActionData[] = []; + + for(const action of actions) + { + if(!action) continue; + + const definition = this._actions.get(action.actionType); + + if(!definition) continue; + + action.definition = definition; + + validatedActions.push(action); + } + + validatedActions.sort(this.sortByPrecedence); + + return validatedActions; + } + + private filterActions(actions: IActiveActionData[]): IActiveActionData[] + { + let preventions: string[] = []; + const activeActions: IActiveActionData[] = []; + + for(const action of actions) + { + if(!action) continue; + + const localAction = this._actions.get(action.actionType); + + if(localAction) preventions = preventions.concat(localAction.getPrevents(action.actionParameter)); + } + + for(const action of actions) + { + if(!action) continue; + + let actionType = action.actionType; + + if(action.actionType === 'fx') actionType = (actionType + ('.' + action.actionParameter)); + + 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.definition.precedence; + const precedenceTwo = actionTwo.definition.precedence; + + if(precedenceOne < precedenceTwo) return 1; + + if(precedenceOne > precedenceTwo) return -1; + + return 0; + } +} diff --git a/packages/avatar/src/actions/index.ts b/packages/avatar/src/actions/index.ts new file mode 100644 index 0000000..a849536 --- /dev/null +++ b/packages/avatar/src/actions/index.ts @@ -0,0 +1,4 @@ +export * from './ActionDefinition'; +export * from './ActionType'; +export * from './ActiveActionData'; +export * from './AvatarActionManager'; diff --git a/packages/avatar/src/alias/AssetAlias.ts b/packages/avatar/src/alias/AssetAlias.ts new file mode 100644 index 0000000..fd07c13 --- /dev/null +++ b/packages/avatar/src/alias/AssetAlias.ts @@ -0,0 +1,37 @@ +import { IAssetAlias } from '@nitrots/api'; + +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/packages/avatar/src/alias/AssetAliasCollection.ts b/packages/avatar/src/alias/AssetAliasCollection.ts new file mode 100644 index 0000000..e4aec28 --- /dev/null +++ b/packages/avatar/src/alias/AssetAliasCollection.ts @@ -0,0 +1,89 @@ +import { IAssetManager, IGraphicAsset } from '@nitrots/api'; +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 hasAlias(k: string): boolean + { + const alias = this._aliases.get(k); + + if(alias) return true; + + return false; + } + + public getAssetName(k: string): string + { + let _local_2 = k; + let _local_3 = 5; + + while(this.hasAlias(_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.getAssetName(name); + + const asset = this._assets.getAsset(name); + + if(!asset) return null; + + return asset; + } +} diff --git a/packages/avatar/src/alias/index.ts b/packages/avatar/src/alias/index.ts new file mode 100644 index 0000000..7d9524c --- /dev/null +++ b/packages/avatar/src/alias/index.ts @@ -0,0 +1,2 @@ +export * from './AssetAlias'; +export * from './AssetAliasCollection'; diff --git a/packages/avatar/src/animation/AddDataContainer.ts b/packages/avatar/src/animation/AddDataContainer.ts new file mode 100644 index 0000000..d0ede74 --- /dev/null +++ b/packages/avatar/src/animation/AddDataContainer.ts @@ -0,0 +1,61 @@ +import { IAssetAnimationAdd } from '@nitrots/api'; + +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 isBlended(): boolean + { + return this._blend !== 1; + } +} diff --git a/packages/avatar/src/animation/Animation.ts b/packages/avatar/src/animation/Animation.ts new file mode 100644 index 0000000..b6defc0 --- /dev/null +++ b/packages/avatar/src/animation/Animation.ts @@ -0,0 +1,311 @@ +import { IAnimation, IAssetAnimation, IAssetAnimationFrame } from '@nitrots/api'; +import { AvatarStructure } from '../AvatarStructure'; +import { AddDataContainer } from './AddDataContainer'; +import { AvatarAnimationLayerData } from './AvatarAnimationLayerData'; +import { AvatarDataContainer } from './AvatarDataContainer'; +import { DirectionDataContainer } from './DirectionDataContainer'; +import { SpriteDataContainer } from './SpriteDataContainer'; + +export class Animation implements IAnimation +{ + private static EMPTY_ARRAY: any[] = []; + + private _id: string; + private _description: string; + private _frames: AvatarAnimationLayerData[][]; + 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: AvatarAnimationLayerData[][] = []; + + this.parseFrames(frames, override.frames, k); + + this._overrideFrames.set(name, frames); + } + } + + this.parseFrames(this._frames, _arg_2.frames, k); + } + + private parseFrames(frames: AvatarAnimationLayerData[][], _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: AvatarAnimationLayerData[] = []; + + if(frame.bodyparts && frame.bodyparts.length) + { + for(const bodyPart of frame.bodyparts) + { + const definition = _arg_3.getActionDefinition(bodyPart.action); + const layer = new AvatarAnimationLayerData(bodyPart, AvatarAnimationLayerData.BODYPART, definition); + + layers.push(layer); + } + } + + if(frame.fxs && frame.fxs.length) + { + for(const fx of frame.fxs) + { + const definition = _arg_3.getActionDefinition(fx.action); + const layer = new AvatarAnimationLayerData(fx, AvatarAnimationLayerData.FX, definition); + + layers.push(layer); + } + } + + frames.push(layers); + + index++; + } + } + } + + public frameCount(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 hasOverriddenActions(): boolean + { + if(!this._overriddenActions) return false; + + return (this._overriddenActions.size > 0); + } + + public overriddenActionNames(): string[] + { + if(!this._overriddenActions) return null; + + const keys: string[] = []; + + for(const key of this._overriddenActions.keys()) keys.push(key); + + return keys; + } + + public overridingAction(k: string): string + { + if(!this._overriddenActions) return null; + + return this._overriddenActions.get(k); + } + + private getFrame(frameCount: number, _arg_2: string = null): AvatarAnimationLayerData[] + { + if(frameCount < 0) frameCount = 0; + + let layers: AvatarAnimationLayerData[] = []; + + 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 getAnimatedBodyPartIds(k: number, _arg_2: string = null): string[] + { + const _local_3: string[] = []; + + for(const layer of this.getFrame(k, _arg_2)) + { + if(layer.type === AvatarAnimationLayerData.BODYPART) + { + _local_3.push(layer.id); + } + + else if(layer.type === AvatarAnimationLayerData.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 getLayerData(frameCount: number, spriteId: string, _arg_3: string = null): AvatarAnimationLayerData + { + for(const layer of this.getFrame(frameCount, _arg_3)) + { + if(layer.id === spriteId) return layer; + + if(layer.type === AvatarAnimationLayerData.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 hasAvatarData(): boolean + { + return this._avatarData !== null; + } + + public hasDirectionData(): boolean + { + return this._directionData !== null; + } + + public hasAddData(): boolean + { + return this._addData !== null; + } + + public getAddData(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 spriteData(): SpriteDataContainer[] + { + return this._spriteData || Animation.EMPTY_ARRAY; + } + + public get avatarData(): AvatarDataContainer + { + return this._avatarData; + } + + public get directionData(): DirectionDataContainer + { + return this._directionData; + } + + public get removeData(): string[] + { + return this._removeData || Animation.EMPTY_ARRAY; + } + + public get addData(): AddDataContainer[] + { + return this._addData || Animation.EMPTY_ARRAY; + } + + public toString(): string + { + return this._description; + } + + public get resetOnToggle(): boolean + { + return this._resetOnToggle; + } +} diff --git a/packages/avatar/src/animation/AnimationManager.ts b/packages/avatar/src/animation/AnimationManager.ts new file mode 100644 index 0000000..daa7e6b --- /dev/null +++ b/packages/avatar/src/animation/AnimationManager.ts @@ -0,0 +1,49 @@ +import { IAnimation, IAnimationLayerData, IAnimationManager, IAssetAnimation } from '@nitrots/api'; +import { AvatarStructure } from '../AvatarStructure'; +import { Animation } from './Animation'; + +export class AnimationManager implements IAnimationManager +{ + private _animations: Map; + + constructor() + { + this._animations = new Map(); + } + + public registerAnimation(structure: AvatarStructure, _arg_2: { [index: string]: IAssetAnimation }): boolean + { + if(!_arg_2) return false; + + const animationData = _arg_2[Object.keys(_arg_2)[0]]; + + const animation = new Animation(structure, animationData); + + this._animations.set(animationData.name, animation); + + return true; + } + + public getAnimation(animation: string): Animation + { + const existing = this._animations.get(animation); + + if(!existing) return null; + + return existing; + } + + public getLayerData(animation: string, frameCount: number, spriteId: string): IAnimationLayerData + { + const existing = this.getAnimation(animation); + + if(!existing) return null; + + return existing.getLayerData(frameCount, spriteId); + } + + public get animations(): Map + { + return this._animations; + } +} diff --git a/packages/avatar/src/animation/AvatarAnimationLayerData.ts b/packages/avatar/src/animation/AvatarAnimationLayerData.ts new file mode 100644 index 0000000..9e4714b --- /dev/null +++ b/packages/avatar/src/animation/AvatarAnimationLayerData.ts @@ -0,0 +1,109 @@ +import { IActionDefinition, IActiveActionData, IAnimationLayerData, IAssetAnimationFramePart } from '@nitrots/api'; +import { ActiveActionData } from '../actions'; + +export class AvatarAnimationLayerData 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.baseAsInt().toString(); + + if(_arg_3) + { + this._action = new ActiveActionData(_arg_3.state, this.base); + this._action.definition = _arg_3; + } + } + + public get items(): Map + { + return this._items; + } + + private baseAsInt(): 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 animationFrame(): 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/packages/avatar/src/animation/AvatarDataContainer.ts b/packages/avatar/src/animation/AvatarDataContainer.ts new file mode 100644 index 0000000..399cc68 --- /dev/null +++ b/packages/avatar/src/animation/AvatarDataContainer.ts @@ -0,0 +1,136 @@ +import { IAssetAnimationAvatar, IAvatarDataContainer } from '@nitrots/api'; +import { AdjustmentFilter } from 'pixi-filters'; + +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._colorTransform = new AdjustmentFilter({ red: (this._r / 255), green: (this._g / 255), blue: (this._b / 255), alpha: this._alphaMultiplier }); + this._colorMap = this.generatePaletteMapForGrayscale(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 paletteIsGrayscale(): boolean + { + return this._paletteIsGrayscale; + } + + private generatePaletteMapForGrayscale(background: number, foreground: number): Map + { + const alphaBackground = ((background >> 24) & 0xFF); + const redBackground = ((background >> 16) & 0xFF); + const greenBackground = ((background >> 8) & 0xFF); + const blueBackground = ((background >> 0) & 0xFF); + const alphaForeground = ((foreground >> 24) & 0xFF); + const redForeground = ((foreground >> 16) & 0xFF); + const greenForeground = ((foreground >> 8) & 0xFF); + const blueForeground = ((foreground >> 0) & 0xFF); + const alphaDifference = ((alphaForeground - alphaBackground) / 0xFF); + const redDifference = ((redForeground - redBackground) / 0xFF); + const greenDifference = ((greenForeground - greenBackground) / 0xFF); + const blueDifference = ((blueForeground - blueBackground) / 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 = alphaBackground; + let _local_21 = redBackground; + let _local_22 = greenBackground; + let _local_23 = blueBackground; + + for(let i = 0; i < 256; i++) + { + if((((_local_21 == redBackground) && (_local_22 == greenBackground)) && (_local_23 == blueBackground))) + { + _local_20 = 0; + } + _local_20 = (_local_20 + alphaDifference); + _local_21 = (_local_21 + redDifference); + _local_22 = (_local_22 + greenDifference); + _local_23 = (_local_23 + blueDifference); + _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_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/packages/avatar/src/animation/DirectionDataContainer.ts b/packages/avatar/src/animation/DirectionDataContainer.ts new file mode 100644 index 0000000..e90f453 --- /dev/null +++ b/packages/avatar/src/animation/DirectionDataContainer.ts @@ -0,0 +1,16 @@ +import { IAssetAnimationDirection } from '@nitrots/api'; + +export class DirectionDataContainer +{ + private _offset: number; + + constructor(k: IAssetAnimationDirection) + { + this._offset = k.offset; + } + + public get offset(): number + { + return this._offset; + } +} diff --git a/packages/avatar/src/animation/SpriteDataContainer.ts b/packages/avatar/src/animation/SpriteDataContainer.ts new file mode 100644 index 0000000..6755240 --- /dev/null +++ b/packages/avatar/src/animation/SpriteDataContainer.ts @@ -0,0 +1,94 @@ +import { IAnimation, IAssetAnimationSprite, ISpriteDataContainer } from '@nitrots/api'; + +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 getDirectionOffsetX(k: number): number + { + if(k < this._dx.length) return this._dx[k]; + + return 0; + } + + public getDirectionOffsetY(k: number): number + { + if(k < this._dy.length) return this._dy[k]; + + return 0; + } + + public getDirectionOffsetZ(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 hasDirections(): boolean + { + return this._hasDirections; + } + + public get hasStaticY(): boolean + { + return this._hasStaticY; + } +} diff --git a/packages/avatar/src/animation/index.ts b/packages/avatar/src/animation/index.ts new file mode 100644 index 0000000..f2e83c4 --- /dev/null +++ b/packages/avatar/src/animation/index.ts @@ -0,0 +1,7 @@ +export * from './AddDataContainer'; +export * from './Animation'; +export * from './AnimationManager'; +export * from './AvatarAnimationLayerData'; +export * from './AvatarDataContainer'; +export * from './DirectionDataContainer'; +export * from './SpriteDataContainer'; diff --git a/packages/avatar/src/cache/AvatarImageActionCache.ts b/packages/avatar/src/cache/AvatarImageActionCache.ts new file mode 100644 index 0000000..0b65729 --- /dev/null +++ b/packages/avatar/src/cache/AvatarImageActionCache.ts @@ -0,0 +1,57 @@ +import { GetTickerTime } from '@nitrots/utils'; +import { AvatarImageDirectionCache } from './AvatarImageDirectionCache'; + +export class AvatarImageActionCache +{ + private _cache: Map; + private _lastAccessTime: number; + + constructor() + { + this._cache = new Map(); + + this.setLastAccessTime(GetTickerTime()); + } + + public dispose(): void + { + this.debugInfo('[dispose]'); + + if(!this._cache) return; + + for(const direction of this._cache.values()) + { + if(direction) direction.dispose(); + } + + this._cache.clear(); + } + + public getDirectionCache(k: number): AvatarImageDirectionCache + { + const existing = this._cache.get(k.toString()); + + if(!existing) return null; + + return existing; + } + + public updateDirectionCache(k: number, _arg_2: AvatarImageDirectionCache): void + { + this._cache.set(k.toString(), _arg_2); + } + + public setLastAccessTime(k: number): void + { + this._lastAccessTime = k; + } + + public getLastAccessTime(): number + { + return this._lastAccessTime; + } + + private debugInfo(k: string): void + { + } +} diff --git a/packages/avatar/src/cache/AvatarImageBodyPartCache.ts b/packages/avatar/src/cache/AvatarImageBodyPartCache.ts new file mode 100644 index 0000000..cb7d5ce --- /dev/null +++ b/packages/avatar/src/cache/AvatarImageBodyPartCache.ts @@ -0,0 +1,96 @@ +import { IActiveActionData } from '@nitrots/api'; +import { AvatarImageActionCache } from './AvatarImageActionCache'; + +export class AvatarImageBodyPartCache +{ + private _cache: Map; + private _currentAction: IActiveActionData; + private _currentDirection: number; + private _disposed: boolean; + + constructor() + { + this._cache = new Map(); + } + + public setAction(k: IActiveActionData, _arg_2: number): void + { + if(!this._currentAction) this._currentAction = k; + + const _local_3 = this.getActionCache(this._currentAction); + + if(_local_3) _local_3.setLastAccessTime(_arg_2); + + this._currentAction = k; + } + + public dispose(): void + { + if(!this._disposed) + { + if(!this._cache) return; + + this.disposeActions(0, 2147483647); + + this._cache.clear(); + + this._cache = null; + this._disposed = true; + } + } + + public disposeActions(k: number, _arg_2: number): void + { + if(!this._cache || this._disposed) return; + + for(const [key, cache] of this._cache.entries()) + { + if(!cache) continue; + + const _local_3 = cache.getLastAccessTime(); + + if((_arg_2 - _local_3) >= k) + { + cache.dispose(); + + this._cache.delete(key); + } + } + } + + public getAction(): IActiveActionData + { + return this._currentAction; + } + + public setDirection(k: number): void + { + this._currentDirection = k; + } + + public getDirection(): number + { + return this._currentDirection; + } + + public getActionCache(k: IActiveActionData = null): AvatarImageActionCache + { + if(!this._currentAction) return null; + + if(!k) k = this._currentAction; + + if(k.overridingAction) return this._cache.get(k.overridingAction); + + return this._cache.get(k.id); + } + + public updateActionCache(k: IActiveActionData, _arg_2: AvatarImageActionCache): void + { + if(k.overridingAction) this._cache.set(k.overridingAction, _arg_2); + else this._cache.set(k.id, _arg_2); + } + + private debugInfo(k: string): void + { + } +} diff --git a/packages/avatar/src/cache/AvatarImageCache.ts b/packages/avatar/src/cache/AvatarImageCache.ts new file mode 100644 index 0000000..6c8381e --- /dev/null +++ b/packages/avatar/src/cache/AvatarImageCache.ts @@ -0,0 +1,444 @@ +import { AvatarDirectionAngle, AvatarFigurePartType, AvatarScaleType, GeometryType, IActiveActionData, IAvatarImage } from '@nitrots/api'; +import { GetTickerTime } from '@nitrots/utils'; +import { Container, Matrix, Point, Rectangle, Sprite, Texture } from 'pixi.js'; +import { AvatarImageBodyPartContainer } from '../AvatarImageBodyPartContainer'; +import { AvatarImagePartContainer } from '../AvatarImagePartContainer'; +import { AvatarStructure } from '../AvatarStructure'; +import { AssetAliasCollection } from '../alias'; +import { AvatarAnimationLayerData } from '../animation'; +import { AvatarCanvas } from '../structure'; +import { AvatarImageActionCache } from './AvatarImageActionCache'; +import { AvatarImageBodyPartCache } from './AvatarImageBodyPartCache'; +import { AvatarImageDirectionCache } from './AvatarImageDirectionCache'; +import { ImageData } from './ImageData'; + +export class AvatarImageCache +{ + private static DEFAULT_MAX_CACHE_STORAGE_TIME_MS: 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; + + 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(); + } + + 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 disposeInactiveActions(k: number = 60000): void + { + const time = GetTickerTime(); + + if(this._cache) + { + for(const cache of this._cache.values()) + { + if(!cache) continue; + + cache.disposeActions(k, time); + } + } + } + + public resetBodyPartCache(k: IActiveActionData): void + { + if(this._cache) + { + for(const cache of this._cache.values()) + { + if(!cache) continue; + + cache.setAction(k, 0); + } + } + } + + public setDirection(k: string, _arg_2: number): void + { + const parts = this._structure.getBodyPartsUnordered(k); + + if(parts) + { + for(const part of parts) + { + const actionCache = this.getBodyPartCache(part); + + if(!actionCache) continue; + + actionCache.setDirection(_arg_2); + } + } + } + + public setAction(k: IActiveActionData, _arg_2: number): void + { + const _local_3 = this._structure.getActiveBodyPartIds(k, this._avatar); + + for(const _local_4 of _local_3) + { + const _local_5 = this.getBodyPartCache(_local_4); + + if(_local_5) _local_5.setAction(k, _arg_2); + } + } + + public setGeometryType(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.disposeInactiveActions(0); + + this._geometryType = k; + this._canvas = null; + } + + public getImageContainer(key: string, frameNumber: number, forceRefresh: boolean = false): AvatarImageBodyPartContainer + { + const bodyPartCache = this.getBodyPartCache(key) || new AvatarImageBodyPartCache(); + + this._cache.set(key, bodyPartCache); + + let direction = bodyPartCache.getDirection(); + let action = bodyPartCache.getAction(); + let adjustedFrameCount = frameNumber; + + if(action.definition.startFromFrameZero) adjustedFrameCount -= action.startFrame; + + let adjustedAction = action; + let removeData: string[] = []; + let items: Map = new Map(); + + const positionOffset = new Point(); + + if(action.definition.isAnimation) + { + let adjustedDirection = direction; + + const animation = this._structure.getAnimation(((action.definition.state + '.') + action.actionParameter)); + const animationFrameOffset = (frameNumber - action.startFrame); + + if(animation) + { + const layerData = animation.getLayerData(animationFrameOffset, key, action.overridingAction); + + if(layerData) + { + adjustedDirection = (direction + layerData.dd + 8) % 8; + + positionOffset.x = this._scale === AvatarScaleType.LARGE ? layerData.dx : layerData.dx / 2; + positionOffset.y = this._scale === AvatarScaleType.LARGE ? layerData.dy : layerData.dy / 2; + + adjustedFrameCount = layerData.animationFrame; + + if(layerData.action) action = layerData.action; + + if(layerData.type === AvatarAnimationLayerData.BODYPART) + { + if(layerData.action) adjustedAction = layerData.action; + + direction = adjustedDirection; + } + else if(layerData.type === AvatarAnimationLayerData.FX) direction = adjustedDirection; + + items = layerData.items; + } + + removeData = animation.removeData; + } + } + + let actionCache = bodyPartCache.getActionCache(adjustedAction); + + if(!actionCache || forceRefresh) + { + actionCache = new AvatarImageActionCache(); + bodyPartCache.updateActionCache(adjustedAction, actionCache); + } + + let directionCache = actionCache.getDirectionCache(direction); + + if(!directionCache || forceRefresh) + { + const partList = this._structure.getParts(key, this._avatar.getFigure(), adjustedAction, this._geometryType, direction, removeData, this._avatar, items); + + directionCache = new AvatarImageDirectionCache(partList); + + actionCache.updateDirectionCache(direction, directionCache); + } + + let imageContainer = directionCache.getImageContainer(adjustedFrameCount); + + if(!imageContainer || forceRefresh) + { + const partList = directionCache.getPartList(); + + imageContainer = this.renderBodyPart(direction, partList, adjustedFrameCount, action); + + if(imageContainer && !forceRefresh) + { + if(imageContainer.isCacheable) directionCache.updateImageContainer(imageContainer, adjustedFrameCount); + } + else + { + return null; + } + } + + const offset = this._structure.getFrameBodyPartOffset(adjustedAction, direction, adjustedFrameCount, key); + + positionOffset.x += offset.x; + positionOffset.y += offset.y; + + imageContainer.offset = positionOffset; + + return imageContainer; + } + + public getBodyPartCache(k: string): AvatarImageBodyPartCache + { + let existing = this._cache.get(k); + + if(!existing) + { + existing = new AvatarImageBodyPartCache(); + + this._cache.set(k, existing); + } + + return existing; + } + + private renderBodyPart(direction: number, containers: AvatarImagePartContainer[], frameCount: number, action: IActiveActionData): AvatarImageBodyPartContainer + { + if(!containers || !containers.length) return null; + + if(!this._canvas) + { + this._canvas = this._structure.getCanvas(this._scale, this._geometryType); + + if(!this._canvas) return null; + } + + const isFlipped = AvatarDirectionAngle.DIRECTION_IS_FLIPPED[direction] || false; + let assetPartDefinition = action.definition.assetPartDefinition; + let isCacheable = true; + let containerIndex = (containers.length - 1); + + while(containerIndex >= 0) + { + const container = containers[containerIndex]; + + let color = 16777215; + + if(!((direction == 7) && ((container.partType === 'fc') || (container.partType === 'ey')))) + { + if(!((container.partType === 'ri') && !container.partId)) + { + const partId = container.partId; + const animationFrame = container.getFrameDefinition(frameCount); + + let partType = container.partType; + let frameNumber = 0; + + if(animationFrame) + { + frameNumber = animationFrame.number; + + if((animationFrame.assetPartDefinition) && (animationFrame.assetPartDefinition !== '')) assetPartDefinition = animationFrame.assetPartDefinition; + } + else frameNumber = container.getFrameIndex(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.flippedPartType !== partType) partType = container.flippedPartType; + } + } + + 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.source) + { + isCacheable = false; + } + else + { + if(container.isColorable && container.color) color = container.color.rgb; + + const offset = new Point(-(asset.x), -(asset.y)); + + if(flipH) offset.x = (offset.x + ((this._scale === AvatarScaleType.LARGE) ? 65 : 31)); + + this._unionImages.push(new ImageData(texture, asset.rectangle, offset, flipH, color)); + } + } + } + } + + containerIndex--; + } + + if(!this._unionImages.length) return null; + + const imageData = this.createUnionImage(this._unionImages, isFlipped); + const canvasOffset = ((this._scale === AvatarScaleType.LARGE) ? (this._canvas.height - 16) : (this._canvas.height - 8)); + const offset = new Point(-(imageData.regPoint.x), (canvasOffset - imageData.regPoint.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 convertColorToHex(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 createUnionImage(k: ImageData[], isFlipped: boolean): ImageData + { + const bounds = new Rectangle(); + + for(const data of k) data && bounds.enlarge(data.offsetRect); + + 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 regPoint = point.clone(); + + regPoint.x -= data.regPoint.x; + regPoint.y -= data.regPoint.y; + + if(isFlipped) regPoint.x = (container.width - (regPoint.x + data.rect.width)); + + if(isFlipped != data.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(data.texture); + + sprite.tint = data.colorTransform; + sprite.setFromMatrix(this._matrix); + + container.addChild(sprite); + } + + return new ImageData(null, container.getLocalBounds().rectangle, point, isFlipped, null, container); + } +} diff --git a/packages/avatar/src/cache/AvatarImageDirectionCache.ts b/packages/avatar/src/cache/AvatarImageDirectionCache.ts new file mode 100644 index 0000000..da3a75e --- /dev/null +++ b/packages/avatar/src/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 getPartList(): AvatarImagePartContainer[] + { + return this._partList; + } + + public getImageContainer(k: number): AvatarImageBodyPartContainer + { + const existing = this._images.get(this.getCacheKey(k)); + + if(!existing) return null; + + return existing; + } + + public updateImageContainer(k: AvatarImageBodyPartContainer, _arg_2: number): void + { + const name = this.getCacheKey(_arg_2); + + const existing = this._images.get(name); + + if(existing) existing.dispose(); + + this._images.set(name, k); + } + + private getCacheKey(k: number): string + { + let name = ''; + + for(const part of this._partList) name += (part.getCacheableKey(k) + '/'); + + return name; + } + + private debugInfo(k: string): void + { + } +} diff --git a/packages/avatar/src/cache/ImageData.ts b/packages/avatar/src/cache/ImageData.ts new file mode 100644 index 0000000..c43c2c2 --- /dev/null +++ b/packages/avatar/src/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 _colorTransform: 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._colorTransform = color; + + if(flipH) this._regPoint.x = (-(this._regPoint.x) + rectangle.width); + } + + public dispose(): void + { + this._texture = null; + this._regPoint = null; + this._colorTransform = null; + } + + public get texture(): Texture + { + return this._texture; + } + + public get container(): Container + { + return this._container; + } + + public get rect(): Rectangle + { + return this._rect; + } + + public get regPoint(): Point + { + return this._regPoint; + } + + public get flipH(): boolean + { + return this._flipH; + } + + public get colorTransform(): number + { + return this._colorTransform; + } + + public get offsetRect(): Rectangle + { + return new Rectangle(-(this._regPoint.x), -(this._regPoint.y), this._rect.width, this._rect.height); + } +} diff --git a/packages/avatar/src/cache/index.ts b/packages/avatar/src/cache/index.ts new file mode 100644 index 0000000..d8d2e53 --- /dev/null +++ b/packages/avatar/src/cache/index.ts @@ -0,0 +1,5 @@ +export * from './AvatarImageActionCache'; +export * from './AvatarImageBodyPartCache'; +export * from './AvatarImageCache'; +export * from './AvatarImageDirectionCache'; +export * from './ImageData'; diff --git a/packages/avatar/src/data/HabboAvatarAnimations.ts b/packages/avatar/src/data/HabboAvatarAnimations.ts new file mode 100644 index 0000000..f1fc2cc --- /dev/null +++ b/packages/avatar/src/data/HabboAvatarAnimations.ts @@ -0,0 +1,827 @@ +export const HabboAvatarAnimations = { + '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 + } + ] + } + ] + } + ] + } + } + ] +}; diff --git a/packages/avatar/src/data/HabboAvatarGeometry.ts b/packages/avatar/src/data/HabboAvatarGeometry.ts new file mode 100644 index 0000000..e6b9db0 --- /dev/null +++ b/packages/avatar/src/data/HabboAvatarGeometry.ts @@ -0,0 +1,1830 @@ +export const HabboAvatarGeometry = { + '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 + } + ] + } + ] + } + ] + } +}; diff --git a/packages/avatar/src/data/HabboAvatarPartSets.ts b/packages/avatar/src/data/HabboAvatarPartSets.ts new file mode 100644 index 0000000..1bd4750 --- /dev/null +++ b/packages/avatar/src/data/HabboAvatarPartSets.ts @@ -0,0 +1,418 @@ +export const HabboAvatarPartSets = { + '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' + } + ] + } + ] + } +}; diff --git a/packages/avatar/src/geometry/AvatarModelGeometry.ts b/packages/avatar/src/geometry/AvatarModelGeometry.ts new file mode 100644 index 0000000..821e7f7 --- /dev/null +++ b/packages/avatar/src/geometry/AvatarModelGeometry.ts @@ -0,0 +1,287 @@ +import { IAvatarImage } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { Matrix4x4 } from '@nitrots/utils/src/Matrix4x4'; +import { AvatarCanvas } from '../structure'; +import { AvatarSet } from './AvatarSet'; +import { GeometryBodyPart } from './GeometryBodyPart'; + +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.getPartIds(null)) + { + itemIds.set(part, geometryBodyPart); + } + } + } + + this._geometryTypes.set(type.id, bodyParts); + this._itemIdToBodyPartMap.set(type.id, itemIds); + } + } + } + + public removeDynamicItems(k: IAvatarImage): void + { + for(const geometry of this._geometryTypes.values()) + { + if(!geometry) continue; + + for(const part of geometry.values()) + { + if(!part) continue; + + part.removeDynamicParts(k); + } + } + } + + public getBodyPartIdsInAvatarSet(k: string): string[] + { + const avatarSet = this._avatarSet.findAvatarSet(k); + + if(!avatarSet) return []; + + return avatarSet.getBodyParts(); + } + + public isMainAvatarSet(k: string): boolean + { + const avatarSet = this._avatarSet.findAvatarSet(k); + + if(!avatarSet) return false; + + return avatarSet.isMain; + } + + public getCanvas(k: string, _arg_2: string): AvatarCanvas + { + const canvas = this._canvases.get(k); + + if(!canvas) return null; + + return (canvas.get(_arg_2) || null); + } + + private typeExists(k: string): boolean + { + const existing = this._geometryTypes.get(k); + + if(existing) return true; + + return false; + } + + private hasBodyPart(k: string, _arg_2: string): boolean + { + if(this.typeExists(k)) + { + const existing = this._geometryTypes.get(k); + + if(existing && existing.get(_arg_2)) return true; + } + + return false; + } + + private getBodyPartIDs(k: string): string[] + { + const parts = this.getBodyPartsOfType(k); + + const types = []; + + if(parts) + { + for(const part of parts.values()) + { + if(!part) continue; + + types.push(part.id); + } + } + + return types; + } + + private getBodyPartsOfType(k: string): Map + { + if(this.typeExists(k)) return this._geometryTypes.get(k); + + return new Map(); + } + + public getBodyPart(k: string, _arg_2: string): GeometryBodyPart + { + return (this.getBodyPartsOfType(k).get(_arg_2) || null); + } + + public getBodyPartOfItem(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.getBodyPartsOfType(k); + + if(parts) + { + for(const part of parts.values()) + { + if(!part) continue; + + if(part.hasPart(_arg_2, _arg_3)) return part; + } + } + } + + return null; + } + + private getBodyPartsInAvatarSet(k: Map, _arg_2: string): GeometryBodyPart[] + { + const parts = this.getBodyPartIdsInAvatarSet(_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 getBodyPartsAtAngle(k: string, _arg_2: number, _arg_3: string): string[] + { + if(!_arg_3) return []; + + const geometryParts = this.getBodyPartsOfType(_arg_3); + const parts = this.getBodyPartsInAvatarSet(geometryParts, k); + const sets: [number, GeometryBodyPart][] = []; + const ids: string[] = []; + + this._transformation = Matrix4x4.getYRotationMatrix(_arg_2); + + for(const part of parts.values()) + { + if(!part) continue; + + part.applyTransform(this._transformation); + + sets.push([part.getDistance(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 getParts(k: string, _arg_2: string, _arg_3: number, _arg_4: any[], _arg_5: IAvatarImage): string[] + { + if(this.hasBodyPart(k, _arg_2)) + { + const part = this.getBodyPartsOfType(k).get(_arg_2); + + this._transformation = Matrix4x4.getYRotationMatrix(_arg_3); + + return part.getParts(this._transformation, this._camera, _arg_4, _arg_5); + } + + return []; + } +} diff --git a/packages/avatar/src/geometry/AvatarSet.ts b/packages/avatar/src/geometry/AvatarSet.ts new file mode 100644 index 0000000..2dee804 --- /dev/null +++ b/packages/avatar/src/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.getBodyParts()); + } + + this._allBodyParts = bodyParts; + } + + public findAvatarSet(k: string): AvatarSet + { + if(k === this._id) return this; + + for(const avatarSet of this._avatarSets.values()) + { + if(!avatarSet) continue; + + if(!avatarSet.findAvatarSet(k)) continue; + + return avatarSet; + } + + return null; + } + + public getBodyParts(): string[] + { + return this._allBodyParts.concat(); + } + + public get id(): string + { + return this._id; + } + + public get isMain(): boolean + { + if(this._isMain) return true; + + for(const avatarSet of this._avatarSets.values()) + { + if(!avatarSet) continue; + + if(!avatarSet.isMain) continue; + + return true; + } + + return false; + } +} diff --git a/packages/avatar/src/geometry/GeometryBodyPart.ts b/packages/avatar/src/geometry/GeometryBodyPart.ts new file mode 100644 index 0000000..4d61c93 --- /dev/null +++ b/packages/avatar/src/geometry/GeometryBodyPart.ts @@ -0,0 +1,192 @@ +import { IAvatarImage } from '@nitrots/api'; +import { Matrix4x4, Node3D, Vector3d } from '@nitrots/utils'; +import { GeometryItem } from './GeometryItem'; + +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 getDynamicParts(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 getPartIds(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 removeDynamicParts(k: IAvatarImage): boolean + { + this._dynamicParts.delete(k); + + return true; + } + + public addPart(k: any, _arg_2: IAvatarImage): boolean + { + if(this.hasPart(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 hasPart(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 getParts(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.applyTransform(k); + + parts.push([part.getDistance(_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.applyTransform(k); + + parts.push([part.getDistance(_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 getDistance(k: Vector3d): number + { + const _local_2 = Math.abs(((k.z - this.transformedLocation.z) - this._radius)); + const _local_3 = Math.abs(((k.z - this.transformedLocation.z) + this._radius)); + + return Math.min(_local_2, _local_3); + } + + public get id(): string + { + return this._id; + } + + public get radius(): number + { + return this._radius; + } +} diff --git a/packages/avatar/src/geometry/GeometryItem.ts b/packages/avatar/src/geometry/GeometryItem.ts new file mode 100644 index 0000000..3aea172 --- /dev/null +++ b/packages/avatar/src/geometry/GeometryItem.ts @@ -0,0 +1,54 @@ +import { Node3D, Vector3d } from '@nitrots/utils'; + +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 getDistance(k: Vector3d): number + { + const _local_2 = Math.abs(((k.z - this.transformedLocation.z) - this._radius)); + const _local_3 = Math.abs(((k.z - this.transformedLocation.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 isDoubleSided(): boolean + { + return this._isDoubleSided; + } + + public toString(): string + { + return ((((this._id + ': ') + this.location) + ' - ') + this.transformedLocation); + } + + public get isDynamic(): boolean + { + return this._isDynamic; + } +} diff --git a/packages/avatar/src/geometry/index.ts b/packages/avatar/src/geometry/index.ts new file mode 100644 index 0000000..0eb1361 --- /dev/null +++ b/packages/avatar/src/geometry/index.ts @@ -0,0 +1,4 @@ +export * from './AvatarModelGeometry'; +export * from './AvatarSet'; +export * from './GeometryBodyPart'; +export * from './GeometryItem'; diff --git a/packages/avatar/src/index.ts b/packages/avatar/src/index.ts new file mode 100644 index 0000000..8a429ea --- /dev/null +++ b/packages/avatar/src/index.ts @@ -0,0 +1,25 @@ +export * from './AvatarAssetDownloadLibrary'; +export * from './AvatarAssetDownloadManager'; +export * from './AvatarFigureContainer'; +export * from './AvatarImage'; +export * from './AvatarImageBodyPartContainer'; +export * from './AvatarImagePartContainer'; +export * from './AvatarRenderManager'; +export * from './AvatarStructure'; +export * from './EffectAssetDownloadLibrary'; +export * from './EffectAssetDownloadManager'; +export * from './FigureDataContainer'; +export * from './GetAvatarRenderManager'; +export * from './PlaceHolderAvatarImage'; +export * from './actions'; +export * from './alias'; +export * from './animation'; +export * from './cache'; +export * from './data/HabboAvatarAnimations'; +export * from './data/HabboAvatarGeometry'; +export * from './data/HabboAvatarPartSets'; +export * from './geometry'; +export * from './structure'; +export * from './structure/animation'; +export * from './structure/figure'; +export * from './structure/parts'; diff --git a/packages/avatar/src/structure/AvatarAnimationData.ts b/packages/avatar/src/structure/AvatarAnimationData.ts new file mode 100644 index 0000000..fd78ccc --- /dev/null +++ b/packages/avatar/src/structure/AvatarAnimationData.ts @@ -0,0 +1,57 @@ +import { IActionDefinition, IFigureSetData } from '@nitrots/api'; +import { AnimationAction } from './animation'; + +export class AvatarAnimationData 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 appendJSON(k: any): boolean + { + for(const _local_2 of k.action) + { + this._actions.set(_local_2.id, new AnimationAction(_local_2)); + } + + return true; + } + + public getAction(action: IActionDefinition): AnimationAction + { + const existing = this._actions.get(action.id); + + if(!existing) return null; + + return existing; + } + + public getFrameCount(k: IActionDefinition): number + { + const animationAction = this.getAction(k); + + if(!animationAction) return 0; + + return animationAction.frameCount; + } +} diff --git a/packages/avatar/src/structure/AvatarCanvas.ts b/packages/avatar/src/structure/AvatarCanvas.ts new file mode 100644 index 0000000..69a01a6 --- /dev/null +++ b/packages/avatar/src/structure/AvatarCanvas.ts @@ -0,0 +1,47 @@ +import { AvatarScaleType } from '@nitrots/api'; +import { Point } from 'pixi.js'; + +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 regPoint(): Point + { + return this._regPoint; + } +} diff --git a/packages/avatar/src/structure/FigureSetData.ts b/packages/avatar/src/structure/FigureSetData.ts new file mode 100644 index 0000000..ff7d218 --- /dev/null +++ b/packages/avatar/src/structure/FigureSetData.ts @@ -0,0 +1,129 @@ +import { IFigureData, IFigurePartSet, IFigureSetData, IPalette, ISetType, IStructureData } from '@nitrots/api'; +import { Palette, SetType } from './figure'; + +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: IFigureData): boolean + { + if(!data) return false; + + for(const palette of data.palettes) + { + const newPalette = new Palette(palette); + + if(!newPalette) continue; + + this._palettes.set(newPalette.id.toString(), newPalette); + } + + for(const set of data.setTypes) + { + const newSet = new SetType(set); + + if(!newSet) continue; + + this._setTypes.set(newSet.type, newSet); + } + + return true; + } + + public injectJSON(data: IFigureData): void + { + for(const setType of data.setTypes) + { + const existingSetType = this._setTypes.get(setType.type); + + if(existingSetType) existingSetType.cleanUp(setType); + else this._setTypes.set(setType.type, new SetType(setType)); + } + + this.appendJSON(data); + } + + public appendJSON(data: IFigureData): boolean + { + if(!data) return false; + + for(const palette of data.palettes) + { + const id = palette.id.toString(); + const existingPalette = this._palettes.get(id); + + if(!existingPalette) this._palettes.set(id, new Palette(palette)); + else existingPalette.append(palette); + } + + for(const setType of data.setTypes) + { + const type = setType.type; + const existingSetType = this._setTypes.get(type); + + if(!existingSetType) this._setTypes.set(type, new SetType(setType)); + else existingSetType.append(setType); + } + + return false; + } + + public getMandatorySetTypeIds(k: string, _arg_2: number): string[] + { + const types: string[] = []; + + for(const set of this._setTypes.values()) + { + if(!set || !set.isMandatory(k, _arg_2)) continue; + + types.push(set.type); + } + + return types; + } + + public getDefaultPartSet(type: string, gender: string): IFigurePartSet + { + const setType = this._setTypes.get(type); + + if(!setType) return null; + + return setType.getDefaultPartSet(gender); + } + + public getSetType(k: string): ISetType + { + return (this._setTypes.get(k) || null); + } + + public getPalette(k: number): IPalette + { + return (this._palettes.get(k.toString()) || null); + } + + public getFigurePartSet(k: number): IFigurePartSet + { + for(const set of this._setTypes.values()) + { + const partSet = set.getPartSet(k); + + if(!partSet) continue; + + return partSet; + } + + return null; + } +} diff --git a/packages/avatar/src/structure/PartSetsData.ts b/packages/avatar/src/structure/PartSetsData.ts new file mode 100644 index 0000000..6e80742 --- /dev/null +++ b/packages/avatar/src/structure/PartSetsData.ts @@ -0,0 +1,118 @@ +import { IActionDefinition, IFigureSetData } from '@nitrots/api'; +import { ActionDefinition } from '../actions'; +import { ActivePartSet, PartDefinition } from './parts'; + +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 appendJSON(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 getActiveParts(k: IActionDefinition): string[] + { + const activePartSet = this._activePartSets.get(k.activePartSet); + + if(!activePartSet) return []; + + return activePartSet.parts; + } + + public getPartDefinition(part: string): PartDefinition + { + const existing = this._parts.get(part); + + if(!existing) return null; + + return existing; + } + + public addPartDefinition(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 getActivePartSet(k: ActionDefinition): ActivePartSet + { + const existing = this._activePartSets.get(k.activePartSet); + + if(!existing) return null; + + return existing; + } + + public get parts(): Map + { + return this._parts; + } + + public get activePartSets(): Map + { + return this._activePartSets; + } +} diff --git a/packages/avatar/src/structure/animation/AnimationAction.ts b/packages/avatar/src/structure/animation/AnimationAction.ts new file mode 100644 index 0000000..9e38ac1 --- /dev/null +++ b/packages/avatar/src/structure/animation/AnimationAction.ts @@ -0,0 +1,138 @@ +import { Point } from 'pixi.js'; +import { AnimationActionPart } from './AnimationActionPart'; + +export class AnimationAction +{ + public static DEFAULT_OFFSET: 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 getPart(type: string): AnimationActionPart + { + if(!type) return null; + + const existing = this._actionParts.get(type); + + if(!existing) return null; + + return existing; + } + + public getFrameBodyPartOffset(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.DEFAULT_OFFSET; + + const frameOffset = offsets.get(frameId); + + if(!frameOffset) return AnimationAction.DEFAULT_OFFSET; + + const offset = frameOffset.get(partId); + + if(!offset) return AnimationAction.DEFAULT_OFFSET; + + return offset; + } + + public get id(): string + { + return this._id; + } + + public get parts(): Map + { + return this._actionParts; + } + + public get frameCount(): number + { + return this._frameCount; + } +} diff --git a/packages/avatar/src/structure/animation/AnimationActionPart.ts b/packages/avatar/src/structure/animation/AnimationActionPart.ts new file mode 100644 index 0000000..ea16687 --- /dev/null +++ b/packages/avatar/src/structure/animation/AnimationActionPart.ts @@ -0,0 +1,30 @@ +import { AvatarAnimationFrame } from './AvatarAnimationFrame'; + +export class AnimationActionPart +{ + private _frames: AvatarAnimationFrame[]; + + 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 AvatarAnimationFrame(frame)); + + let repeats = frame.repeats || 0; + + if(repeats > 1) while(--repeats > 0) this._frames.push(this._frames[(this._frames.length - 1)]); + } + } + } + + public get frames(): AvatarAnimationFrame[] + { + return this._frames; + } +} diff --git a/packages/avatar/src/structure/animation/AvatarAnimationFrame.ts b/packages/avatar/src/structure/animation/AvatarAnimationFrame.ts new file mode 100644 index 0000000..3b9ec35 --- /dev/null +++ b/packages/avatar/src/structure/animation/AvatarAnimationFrame.ts @@ -0,0 +1,21 @@ +export class AvatarAnimationFrame +{ + 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 assetPartDefinition(): string + { + return this._assetPartDefinition; + } +} diff --git a/packages/avatar/src/structure/animation/index.ts b/packages/avatar/src/structure/animation/index.ts new file mode 100644 index 0000000..98af842 --- /dev/null +++ b/packages/avatar/src/structure/animation/index.ts @@ -0,0 +1,3 @@ +export * from './AnimationAction'; +export * from './AnimationActionPart'; +export * from './AvatarAnimationFrame'; diff --git a/packages/avatar/src/structure/figure/FigurePart.ts b/packages/avatar/src/structure/figure/FigurePart.ts new file mode 100644 index 0000000..09c0a1c --- /dev/null +++ b/packages/avatar/src/structure/figure/FigurePart.ts @@ -0,0 +1,53 @@ +import { IFigureDataPart, IFigurePart } from '@nitrots/api'; + +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: IFigureDataPart) + { + if(!data) throw new Error('invalid_data'); + + this._id = data.id; + this._type = data.type; + this._index = data.index; + this._colorLayerIndex = data.colorindex; + this._paletteMapId = -1; + this._breed = -1; + } + + 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 colorLayerIndex(): number + { + return this._colorLayerIndex; + } + + public get paletteMap(): number + { + return this._paletteMapId; + } +} diff --git a/packages/avatar/src/structure/figure/FigurePartSet.ts b/packages/avatar/src/structure/figure/FigurePartSet.ts new file mode 100644 index 0000000..5cb2f79 --- /dev/null +++ b/packages/avatar/src/structure/figure/FigurePartSet.ts @@ -0,0 +1,134 @@ +import { IFigureDataSet, IFigurePart, IFigurePartSet } from '@nitrots/api'; +import { FigurePart } from './FigurePart'; + +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: IFigureDataSet) + { + if(!type || !data) throw new Error('invalid_data'); + + this._id = data.id; + this._type = type; + this._gender = data.gender; + this._clubLevel = data.club; + this._isColorable = data.colorable; + this._isSelectable = data.selectable; + this._parts = []; + this._hiddenLayers = []; + this._isPreSelectable = data.preselectable; + this._isSellable = data.sellable; + + for(const part of data.parts) + { + 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) + { + for(const hiddenLayer of data.hiddenLayers) this._hiddenLayers.push(hiddenLayer.partType); + } + } + + public dispose(): void + { + 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 getPart(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 isSelectable(): boolean + { + return this._isSelectable; + } + + public get parts(): IFigurePart[] + { + return this._parts; + } + + public get hiddenLayers(): string[] + { + return this._hiddenLayers; + } + + public get isPreSelectable(): boolean + { + return this._isPreSelectable; + } + + public get isSellable(): boolean + { + return this._isSellable; + } +} diff --git a/packages/avatar/src/structure/figure/Palette.ts b/packages/avatar/src/structure/figure/Palette.ts new file mode 100644 index 0000000..33fed5e --- /dev/null +++ b/packages/avatar/src/structure/figure/Palette.ts @@ -0,0 +1,46 @@ +import { IAdvancedMap, IFigureDataPalette, IPalette, IPartColor } from '@nitrots/api'; +import { AdvancedMap } from '@nitrots/utils'; +import { PartColor } from './PartColor'; + +export class Palette implements IPalette +{ + private _id: number; + private _colors: IAdvancedMap; + + constructor(data: IFigureDataPalette) + { + if(!data) throw new Error('invalid_data'); + + this._id = data.id; + this._colors = new AdvancedMap(); + + this.append(data); + } + + public append(data: IFigureDataPalette): void + { + for(const color of data.colors) + { + const newColor = new PartColor(color); + + this._colors.add(color.id.toString(), newColor); + } + } + + public getColor(id: number): IPartColor + { + if((id === undefined) || id < 0) return null; + + return (this._colors.getValue(id.toString()) || null); + } + + public get id(): number + { + return this._id; + } + + public get colors(): IAdvancedMap + { + return this._colors; + } +} diff --git a/packages/avatar/src/structure/figure/PartColor.ts b/packages/avatar/src/structure/figure/PartColor.ts new file mode 100644 index 0000000..af96476 --- /dev/null +++ b/packages/avatar/src/structure/figure/PartColor.ts @@ -0,0 +1,46 @@ +import { IFigureDataColor, IPartColor } from '@nitrots/api'; + +export class PartColor implements IPartColor +{ + private _id: number; + private _index: number; + private _clubLevel: number; + private _isSelectable: boolean; + private _rgb: number; + + constructor(data: IFigureDataColor) + { + if(!data) throw new Error('invalid_data'); + + this._id = data.id; + this._index = data.index; + this._clubLevel = (data.club || 0); + this._isSelectable = data.selectable; + this._rgb = parseInt('0x' + data.hexCode, 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 rgb(): number + { + return this._rgb; + } +} diff --git a/packages/avatar/src/structure/figure/SetType.ts b/packages/avatar/src/structure/figure/SetType.ts new file mode 100644 index 0000000..e24dfad --- /dev/null +++ b/packages/avatar/src/structure/figure/SetType.ts @@ -0,0 +1,104 @@ +import { IAdvancedMap, IFigureDataSetType, IFigurePartSet, ISetType } from '@nitrots/api'; +import { AdvancedMap } from '@nitrots/utils'; +import { FigurePartSet } from './FigurePartSet'; + +export class SetType implements ISetType +{ + private _type: string; + private _paletteId: number; + private _isMandatory: { [index: string]: boolean[] }; + private _partSets: IAdvancedMap; + + constructor(data: IFigureDataSetType) + { + if(!data) throw new Error('invalid_data'); + + this._type = data.type; + this._paletteId = data.paletteId; + this._isMandatory = {}; + this._isMandatory['F'] = [data.mandatory_f_0, data.mandatory_f_1]; + this._isMandatory['M'] = [data.mandatory_m_0, data.mandatory_m_1]; + this._partSets = new AdvancedMap(); + + this.append(data); + } + + public dispose(): void + { + for(const set of this._partSets.getValues()) + { + const partSet = set as FigurePartSet; + + partSet.dispose(); + } + + this._partSets = null; + } + + public cleanUp(data: IFigureDataSetType): void + { + for(const set of data.sets) + { + const setId = set.id.toString(); + const partSet = (this._partSets.getValue(setId) as FigurePartSet); + + if(partSet) + { + partSet.dispose(); + + this._partSets.remove(setId); + } + } + } + + public append(setType: IFigureDataSetType): void + { + if(!setType || !setType.sets) return; + + for(const set of setType.sets) this._partSets.add(set.id.toString(), new FigurePartSet(this._type, set)); + } + + public getDefaultPartSet(gender: string): IFigurePartSet + { + for(const set of this._partSets.getValues()) + { + if(!set) continue; + + if((set.clubLevel === 0) && ((set.gender === gender) || (set.gender === 'U'))) return set; + } + + return null; + } + + public getPartSet(k: number): IFigurePartSet + { + return this._partSets.getValue(k.toString()); + } + + public get type(): string + { + return this._type; + } + + public get paletteID(): number + { + return this._paletteId; + } + + public isMandatory(k: string, _arg_2: number): boolean + { + return this._isMandatory[k.toUpperCase()][Math.min(_arg_2, 1)]; + } + + public optionalFromClubLevel(k: string): number + { + const _local_2 = this._isMandatory[k.toUpperCase()]; + + return _local_2.indexOf(false); + } + + public get partSets(): IAdvancedMap + { + return this._partSets; + } +} diff --git a/packages/avatar/src/structure/figure/index.ts b/packages/avatar/src/structure/figure/index.ts new file mode 100644 index 0000000..1b9ebc3 --- /dev/null +++ b/packages/avatar/src/structure/figure/index.ts @@ -0,0 +1,5 @@ +export * from './FigurePart'; +export * from './FigurePartSet'; +export * from './Palette'; +export * from './PartColor'; +export * from './SetType'; diff --git a/packages/avatar/src/structure/index.ts b/packages/avatar/src/structure/index.ts new file mode 100644 index 0000000..9d2754f --- /dev/null +++ b/packages/avatar/src/structure/index.ts @@ -0,0 +1,7 @@ +export * from './AvatarAnimationData'; +export * from './AvatarCanvas'; +export * from './FigureSetData'; +export * from './PartSetsData'; +export * from './animation'; +export * from './figure'; +export * from './parts'; diff --git a/packages/avatar/src/structure/parts/ActivePartSet.ts b/packages/avatar/src/structure/parts/ActivePartSet.ts new file mode 100644 index 0000000..4244308 --- /dev/null +++ b/packages/avatar/src/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 parts(): string[] + { + return this._parts; + } +} diff --git a/packages/avatar/src/structure/parts/PartDefinition.ts b/packages/avatar/src/structure/parts/PartDefinition.ts new file mode 100644 index 0000000..19caa8c --- /dev/null +++ b/packages/avatar/src/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 hasStaticId(): boolean + { + return this._staticId >= 0; + } + + public get staticId(): number + { + return this._staticId; + } + + public set staticId(k: number) + { + this._staticId = k; + } + + public get setType(): string + { + return this._setType; + } + + public get flippedSetType(): string + { + return this._flippedSetType; + } + + public set flippedSetType(type: string) + { + this._flippedSetType = type; + } + + public get removeSetType(): string + { + return this._removeSetType; + } + + public get appendToFigure(): boolean + { + return this._appendToFigure; + } + + public set appendToFigure(flag: boolean) + { + this._appendToFigure = flag; + } +} diff --git a/packages/avatar/src/structure/parts/index.ts b/packages/avatar/src/structure/parts/index.ts new file mode 100644 index 0000000..31faf62 --- /dev/null +++ b/packages/avatar/src/structure/parts/index.ts @@ -0,0 +1,2 @@ +export * from './ActivePartSet'; +export * from './PartDefinition'; diff --git a/packages/avatar/tsconfig.json b/packages/avatar/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/avatar/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/camera/.eslintrc.json b/packages/camera/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/camera/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/camera/.gitignore b/packages/camera/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/camera/.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/packages/camera/index.ts b/packages/camera/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/camera/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/camera/package.json b/packages/camera/package.json new file mode 100644 index 0000000..1172279 --- /dev/null +++ b/packages/camera/package.json @@ -0,0 +1,23 @@ +{ + "name": "@nitrots/camera", + "description": "Nitro camera module", + "version": "1.0.0", + "type": "module", + "license": "GPL-3.0", + "scripts": { + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/configuration": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "@nitrots/events": "1.0.0", + "@nitrots/utils": "1.0.0", + "pixi.js": "^8.0.4" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/camera/src/GetRoomCameraWidgetManager.ts b/packages/camera/src/GetRoomCameraWidgetManager.ts new file mode 100644 index 0000000..0f6f44f --- /dev/null +++ b/packages/camera/src/GetRoomCameraWidgetManager.ts @@ -0,0 +1,5 @@ +import { RoomCameraWidgetManager } from './RoomCameraWidgetManager'; + +const roomCameraWidgetManager = new RoomCameraWidgetManager(); + +export const GetRoomCameraWidgetManager = () => roomCameraWidgetManager; diff --git a/packages/camera/src/RoomCameraWidgetEffect.ts b/packages/camera/src/RoomCameraWidgetEffect.ts new file mode 100644 index 0000000..f33e61b --- /dev/null +++ b/packages/camera/src/RoomCameraWidgetEffect.ts @@ -0,0 +1,60 @@ +import { IRoomCameraWidgetEffect } from '@nitrots/api'; +import { BLEND_MODES, ColorMatrix, Texture } from 'pixi.js'; + +export class RoomCameraWidgetEffect implements IRoomCameraWidgetEffect +{ + private _name: string; + private _minLevel: number = -1; + private _texture: Texture = null; + private _colorMatrix: ColorMatrix = null; + private _blendMode: BLEND_MODES = null; + + constructor(name: string, minLevel: number = -1, texture: Texture = null, colorMatrix: ColorMatrix = null, blendMode: BLEND_MODES = null) + { + this._name = name; + this._minLevel = minLevel; + this._texture = texture; + this._colorMatrix = colorMatrix; + this._blendMode = blendMode; + } + + public get name(): string + { + return this._name; + } + + public get texture(): Texture + { + return this._texture; + } + + public set texture(texture: Texture) + { + this._texture = texture; + } + + public get colorMatrix(): ColorMatrix + { + return this._colorMatrix; + } + + public set colorMatrix(colorMatrix: ColorMatrix) + { + this._colorMatrix = colorMatrix; + } + + public get blendMode(): BLEND_MODES + { + return this._blendMode; + } + + public set blendMode(blendMode: BLEND_MODES) + { + this._blendMode = blendMode; + } + + public get minLevel(): number + { + return this._minLevel; + } +} diff --git a/packages/camera/src/RoomCameraWidgetManager.ts b/packages/camera/src/RoomCameraWidgetManager.ts new file mode 100644 index 0000000..34ed50e --- /dev/null +++ b/packages/camera/src/RoomCameraWidgetManager.ts @@ -0,0 +1,103 @@ +import { IRoomCameraWidgetEffect, IRoomCameraWidgetManager, IRoomCameraWidgetSelectedEffect } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { GetConfiguration } from '@nitrots/configuration'; +import { GetEventDispatcher, RoomCameraWidgetManagerEvent } from '@nitrots/events'; +import { TextureUtils } from '@nitrots/utils'; +import { BLEND_MODES, ColorMatrix, ColorMatrixFilter, Container, Sprite, Texture } from 'pixi.js'; +import { RoomCameraWidgetEffect } from './RoomCameraWidgetEffect'; + +export class RoomCameraWidgetManager implements IRoomCameraWidgetManager +{ + private _effects: Map; + private _isLoaded: boolean; + + constructor() + { + this._effects = new Map(); + this._isLoaded = false; + } + + public async init(): Promise + { + if(this._isLoaded) return; + + this._isLoaded = true; + + const imagesUrl = GetConfiguration().getValue('image.library.url') + 'Habbo-Stories/'; + const effects = GetConfiguration().getValue<{ name: string, colorMatrix?: ColorMatrix, minLevel: number, blendMode?: BLEND_MODES, enabled: boolean }[]>('camera.available.effects'); + + for(const effect of effects) + { + if(!effect.enabled) continue; + + const cameraEffect = new RoomCameraWidgetEffect(effect.name, effect.minLevel); + + if(effect.colorMatrix.length) + { + cameraEffect.colorMatrix = effect.colorMatrix; + } + else + { + const url = `${ imagesUrl }${ effect.name }.png`; + + await GetAssetManager().downloadAsset(url); + + cameraEffect.texture = GetAssetManager().getTexture(url); + cameraEffect.blendMode = effect.blendMode; + } + + this._effects.set(cameraEffect.name, cameraEffect); + } + + GetEventDispatcher().dispatchEvent(new RoomCameraWidgetManagerEvent(RoomCameraWidgetManagerEvent.INITIALIZED)); + } + + public async applyEffects(texture: Texture, selectedEffects: IRoomCameraWidgetSelectedEffect[], isZoomed: boolean): Promise + { + const container = new Container(); + const sprite = new Sprite(texture); + + container.addChild(sprite); + + if(isZoomed) sprite.scale.set(2); + + for(const selectedEffect of selectedEffects) + { + const effect = selectedEffect.effect; + + if(!effect) continue; + + if(effect.colorMatrix) + { + const filter = new ColorMatrixFilter(); + + filter.matrix = effect.colorMatrix; + filter.alpha = selectedEffect.alpha; + + if(!Array.isArray(sprite.filters)) sprite.filters = []; + + sprite.filters.push(filter); + } + else + { + const effectSprite = new Sprite(effect.texture); + effectSprite.alpha = selectedEffect.alpha; + effectSprite.blendMode = effect.blendMode; + + container.addChild(effectSprite); + } + } + + return await TextureUtils.generateImage(container); + } + + public get effects(): Map + { + return this._effects; + } + + public get isLoaded(): boolean + { + return this._isLoaded; + } +} diff --git a/packages/camera/src/RoomCameraWidgetSelectedEffect.ts b/packages/camera/src/RoomCameraWidgetSelectedEffect.ts new file mode 100644 index 0000000..c76ddeb --- /dev/null +++ b/packages/camera/src/RoomCameraWidgetSelectedEffect.ts @@ -0,0 +1,23 @@ +import { IRoomCameraWidgetEffect } from '@nitrots/api'; + +export class RoomCameraWidgetSelectedEffect +{ + private _effect: IRoomCameraWidgetEffect; + private _alpha: number; + + constructor(effect: IRoomCameraWidgetEffect, alpha: number) + { + this._effect = effect; + this._alpha = alpha; + } + + public get effect(): IRoomCameraWidgetEffect + { + return this._effect; + } + + public get alpha(): number + { + return this._alpha; + } +} diff --git a/packages/camera/src/index.ts b/packages/camera/src/index.ts new file mode 100644 index 0000000..a2f3069 --- /dev/null +++ b/packages/camera/src/index.ts @@ -0,0 +1,4 @@ +export * from './GetRoomCameraWidgetManager'; +export * from './RoomCameraWidgetEffect'; +export * from './RoomCameraWidgetManager'; +export * from './RoomCameraWidgetSelectedEffect'; diff --git a/packages/camera/tsconfig.json b/packages/camera/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/camera/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/communication/.eslintrc.json b/packages/communication/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/communication/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/communication/.gitignore b/packages/communication/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/communication/.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/packages/communication/index.ts b/packages/communication/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/communication/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/communication/package.json b/packages/communication/package.json new file mode 100644 index 0000000..a4de308 --- /dev/null +++ b/packages/communication/package.json @@ -0,0 +1,21 @@ +{ + "name": "@nitrots/communication", + "description": "Nitro communication module", + "version": "1.0.0", + "type": "module", + "license": "GPL-3.0", + "scripts": { + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "@nitrots/events": "1.0.0", + "@nitrots/utils": "1.0.0" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/communication/src/CommunicationManager.ts b/packages/communication/src/CommunicationManager.ts new file mode 100644 index 0000000..2389d76 --- /dev/null +++ b/packages/communication/src/CommunicationManager.ts @@ -0,0 +1,97 @@ +import { ICommunicationManager, IConnection, IMessageConfiguration, IMessageEvent } from '@nitrots/api'; +import { GetConfiguration } from '@nitrots/configuration'; +import { GetEventDispatcher, NitroEventType } from '@nitrots/events'; +import { GetTickerTime } from '@nitrots/utils'; +import { NitroMessages } from './NitroMessages'; +import { SocketConnection } from './SocketConnection'; +import { AuthenticatedEvent, ClientHelloMessageComposer, ClientPingEvent, InfoRetrieveMessageComposer, PongMessageComposer, SSOTicketMessageComposer } from './messages'; + +export class CommunicationManager implements ICommunicationManager +{ + private _connection: IConnection = new SocketConnection(); + private _messages: IMessageConfiguration = new NitroMessages(); + + private _pongInterval: any = null; + + constructor() + { + this._connection.registerMessages(this._messages); + } + + public async init(): Promise + { + GetEventDispatcher().addEventListener(NitroEventType.SOCKET_CLOSED, () => + { + this.stopPong(); + }); + + return new Promise((resolve, reject) => + { + GetEventDispatcher().addEventListener(NitroEventType.SOCKET_OPENED, () => + { + if(GetConfiguration().getValue('system.pong.manually', false)) this.startPong(); + + this._connection.send(new ClientHelloMessageComposer(null, null, null, null)); + this._connection.send(new SSOTicketMessageComposer(GetConfiguration().getValue('sso.ticket', null), GetTickerTime())); + }); + + GetEventDispatcher().addEventListener(NitroEventType.SOCKET_ERROR, () => + { + reject(); + }); + + this._connection.addMessageEvent(new ClientPingEvent((event: ClientPingEvent) => this.sendPong())); + + this._connection.addMessageEvent(new AuthenticatedEvent((event: AuthenticatedEvent) => + { + this._connection.authenticated(); + + resolve(); + + event.connection.send(new InfoRetrieveMessageComposer()); + })); + + this._connection.init(GetConfiguration().getValue('socket.url')); + }); + } + + protected startPong(): void + { + if(this._pongInterval) this.stopPong(); + + this._pongInterval = setInterval(() => this.sendPong(), GetConfiguration().getValue('system.pong.interval.ms', 20000)); + } + + protected stopPong(): void + { + if(!this._pongInterval) return; + + clearInterval(this._pongInterval); + + this._pongInterval = null; + } + + protected sendPong(): void + { + this._connection?.send(new PongMessageComposer()); + } + + 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 connection(): IConnection + { + return this._connection; + } +} diff --git a/packages/communication/src/GetCommunication.ts b/packages/communication/src/GetCommunication.ts new file mode 100644 index 0000000..e6a2eed --- /dev/null +++ b/packages/communication/src/GetCommunication.ts @@ -0,0 +1,5 @@ +import { CommunicationManager } from './CommunicationManager'; + +const communication = new CommunicationManager(); + +export const GetCommunication = () => communication; diff --git a/packages/communication/src/NitroMessages.ts b/packages/communication/src/NitroMessages.ts new file mode 100644 index 0000000..7b40517 --- /dev/null +++ b/packages/communication/src/NitroMessages.ts @@ -0,0 +1,1179 @@ +import { IMessageConfiguration } from '@nitrots/api'; +import { AcceptFriendMessageComposer, AcceptFriendResultEvent, AcceptGameInviteMessageComposer, AcceptQuestMessageComposer, AccountSafetyLockStatusChangeMessageEvent, AchievementEvent, AchievementNotificationMessageEvent, AchievementResolutionCompletedMessageEvent, AchievementResolutionProgressMessageEvent, AchievementResolutionsMessageEvent, AchievementsEvent, AchievementsScoreEvent, ActivateQuestMessageComposer, ActivityPointNotificationMessageEvent, AddFavouriteRoomMessageComposer, AddJukeboxDiskComposer, AddSpamWallPostItMessageComposer, ApplySnapshotMessageComposer, ApplyTonerComposer, ApproveAllMembershipRequestsMessageComposer, ApproveNameMessageComposer, ApproveNameMessageEvent, AuthenticatedEvent, AuthenticationMessageComposer, AvailabilityStatusMessageEvent, AvailabilityTimeMessageEvent, AvatarEffectActivatedComposer, AvatarEffectActivatedEvent, AvatarEffectAddedEvent, AvatarEffectExpiredEvent, AvatarEffectSelectedComposer, AvatarEffectSelectedEvent, AvatarEffectsEvent, BadgePointLimitsEvent, BadgeReceivedEvent, BadgesEvent, BannedUsersFromRoomEvent, BonusRareInfoMessageEvent, BotAddedToInventoryEvent, BotCommandConfigurationEvent, BotErrorEvent, BotForceOpenContextMenuEvent, BotInventoryMessageEvent, BotPlaceComposer, BotReceivedMessageEvent, BotRemoveComposer, BotRemovedFromInventoryEvent, BotSkillListUpdateEvent, BotSkillSaveComposer, BreedPetsMessageComposer, BuildersClubFurniCountMessageEvent, BuildersClubPlaceRoomItemMessageComposer, BuildersClubPlaceWallItemMessageComposer, BuildersClubQueryFurniCountMessageComposer, BuildersClubSubscriptionStatusMessageEvent, BundleDiscountRulesetMessageEvent, BuyMarketplaceOfferMessageComposer, BuyMarketplaceTokensMessageComposer, CallForHelpDisabledNotifyMessageEvent, CallForHelpFromForumMessageMessageComposer, CallForHelpFromForumThreadMessageComposer, CallForHelpFromIMMessageComposer, CallForHelpFromPhotoMessageComposer, CallForHelpFromSelfieMessageComposer, CallForHelpMessageComposer, CallForHelpPendingCallsDeletedMessageEvent, CallForHelpPendingCallsMessageEvent, CallForHelpReplyMessageEvent, CallForHelpResultMessageEvent, CameraPublishStatusMessageEvent, CameraPurchaseOKMessageEvent, CameraSnapshotMessageEvent, CameraStorageUrlMessageEvent, CampaignCalendarDataMessageEvent, CampaignCalendarDoorOpenedMessageEvent, CanCreateRoomEvent, CanCreateRoomEventEvent, CanCreateRoomMessageComposer, CancelEventMessageComposer, CancelMarketplaceOfferMessageComposer, CancelMysteryBoxWaitMessageEvent, CancelPetBreedingComposer, CancelQuestMessageComposer, CatalogGroupsComposer, CatalogPageExpirationEvent, CatalogPageMessageEvent, CatalogPageWithEarliestExpiryMessageEvent, CatalogPagesListEvent, CatalogPublishedMessageEvent, CategoriesWithVisitorCountEvent, CfhChatlogEvent, CfhSanctionMessageEvent, CfhTopicsInitEvent, ChangeEmailComposer, ChangeEmailResultEvent, ChangeQueueMessageComposer, ChangeUserNameMessageComposer, ChangeUserNameResultMessageEvent, ChatReviewGuideDecidesOnOfferMessageComposer, ChatReviewGuideDetachedMessageComposer, ChatReviewGuideVoteMessageComposer, ChatReviewSessionCreateMessageComposer, ChatReviewSessionDetachedMessageEvent, ChatReviewSessionOfferedToGuideMessageEvent, ChatReviewSessionResultsMessageEvent, ChatReviewSessionStartedMessageEvent, ChatReviewSessionVotingStatusMessageEvent, CheckUserNameMessageComposer, CheckUserNameResultMessageEvent, ClientHelloMessageComposer, ClientPingEvent, CloseIssueDefaultActionMessageComposer, CloseIssuesMessageComposer, ClubGiftInfoEvent, ClubGiftNotificationEvent, ClubGiftSelectedEvent, CommunityGoalEarnedPrizesMessageEvent, CommunityGoalHallOfFameMessageEvent, CommunityGoalProgressMessageEvent, CommunityGoalVoteMessageComposer, CommunityGoalVoteMessageEvent, CompetitionEntrySubmitResultEvent, CompetitionRoomsDataMessageEvent, CompetitionRoomsSearchMessageComposer, CompetitionStatusMessageEvent, CompetitionVotingInfoMessageEvent, CompleteDiffieHandshakeEvent, CompleteDiffieHandshakeMessageComposer, CompostPlantMessageComposer, ConcurrentUsersGoalProgressMessageEvent, ConfirmPetBreedingComposer, ConnectionErrorEvent, ControlYoutubeDisplayPlaybackMessageComposer, ConvertGlobalRoomIdMessageComposer, ConvertedRoomIdEvent, CraftComposer, CraftSecretComposer, CraftableProductsEvent, CraftingRecipeEvent, CraftingRecipesAvailableEvent, CraftingResultEvent, CreateFlatMessageComposer, CurrentTimingCodeMessageEvent, CustomUserNotificationMessageEvent, DeclineFriendMessageComposer, DefaultSanctionMessageComposer, DeleteFavouriteRoomMessageComposer, DeletePendingCallsForHelpMessageComposer, DesktopViewComposer, DesktopViewEvent, DiceValueMessageEvent, DirectSMSClubBuyAvailableMessageEvent, DisconnectMessageComposer, DisconnectReasonEvent, DoorbellMessageEvent, EditEventMessageComposer, ElementPointerMessageEvent, EmailStatusResultEvent, EpicPopupMessageEvent, ExtendRentOrBuyoutFurniMessageComposer, ExtendRentOrBuyoutStripItemMessageComposer, ExtendedProfileChangedMessageEvent, FavoriteMembershipUpdateMessageEvent, FavouriteChangedEvent, FavouritesEvent, FigureSetIdsMessageEvent, FigureUpdateEvent, FindFriendsProcessResultEvent, FindNewFriendsMessageComposer, FireworkChargeDataEvent, FlatAccessDeniedMessageEvent, FlatControllerAddedEvent, FlatControllerRemovedEvent, FlatControllersEvent, FlatCreatedEvent, FloodControlEvent, FloorHeightMapEvent, FollowFriendFailedEvent, FollowFriendMessageComposer, ForumDataMessageEvent, ForumsListMessageEvent, ForwardToACompetitionRoomMessageComposer, ForwardToARandomPromotedRoomMessageComposer, ForwardToASubmittableRoomMessageComposer, ForwardToRandomCompetitionRoomMessageComposer, ForwardToSomeRoomMessageComposer, FriendFurniConfirmLockMessageComposer, FriendListFragmentEvent, FriendListUpdateComposer, FriendListUpdateEvent, FriendNotificationEvent, FriendRequestQuestCompleteMessageComposer, FriendRequestsEvent, FurniRentOrBuyoutOfferMessageEvent, FurnitureAliasesComposer, FurnitureAliasesEvent, FurnitureColorWheelComposer, FurnitureDataEvent, FurnitureDiceActivateComposer, FurnitureDiceDeactivateComposer, FurnitureExchangeComposer, FurnitureFloorAddEvent, FurnitureFloorEvent, FurnitureFloorRemoveEvent, FurnitureFloorUpdateComposer, FurnitureFloorUpdateEvent, FurnitureGroupInfoComposer, FurnitureListAddOrUpdateEvent, FurnitureListComposer, FurnitureListEvent, FurnitureListInvalidateEvent, FurnitureListRemovedEvent, FurnitureMannequinSaveLookComposer, FurnitureMannequinSaveNameComposer, FurnitureMultiStateComposer, FurnitureOneWayDoorComposer, FurniturePickupComposer, FurniturePlaceComposer, FurniturePlacePaintComposer, FurniturePostItPlaceComposer, FurniturePostItPlacedEvent, FurnitureRandomStateComposer, FurnitureStackHeightComposer, FurnitureStackHeightEvent, FurnitureWallAddEvent, FurnitureWallEvent, FurnitureWallMultiStateComposer, FurnitureWallRemoveEvent, FurnitureWallUpdateComposer, FurnitureWallUpdateEvent, Game2AccountGameStatusMessageEvent, Game2CheckGameDirectoryStatusMessageComposer, Game2ExitGameMessageComposer, Game2GameChatMessageComposer, Game2GameDirectoryStatusMessageEvent, Game2GetAccountGameStatusMessageComposer, Game2GetWeeklyFriendsLeaderboardComposer, Game2GetWeeklyLeaderboardComposer, Game2InArenaQueueMessageEvent, Game2JoiningGameFailedMessageEvent, Game2LoadStageReadyMessageComposer, Game2PlayAgainMessageComposer, Game2RequestFullStatusUpdateMessageComposer, Game2StartingGameFailedMessageEvent, Game2StopCounterMessageEvent, Game2UserLeftGameMessageEvent, Game2WeeklyFriendsLeaderboardEvent, Game2WeeklyLeaderboardEvent, GameAchievementsMessageEvent, GameInviteMessageEvent, GameListMessageEvent, GameStatusMessageEvent, GameUnloadedMessageComposer, GenericErrorEvent, GetBadgePointLimitsComposer, GetBonusRareInfoMessageComposer, GetBotInventoryComposer, GetBundleDiscountRulesetComposer, GetCatalogIndexComposer, GetCatalogPageComposer, GetCatalogPageExpirationComposer, GetCatalogPageWithEarliestExpiryComposer, GetCategoriesWithUserCountMessageComposer, GetCfhChatlogMessageComposer, GetCfhStatusMessageComposer, GetClubGiftInfo, GetClubOffersMessageComposer, GetCommunityGoalEarnedPrizesMessageComposer, GetCommunityGoalHallOfFameMessageComposer, GetCommunityGoalProgressMessageComposer, GetConcurrentUsersGoalProgressMessageComposer, GetConcurrentUsersRewardMessageComposer, GetCraftableProductsComposer, GetCraftingRecipeComposer, GetCraftingRecipesAvailableComposer, GetCurrentTimingCodeMessageComposer, GetCustomRoomFilterMessageComposer, GetDailyQuestMessageComposer, GetDirectClubBuyAvailableComposer, GetEmailStatusComposer, GetExtendedProfileByNameMessageComposer, GetFaqCategoryMessageComposer, GetFaqTextMessageComposer, GetForumStatsMessageComposer, GetForumsListMessageComposer, GetFriendRequestsComposer, GetGameAchievementsMessageComposer, GetGameListMessageComposer, GetGameStatusMessageComposer, GetGiftMessageComposer, GetGiftWrappingConfigurationComposer, GetGuestRoomMessageComposer, GetGuestRoomResultEvent, GetGuideReportingStatusMessageComposer, GetHabboBasicMembershipExtendOfferComposer, GetHabboClubExtendOfferMessageComposer, GetHabboGroupBadgesMessageComposer, GetIgnoredUsersComposer, GetInterstitialMessageComposer, GetIsBadgeRequestFulfilledComposer, GetIsOfferGiftableComposer, GetIsUserPartOfCompetitionMessageComposer, GetItemDataComposer, GetJukeboxPlayListMessageComposer, GetLimitedOfferAppearingNextComposer, GetMarketplaceCanMakeOfferComposer, GetMarketplaceConfigurationMessageComposer, GetMarketplaceItemStatsComposer, GetMarketplaceOffersMessageComposer, GetMarketplaceOwnOffersMessageComposer, GetMessagesMessageComposer, GetModeratorRoomInfoMessageComposer, GetModeratorUserInfoMessageComposer, GetNextTargetedOfferComposer, GetNowPlayingMessageComposer, GetOccupiedTilesMessageComposer, GetOfficialRoomsMessageComposer, GetOfficialSongIdMessageComposer, GetPendingCallsForHelpMessageComposer, GetPetCommandsComposer, GetPopularRoomTagsMessageComposer, GetProductOfferComposer, GetPromoArticlesComposer, GetQuestsMessageComposer, GetQuizQuestionsComposer, GetRecyclerStatusMessageComposer, GetRentOrBuyoutOfferMessageComposer, GetResolutionAchievementsMessageComposer, GetRoomAdPurchaseInfoComposer, GetRoomChatlogMessageComposer, GetRoomEntryDataMessageComposer, GetRoomEntryTileMessageComposer, GetRoomVisitsMessageComposer, GetSeasonalCalendarDailyOfferComposer, GetSeasonalQuestsOnlyMessageComposer, GetSecondsUntilMessageComposer, GetSellablePetPalettesComposer, GetSongInfoMessageComposer, GetSoundMachinePlayListMessageComposer, GetSoundSettingsComposer, GetTalentTrackLevelMessageComposer, GetTargetedOfferComposer, GetThreadMessageComposer, GetThreadsMessageComposer, GetUnreadForumsCountMessageComposer, GetUserChatlogMessageComposer, GetUserEventCatsMessageComposer, GetUserFlatCatsMessageComposer, GetUserGameAchievementsMessageComposer, GetUserSongDisksMessageComposer, GetUserTagsComposer, GetWardrobeMessageComposer, GetWeeklyGameRewardComposer, GetWeeklyGameRewardWinnersComposer, GetYoutubeDisplayStatusMessageComposer, GiftReceiverNotFoundEvent, GiftWrappingConfigurationEvent, GoToFlatMessageComposer, GotMysteryBoxPrizeMessageEvent, GroupAdminGiveComposer, GroupAdminTakeComposer, GroupBadgePartsComposer, GroupBadgePartsEvent, GroupBuyComposer, GroupBuyDataComposer, GroupBuyDataEvent, GroupConfirmMemberRemoveEvent, GroupConfirmRemoveMemberComposer, GroupDeleteComposer, GroupDetailsChangedMessageEvent, GroupFavoriteComposer, GroupFurniContextMenuInfoMessageEvent, GroupInformationComposer, GroupInformationEvent, GroupJoinComposer, GroupMembersComposer, GroupMembersEvent, GroupMembershipAcceptComposer, GroupMembershipDeclineComposer, GroupMembershipRequestedMessageEvent, GroupPurchasedEvent, GroupRemoveMemberComposer, GroupSaveBadgeComposer, GroupSaveColorsComposer, GroupSaveInformationComposer, GroupSavePreferencesComposer, GroupSettingsComposer, GroupSettingsEvent, GroupUnfavoriteComposer, GuestRoomSearchResultEvent, GuideOnDutyStatusMessageEvent, GuideReportingStatusMessageEvent, GuideSessionAttachedMessageEvent, GuideSessionCreateMessageComposer, GuideSessionDetachedMessageEvent, GuideSessionEndedMessageEvent, GuideSessionErrorMessageEvent, GuideSessionFeedbackMessageComposer, GuideSessionGetRequesterRoomMessageComposer, GuideSessionGuideDecidesMessageComposer, GuideSessionInviteRequesterMessageComposer, GuideSessionInvitedToGuideRoomMessageEvent, GuideSessionIsTypingMessageComposer, GuideSessionMessageMessageComposer, GuideSessionMessageMessageEvent, GuideSessionOnDutyUpdateMessageComposer, GuideSessionPartnerIsTypingMessageEvent, GuideSessionReportMessageComposer, GuideSessionRequesterCancelsMessageComposer, GuideSessionRequesterRoomMessageEvent, GuideSessionResolvedMessageComposer, GuideSessionStartedMessageEvent, GuideTicketCreationResultMessageEvent, GuideTicketResolutionMessageEvent, GuildBaseSearchMessageComposer, GuildEditFailedMessageEvent, GuildForumThreadsEvent, GuildMemberMgmtFailedMessageEvent, GuildMembershipsMessageEvent, HabboBroadcastMessageEvent, HabboClubExtendOfferMessageEvent, HabboClubOffersMessageEvent, HabboGroupBadgesMessageEvent, HabboGroupDeactivatedMessageEvent, HabboGroupJoinFailedMessageEvent, HabboSearchComposer, HabboSearchResultEvent, HarvestPetMessageComposer, HotelClosedAndOpensEvent, HotelClosesAndWillOpenAtEvent, HotelMergeNameChangeEvent, HotelWillCloseInMinutesEvent, IdentityAccountsEvent, IgnoreResultEvent, IgnoreUserComposer, IgnoreUserIdComposer, IgnoredUsersEvent, InClientLinkEvent, IncomingHeader, InfoFeedEnableMessageEvent, InfoRetrieveMessageComposer, InitCameraMessageEvent, InitDiffieHandshakeEvent, InitDiffieHandshakeMessageComposer, InstantMessageErrorEvent, InterstitialMessageEvent, InterstitialShownMessageComposer, IsBadgeRequestFulfilledEvent, IsOfferGiftableMessageEvent, IsUserPartOfCompetitionMessageEvent, IssueCloseNotificationMessageEvent, IssueDeletedMessageEvent, IssueInfoMessageEvent, IssuePickFailedMessageEvent, ItemDataUpdateMessageEvent, JoinQueueMessageComposer, JoinedQueueMessageEvent, JoiningQueueFailedMessageEvent, JukeboxPlayListFullMessageEvent, JukeboxSongDisksMessageEvent, LagWarningReportMessageComposer, LeaveQueueMessageComposer, LeftQueueMessageEvent, LimitedEditionSoldOutEvent, LimitedOfferAppearingNextMessageEvent, LoadGameMessageEvent, LoadGameUrlEvent, LoveLockFurniFinishedEvent, LoveLockFurniFriendConfirmedEvent, LoveLockFurniStartEvent, MOTDNotificationEvent, MaintenanceStatusMessageEvent, MakeOfferMessageComposer, MarkCatalogNewAdditionsPageOpenedComposer, MarketPlaceOffersEvent, MarketplaceBuyOfferResultEvent, MarketplaceCanMakeOfferResult, MarketplaceCancelOfferResultEvent, MarketplaceConfigurationEvent, MarketplaceItemStatsEvent, MarketplaceMakeOfferResult, MarketplaceOwnOffersEvent, MessageErrorEvent, MessengerInitComposer, MessengerInitEvent, MiniMailNewMessageEvent, MiniMailUnreadCountEvent, ModAlertMessageComposer, ModBanMessageComposer, ModKickMessageComposer, ModMessageMessageComposer, ModMuteMessageComposer, ModToolPreferencesComposer, ModToolSanctionComposer, ModTradingLockMessageComposer, ModerateMessageMessageComposer, ModerateRoomMessageComposer, ModerateThreadMessageComposer, ModeratorActionMessageComposer, ModeratorActionResultMessageEvent, ModeratorCautionEvent, ModeratorInitMessageEvent, ModeratorMessageEvent, ModeratorRoomInfoEvent, ModeratorToolPreferencesEvent, ModeratorUserInfoEvent, MoodlightSettingsComposer, MoodlightSettingsSaveComposer, MoodlightTogggleStateComposer, MuteAllInRoomEvent, MyFavouriteRoomsSearchMessageComposer, MyFrequentRoomHistorySearchMessageComposer, MyFriendsRoomsSearchMessageComposer, MyGuildBasesSearchMessageComposer, MyRecommendedRoomsMessageComposer, MyRoomHistorySearchMessageComposer, MyRoomRightsSearchMessageComposer, MyRoomsSearchMessageComposer, MysteryBoxKeysEvent, MysteryBoxWaitingCanceledMessageComposer, NavigatorCategoryListModeComposer, NavigatorCollapsedEvent, NavigatorDeleteSavedSearchComposer, NavigatorHomeRoomEvent, NavigatorInitComposer, NavigatorLiftedEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSearchCloseComposer, NavigatorSearchComposer, NavigatorSearchEvent, NavigatorSearchOpenComposer, NavigatorSearchSaveComposer, NavigatorSearchesEvent, NavigatorSettingsEvent, NavigatorSettingsSaveComposer, NewConsoleMessageEvent, NewFriendRequestEvent, NewUserExperienceGetGiftsComposer, NewUserExperienceGiftOfferMessageEvent, NewUserExperienceNotCompleteEvent, NewUserExperienceScriptProceedComposer, NoOwnedRoomsAlertMessageEvent, NoSuchFlatEvent, NoobnessLevelMessageEvent, NotEnoughBalanceMessageEvent, NotificationDialogMessageEvent, NowPlayingMessageEvent, ObjectsDataUpdateEvent, ObjectsRollingEvent, OfferRewardDeliveredMessageEvent, OfficialSongIdMessageEvent, OneWayDoorStatusMessageEvent, OpenCampaignCalendarDoorAsStaffComposer, OpenCampaignCalendarDoorComposer, OpenMessageComposer, OpenMysteryTrophyMessageComposer, OpenPetPackageMessageComposer, OpenPetPackageRequestedMessageEvent, OpenPetPackageResultMessageEvent, OpenPresentComposer, OpenQuestTrackerMessageComposer, OpenWelcomeGiftComposer, OutgoingHeader, PeerUsersClassificationMessageComposer, PerformanceLogMessageComposer, PerkAllowancesMessageEvent, PetAddedToInventoryEvent, PetBreedingResultEvent, PetExperienceEvent, PetFigureUpdateEvent, PetInfoEvent, PetInventoryEvent, PetLevelNotificationEvent, PetLevelUpdateMessageEvent, PetMountComposer, PetMoveComposer, PetPlaceComposer, PetPlacingErrorEvent, PetReceivedMessageEvent, PetRemoveComposer, PetRemovedFromInventory, PetRespectComposer, PetRespectNoficationEvent, PetScratchFailedMessageEvent, PetSelectedMessageComposer, PetStatusUpdateEvent, PetSupplementComposer, PetSupplementedNotificationEvent, PetTrainingPanelMessageEvent, PhoneCollectionStateMessageEvent, PhotoCompetitionMessageComposer, PickIssuesMessageComposer, PlayListMessageEvent, PlayListSongAddedMessageEvent, PollAnswerComposer, PollContentsEvent, PollErrorEvent, PollOfferEvent, PollRejectComposer, PollStartComposer, PongMessageComposer, PopularRoomTagsResultEvent, PopularRoomsSearchMessageComposer, PostMessageMessageComposer, PostMessageMessageEvent, PostQuizAnswersComposer, PostThreadMessageEvent, PresentOpenedMessageEvent, ProductOfferEvent, PromoArticlesMessageEvent, PublishPhotoMessageComposer, PurchaseBasicMembershipExtensionComposer, PurchaseErrorMessageEvent, PurchaseFromCatalogAsGiftComposer, PurchaseFromCatalogComposer, PurchaseNotAllowedMessageEvent, PurchaseOKMessageEvent, PurchasePhotoMessageComposer, PurchaseRoomAdMessageComposer, PurchaseTargetedOfferComposer, PurchaseVipMembershipExtensionComposer, QuestCancelledMessageEvent, QuestCompletedMessageEvent, QuestDailyMessageEvent, QuestMessageEvent, QuestionAnsweredEvent, QuestionEvent, QuestionFinishedEvent, QuestsMessageEvent, QuizDataMessageEvent, QuizResultsMessageEvent, RateFlatMessageComposer, RecycleItemsMessageComposer, RecyclerFinishedMessageEvent, RecyclerStatusMessageEvent, RedeemCommunityGoalPrizeMessageComposer, RedeemItemClothingComposer, RedeemMarketplaceOfferCreditsMessageComposer, RedeemVoucherMessageComposer, RejectQuestMessageComposer, RelationshipStatusInfoEvent, ReleaseIssuesMessageComposer, RemainingMuteEvent, RemoveAllRightsMessageComposer, RemoveFriendComposer, RemoveJukeboxDiskComposer, RemoveOwnRoomRightsRoomMessageComposer, RemovePetSaddleComposer, RemoveWallItemComposer, RenderRoomMessageComposer, RenderRoomThumbnailMessageComposer, RentableSpaceCancelRentMessageComposer, RentableSpaceRentFailedMessageEvent, RentableSpaceRentMessageComposer, RentableSpaceRentOkMessageEvent, RentableSpaceStatusMessageComposer, RentableSpaceStatusMessageEvent, RequestABadgeComposer, RequestAchievementsMessageComposer, RequestBadgesComposer, RequestBotCommandConfigurationComposer, RequestCameraConfigurationComposer, RequestFriendComposer, RequestFurniInventoryWhenNotInRoomComposer, RequestPetInfoComposer, RequestPetsComposer, RequestSpamWallPostItMessageEvent, ResetPhoneNumberStateMessageComposer, ResetResolutionAchievementMessageComposer, RespectReceivedEvent, RestoreClientMessageEvent, RoomAdErrorEvent, RoomAdEventTabAdClickedComposer, RoomAdEventTabViewedComposer, RoomAdPurchaseInfoEvent, RoomAdPurchaseInitiatedComposer, RoomAdSearchMessageComposer, RoomAmbassadorAlertComposer, RoomBanUserComposer, RoomBannedUsersComposer, RoomChatSettingsEvent, RoomChatlogEvent, RoomCompetitionInitMessageComposer, RoomDeleteComposer, RoomDimmerPresetsEvent, RoomDoorbellAcceptedEvent, RoomDoorbellAccessComposer, RoomEnterComposer, RoomEnterErrorEvent, RoomEnterEvent, RoomEntryInfoMessageEvent, RoomEntryTileMessageEvent, RoomEventCancelEvent, RoomEventEvent, RoomFilterSettingsMessageEvent, RoomForwardEvent, RoomGiveRightsComposer, RoomHeightMapEvent, RoomHeightMapUpdateEvent, RoomInviteErrorEvent, RoomInviteEvent, RoomKickUserComposer, RoomMessageNotificationMessageEvent, RoomMuteComposer, RoomMuteUserComposer, RoomNetworkOpenConnectionMessageComposer, RoomOccupiedTilesMessageEvent, RoomPaintEvent, RoomPollResultEvent, RoomReadyMessageEvent, RoomRightsClearEvent, RoomRightsEvent, RoomRightsOwnerEvent, RoomScoreEvent, RoomSettingsComposer, RoomSettingsDataEvent, RoomSettingsErrorEvent, RoomSettingsSaveErrorEvent, RoomSettingsSavedEvent, RoomSettingsUpdatedEvent, RoomTakeRightsComposer, RoomTextSearchMessageComposer, RoomThumbnailUpdateResultEvent, RoomUnbanUserComposer, RoomUnitActionComposer, RoomUnitChatComposer, RoomUnitChatEvent, RoomUnitChatShoutComposer, RoomUnitChatShoutEvent, RoomUnitChatStyleComposer, RoomUnitChatWhisperComposer, RoomUnitChatWhisperEvent, RoomUnitDanceComposer, RoomUnitDanceEvent, RoomUnitDropHandItemComposer, RoomUnitEffectEvent, RoomUnitEvent, RoomUnitExpressionEvent, RoomUnitGiveHandItemComposer, RoomUnitGiveHandItemPetComposer, RoomUnitHandItemEvent, RoomUnitHandItemReceivedEvent, RoomUnitIdleEvent, RoomUnitInfoEvent, RoomUnitLookComposer, RoomUnitNumberEvent, RoomUnitPostureComposer, RoomUnitRemoveEvent, RoomUnitSignComposer, RoomUnitStatusEvent, RoomUnitTypingEvent, RoomUnitTypingStartComposer, RoomUnitTypingStopComposer, RoomUnitWalkComposer, RoomUsersClassificationMessageComposer, RoomUsersWithRightsComposer, RoomVisitsEvent, RoomVisualizationSettingsEvent, RoomsWhereMyFriendsAreSearchMessageComposer, RoomsWithHighestScoreSearchMessageComposer, SSOTicketMessageComposer, SanctionStatusEvent, SaveRoomSettingsComposer, SaveWardrobeOutfitMessageComposer, ScrGetKickbackInfoMessageComposer, ScrSendKickbackInfoMessageEvent, SearchFaqsMessageComposer, SeasonalCalendarDailyOfferMessageEvent, SeasonalQuestsMessageEvent, SecondsUntilMessageEvent, SelectClubGiftComposer, SellablePetPalettesMessageEvent, SendMessageComposer, SendRoomInviteComposer, SetActivatedBadgesComposer, SetClothingChangeDataMessageComposer, SetItemDataMessageComposer, SetObjectDataMessageComposer, SetPhoneNumberVerificationStatusMessageComposer, SetRelationshipStatusComposer, SetRoomSessionTagsMessageComposer, SetTargetedOfferStateComposer, SetYoutubeDisplayPlaylistMessageComposer, ShopTargetedOfferViewedComposer, ShowEnforceRoomCategoryDialogEvent, ShowMysteryBoxWaitMessageEvent, SimpleAlertMessageEvent, StartCampaignMessageComposer, StartRoomPollEvent, SubmitRoomToCompetitionMessageComposer, TalentLevelUpEvent, TalentTrackComposer, TalentTrackLevelMessageEvent, TalentTrackMessageEvent, TargetedOfferEvent, TargetedOfferNotFoundEvent, ThreadMessagesMessageEvent, ThumbnailStatusMessageEvent, TogglePetBreedingComposer, TogglePetRidingComposer, ToggleStaffPickMessageComposer, TradingAcceptComposer, TradingAcceptEvent, TradingCancelComposer, TradingCloseComposer, TradingCloseEvent, TradingCompletedEvent, TradingConfirmationComposer, TradingConfirmationEvent, TradingListAddItemComposer, TradingListAddItemsComposer, TradingListItemEvent, TradingListItemRemoveComposer, TradingNoSuchItemEvent, TradingNotOpenEvent, TradingOpenComposer, TradingOpenEvent, TradingOpenFailedEvent, TradingOtherNotAllowedEvent, TradingUnacceptComposer, TradingYouAreNotAllowedEvent, TraxSongInfoMessageEvent, TryPhoneNumberMessageComposer, TryPhoneNumberResultMessageEvent, TryVerificationCodeResultMessageEvent, UnblockGroupMemberMessageComposer, UnignoreUserComposer, UniqueIDMessageComposer, UnloadGameMessageEvent, UnreadForumsCountMessageEvent, UnseenItemsEvent, UnseenResetCategoryComposer, UnseenResetItemsComposer, UpdateActionMessageComposer, UpdateConditionMessageComposer, UpdateFloorPropertiesMessageComposer, UpdateForumReadMarkerMessageComposer, UpdateForumSettingsMessageComposer, UpdateHomeRoomMessageComposer, UpdateMessageMessageEvent, UpdateRoomCategoryAndTradeSettingsComposer, UpdateRoomFilterMessageComposer, UpdateRoomThumbnailMessageComposer, UpdateThreadMessageComposer, UpdateThreadMessageEvent, UpdateTriggerMessageComposer, UsePetProductComposer, UserBannedMessageEvent, UserChatlogEvent, UserClassificationMessageEvent, UserCreditsEvent, UserCurrencyComposer, UserCurrencyEvent, UserCurrentBadgesComposer, UserCurrentBadgesEvent, UserEventCatsEvent, UserFigureComposer, UserFlatCatsEvent, UserGameAchievementsMessageEvent, UserInfoEvent, UserMottoComposer, UserNameChangeMessageEvent, UserPermissionsEvent, UserProfileComposer, UserProfileEvent, UserRelationshipsComposer, UserRespectComposer, UserSettingsCameraFollowComposer, UserSettingsEvent, UserSettingsOldChatComposer, UserSettingsRoomInvitesComposer, UserSettingsSoundComposer, UserSongDisksInventoryMessageEvent, UserSubscriptionComposer, UserSubscriptionEvent, UserTagsMessageEvent, UserUnbannedFromRoomEvent, UserWardrobePageEvent, VerifyCodeMessageComposer, VersionCheckMessageComposer, VisitUserComposer, VoteForRoomMessageComposer, VotePollCounterMessageComposer, VoucherRedeemErrorMessageEvent, VoucherRedeemOkMessageEvent, WardrobeMessageEvent, WeeklyCompetitiveFriendsLeaderboardEvent, WeeklyCompetitiveLeaderboardEvent, WeeklyGameRewardEvent, WeeklyGameRewardWinnersEvent, WelcomeGiftChangeEmailComposer, WelcomeGiftChangeEmailResultEvent, WelcomeGiftStatusEvent, WiredFurniActionEvent, WiredFurniConditionEvent, WiredFurniTriggerEvent, WiredOpenEvent, WiredRewardResultMessageEvent, WiredSaveSuccessEvent, WiredValidationErrorEvent, YouArePlayingGameEvent, YouAreSpectatorMessageEvent, YoutubeControlVideoMessageEvent, YoutubeDisplayPlaylistsEvent, YoutubeDisplayVideoMessageEvent } from './messages'; + +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 + { + // ADVERTISEMENT + this._events.set(IncomingHeader.INTERSTITIAL_MESSAGE, InterstitialMessageEvent); + this._events.set(IncomingHeader.ROOM_AD_ERROR, RoomAdErrorEvent); + + // AVAILABILITY + this._events.set(IncomingHeader.AVAILABILITY_STATUS, AvailabilityStatusMessageEvent); + this._events.set(IncomingHeader.AVAILABILITY_TIME, AvailabilityTimeMessageEvent); + this._events.set(IncomingHeader.HOTEL_CLOSED_AND_OPENS, HotelClosedAndOpensEvent); + this._events.set(IncomingHeader.HOTEL_CLOSES_AND_OPENS_AT, HotelClosesAndWillOpenAtEvent); + this._events.set(IncomingHeader.HOTEL_WILL_CLOSE_MINUTES, HotelWillCloseInMinutesEvent); + this._events.set(IncomingHeader.HOTEL_MAINTENANCE, MaintenanceStatusMessageEvent); + + // AVATAR + this._events.set(IncomingHeader.USER_CHANGE_NAME, ChangeUserNameResultMessageEvent); + this._events.set(IncomingHeader.CHECK_USER_NAME, CheckUserNameResultMessageEvent); + this._events.set(IncomingHeader.USER_FIGURE, FigureUpdateEvent); + this._events.set(IncomingHeader.USER_OUTFITS, WardrobeMessageEvent); + + // BOTS + this._events.set(IncomingHeader.ADD_BOT_TO_INVENTORY, BotAddedToInventoryEvent); + this._events.set(IncomingHeader.USER_BOTS, BotInventoryMessageEvent); + this._events.set(IncomingHeader.BOT_RECEIVED, BotReceivedMessageEvent); + this._events.set(IncomingHeader.REMOVE_BOT_FROM_INVENTORY, BotRemovedFromInventoryEvent); + + // CALL FOR HELP + this._events.set(IncomingHeader.CFH_SANCTION, CfhSanctionMessageEvent); + this._events.set(IncomingHeader.CFH_TOPICS, CfhTopicsInitEvent); + this._events.set(IncomingHeader.CFH_SANCTION_STATUS, SanctionStatusEvent); + + // CAMERA + this._events.set(IncomingHeader.CAMERA_PUBLISH_STATUS, CameraPublishStatusMessageEvent); + this._events.set(IncomingHeader.CAMERA_PURCHASE_OK, CameraPurchaseOKMessageEvent); + this._events.set(IncomingHeader.CAMERA_STORAGE_URL, CameraStorageUrlMessageEvent); + this._events.set(IncomingHeader.COMPETITION_STATUS, CompetitionStatusMessageEvent); + this._events.set(IncomingHeader.INIT_CAMERA, InitCameraMessageEvent); + this._events.set(IncomingHeader.THUMBNAIL_STATUS, ThumbnailStatusMessageEvent); + this._events.set(IncomingHeader.CAMERA_SNAPSHOT, CameraSnapshotMessageEvent); + + // CAMPAIGN + this._events.set(IncomingHeader.CAMPAIGN_CALENDAR_DATA, CampaignCalendarDataMessageEvent); + this._events.set(IncomingHeader.CAMPAIGN_CALENDAR_DOOR_OPENED, CampaignCalendarDoorOpenedMessageEvent); + + // CATALOG + this._events.set(IncomingHeader.BONUS_RARE_INFO, BonusRareInfoMessageEvent); + this._events.set(IncomingHeader.BUILDERS_CLUB_FURNI_COUNT, BuildersClubFurniCountMessageEvent); + this._events.set(IncomingHeader.BUILDERS_CLUB_SUBSCRIPTION, BuildersClubSubscriptionStatusMessageEvent); + this._events.set(IncomingHeader.BUNDLE_DISCOUNT_RULESET, BundleDiscountRulesetMessageEvent); + this._events.set(IncomingHeader.CATALOG_PAGE_EXPIRATION, CatalogPageExpirationEvent); + this._events.set(IncomingHeader.CATALOG_PAGE, CatalogPageMessageEvent); + this._events.set(IncomingHeader.CATALOG_PAGE_LIST, CatalogPagesListEvent); + this._events.set(IncomingHeader.CATALOG_EARLIEST_EXPIRY, CatalogPageWithEarliestExpiryMessageEvent); + this._events.set(IncomingHeader.CATALOG_PUBLISHED, CatalogPublishedMessageEvent); + this._events.set(IncomingHeader.CLUB_GIFT_INFO, ClubGiftInfoEvent); + this._events.set(IncomingHeader.CLUB_GIFT_SELECTED, ClubGiftSelectedEvent); + this._events.set(IncomingHeader.DIRECT_SMS_CLUB_BUY, DirectSMSClubBuyAvailableMessageEvent); + this._events.set(IncomingHeader.GIFT_RECEIVER_NOT_FOUND, GiftReceiverNotFoundEvent); + this._events.set(IncomingHeader.GIFT_WRAPPER_CONFIG, GiftWrappingConfigurationEvent); + this._events.set(IncomingHeader.CLUB_EXTENDED_OFFER, HabboClubExtendOfferMessageEvent); + this._events.set(IncomingHeader.CLUB_OFFERS, HabboClubOffersMessageEvent); + this._events.set(IncomingHeader.IS_OFFER_GIFTABLE, IsOfferGiftableMessageEvent); + this._events.set(IncomingHeader.LIMITED_SOLD_OUT, LimitedEditionSoldOutEvent); + this._events.set(IncomingHeader.LIMITED_OFFER_APPEARING_NEXT, LimitedOfferAppearingNextMessageEvent); + this._events.set(IncomingHeader.NOT_ENOUGH_BALANCE, NotEnoughBalanceMessageEvent); + this._events.set(IncomingHeader.PRODUCT_OFFER, ProductOfferEvent); + this._events.set(IncomingHeader.CATALOG_PURCHASE_ERROR, PurchaseErrorMessageEvent); + this._events.set(IncomingHeader.CATALOG_PURCHASE_NOT_ALLOWED, PurchaseNotAllowedMessageEvent); + this._events.set(IncomingHeader.CATALOG_PURCHASE_OK, PurchaseOKMessageEvent); + this._events.set(IncomingHeader.ROOM_AD_PURCHASE, RoomAdPurchaseInfoEvent); + this._events.set(IncomingHeader.SEASONAL_CALENDAR_OFFER, SeasonalCalendarDailyOfferMessageEvent); + this._events.set(IncomingHeader.CATALOG_RECEIVE_PET_BREEDS, SellablePetPalettesMessageEvent); + this._events.set(IncomingHeader.TARGET_OFFER, TargetedOfferEvent); + this._events.set(IncomingHeader.TARGET_OFFER_NOT_FOUND, TargetedOfferNotFoundEvent); + this._events.set(IncomingHeader.REDEEM_VOUCHER_ERROR, VoucherRedeemErrorMessageEvent); + this._events.set(IncomingHeader.REDEEM_VOUCHER_OK, VoucherRedeemOkMessageEvent); + + // CLIENT + this._events.set(IncomingHeader.CLIENT_PING, ClientPingEvent); + + // COMPETITION + this._events.set(IncomingHeader.COMPETITION_ENTRY_SUBMIT, CompetitionEntrySubmitResultEvent); + this._events.set(IncomingHeader.COMPETITION_VOTING_INFO, CompetitionVotingInfoMessageEvent); + this._events.set(IncomingHeader.COMPETITION_TIMING_CODE, CurrentTimingCodeMessageEvent); + this._events.set(IncomingHeader.COMPETITION_USER_PART_OF, IsUserPartOfCompetitionMessageEvent); + this._events.set(IncomingHeader.COMPETITION_NO_OWNED_ROOMS, NoOwnedRoomsAlertMessageEvent); + this._events.set(IncomingHeader.COMPETITION_SECONDS_UNTIL, SecondsUntilMessageEvent); + + // CRAFTING + this._events.set(IncomingHeader.CRAFTABLE_PRODUCTS, CraftableProductsEvent); + this._events.set(IncomingHeader.CRAFTING_RECIPE, CraftingRecipeEvent); + this._events.set(IncomingHeader.CRAFTING_RECIPES_AVAILABLE, CraftingRecipesAvailableEvent); + this._events.set(IncomingHeader.CRAFTING_RESULT, CraftingResultEvent); + + // 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, MiniMailUnreadCountEvent); + 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); + + // GAMES + this._events.set(IncomingHeader.ACHIEVEMENTRESOLUTIONCOMPLETED, AchievementResolutionCompletedMessageEvent); + this._events.set(IncomingHeader.ACHIEVEMENTRESOLUTIONPROGRESS, AchievementResolutionProgressMessageEvent); + this._events.set(IncomingHeader.ACHIEVEMENTRESOLUTIONS, AchievementResolutionsMessageEvent); + this._events.set(IncomingHeader.LOAD_GAME_URL, LoadGameUrlEvent); + this._events.set(IncomingHeader.LOADGAME, LoadGameMessageEvent); + this._events.set(IncomingHeader.UNLOADGAME, UnloadGameMessageEvent); + this._events.set(IncomingHeader.GAME_CENTER_GAME_LIST, GameListMessageEvent); + this._events.set(IncomingHeader.GAMESTATUSMESSAGE, GameStatusMessageEvent); + this._events.set(IncomingHeader.GAME_CENTER_ACHIEVEMENTS, UserGameAchievementsMessageEvent); + this._events.set(IncomingHeader.GAME_CENTER_STATUS, Game2AccountGameStatusMessageEvent); + this._events.set(IncomingHeader.GAME_CENTER_IN_ARENA_QUEUE, Game2InArenaQueueMessageEvent); + this._events.set(IncomingHeader.GAME_CENTER_STOP_COUNTER, Game2StopCounterMessageEvent); + this._events.set(IncomingHeader.GAME_CENTER_USER_LEFT_GAME, Game2UserLeftGameMessageEvent); + this._events.set(IncomingHeader.GAME_CENTER_DIRECTORY_STATUS, Game2GameDirectoryStatusMessageEvent); + this._events.set(IncomingHeader.GAME_CENTER_STARTING_GAME_FAILED, Game2StartingGameFailedMessageEvent); + this._events.set(IncomingHeader.GAME_CENTER_JOINING_FAILED, Game2JoiningGameFailedMessageEvent); + this._events.set(IncomingHeader.GAMEACHIEVEMENTS, GameAchievementsMessageEvent); + this._events.set(IncomingHeader.GAMEINVITE, GameInviteMessageEvent); + this._events.set(IncomingHeader.JOINEDQUEUEMESSAGE, JoinedQueueMessageEvent); + this._events.set(IncomingHeader.JOININGQUEUEFAILED, JoiningQueueFailedMessageEvent); + this._events.set(IncomingHeader.LEFTQUEUE, LeftQueueMessageEvent); + this._events.set(IncomingHeader.WEEKLY_GAME_REWARD, WeeklyGameRewardEvent); + this._events.set(IncomingHeader.WEEKLY_GAME_REWARD_WINNERS, WeeklyGameRewardWinnersEvent); + this._events.set(IncomingHeader.WEEKLY_COMPETITIVE_LEADERBOARD, WeeklyCompetitiveLeaderboardEvent); + this._events.set(IncomingHeader.WEEKLY_COMPETITIVE_FRIENDS_LEADERBOARD, WeeklyCompetitiveFriendsLeaderboardEvent); + this._events.set(IncomingHeader.WEEKLY_GAME2_FRIENDS_LEADERBOARD, Game2WeeklyFriendsLeaderboardEvent); + this._events.set(IncomingHeader.WEEKLY_GAME2_LEADERBOARD, Game2WeeklyLeaderboardEvent); + + // 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); + this._events.set(IncomingHeader.GROUP_PURCHASED, GroupPurchasedEvent); + this._events.set(IncomingHeader.GROUP_BADGES, HabboGroupBadgesMessageEvent); + this._events.set(IncomingHeader.GROUP_DEACTIVATE, HabboGroupDeactivatedMessageEvent); + this._events.set(IncomingHeader.GROUP_MEMBERSHIP_REQUESTED, GroupMembershipRequestedMessageEvent); + this._events.set(IncomingHeader.GROUP_DETAILS_CHANGED, GroupDetailsChangedMessageEvent); + this._events.set(IncomingHeader.GROUP_HABBO_JOIN_FAILED, HabboGroupJoinFailedMessageEvent); + + // GROUP FORUMS + this._events.set(IncomingHeader.GROUP_FORUM_DATA, ForumDataMessageEvent); + this._events.set(IncomingHeader.GROUP_FORUM_LIST, ForumsListMessageEvent); + this._events.set(IncomingHeader.GROUP_FORUM_THREADS, GuildForumThreadsEvent); + this._events.set(IncomingHeader.GROUP_FORUM_POST, PostMessageMessageEvent); + this._events.set(IncomingHeader.GROUP_FORUM_POST_THREAD, PostThreadMessageEvent); + this._events.set(IncomingHeader.GROUP_FORUM_THREAD_MESSAGES, ThreadMessagesMessageEvent); + this._events.set(IncomingHeader.GROUP_FORUM_UNREAD_COUNT, UnreadForumsCountMessageEvent); + this._events.set(IncomingHeader.GROUP_FORUM_UPDATE_MESSAGE, UpdateMessageMessageEvent); + this._events.set(IncomingHeader.GROUP_FORUM_UPDATE_THREAD, UpdateThreadMessageEvent); + + // HELP + this._events.set(IncomingHeader.CFH_DISABLED_NOTIFY, CallForHelpDisabledNotifyMessageEvent); + this._events.set(IncomingHeader.CFH_PENDING_CALLS_DELETED, CallForHelpPendingCallsDeletedMessageEvent); + this._events.set(IncomingHeader.CFH_PENDING_CALLS, CallForHelpPendingCallsMessageEvent); + this._events.set(IncomingHeader.CFH_REPLY, CallForHelpReplyMessageEvent); + this._events.set(IncomingHeader.CFH_RESULT_MESSAGE, CallForHelpResultMessageEvent); + this._events.set(IncomingHeader.GUIDE_ON_DUTY_STATUS, GuideOnDutyStatusMessageEvent); + this._events.set(IncomingHeader.GUIDE_SESSION_ATTACHED, GuideSessionAttachedMessageEvent); + this._events.set(IncomingHeader.GUIDE_SESSION_DETACHED, GuideSessionDetachedMessageEvent); + this._events.set(IncomingHeader.GUIDE_SESSION_ENDED, GuideSessionEndedMessageEvent); + this._events.set(IncomingHeader.GUIDE_SESSION_ERROR, GuideSessionErrorMessageEvent); + this._events.set(IncomingHeader.GUIDE_SESSION_INVITED_TO_GUIDE_ROOM, GuideSessionInvitedToGuideRoomMessageEvent); + this._events.set(IncomingHeader.GUIDE_SESSION_MESSAGE, GuideSessionMessageMessageEvent); + this._events.set(IncomingHeader.GUIDE_SESSION_PARTNER_IS_TYPING, GuideSessionPartnerIsTypingMessageEvent); + this._events.set(IncomingHeader.GUIDE_SESSION_REQUESTER_ROOM, GuideSessionRequesterRoomMessageEvent); + this._events.set(IncomingHeader.GUIDE_SESSION_STARTED, GuideSessionStartedMessageEvent); + this._events.set(IncomingHeader.GUIDE_TICKET_CREATION_RESULT, GuideTicketCreationResultMessageEvent); + this._events.set(IncomingHeader.GUIDE_TICKET_RESOLUTION, GuideTicketResolutionMessageEvent); + this._events.set(IncomingHeader.GUIDE_REPORTING_STATUS, GuideReportingStatusMessageEvent); + this._events.set(IncomingHeader.HOTEL_MERGE_NAME_CHANGE, HotelMergeNameChangeEvent); + this._events.set(IncomingHeader.ISSUE_CLOSE_NOTIFICATION, IssueCloseNotificationMessageEvent); + this._events.set(IncomingHeader.QUIZ_DATA, QuizDataMessageEvent); + this._events.set(IncomingHeader.QUIZ_RESULTS, QuizResultsMessageEvent); + this._events.set(IncomingHeader.CHAT_REVIEW_SESSION_DETACHED, ChatReviewSessionDetachedMessageEvent); + this._events.set(IncomingHeader.CHAT_REVIEW_SESSION_OFFERED_TO_GUIDE, ChatReviewSessionOfferedToGuideMessageEvent); + this._events.set(IncomingHeader.CHAT_REVIEW_SESSION_RESULTS, ChatReviewSessionResultsMessageEvent); + this._events.set(IncomingHeader.CHAT_REVIEW_SESSION_STARTED, ChatReviewSessionStartedMessageEvent); + this._events.set(IncomingHeader.CHAT_REVIEW_SESSION_VOTING_STATUS, ChatReviewSessionVotingStatusMessageEvent); + + // INVENTORY + this._events.set(IncomingHeader.ACHIEVEMENT_PROGRESSED, AchievementEvent); + this._events.set(IncomingHeader.ACHIEVEMENT_LIST, AchievementsEvent); + this._events.set(IncomingHeader.USER_ACHIEVEMENT_SCORE, AchievementsScoreEvent); + 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); + this._events.set(IncomingHeader.AVATAR_EFFECT_SELECTED, AvatarEffectSelectedEvent); + this._events.set(IncomingHeader.USER_BADGES, BadgesEvent); + this._events.set(IncomingHeader.USER_BADGES_ADD, BadgeReceivedEvent); + this._events.set(IncomingHeader.BADGE_POINT_LIMITS, BadgePointLimitsEvent); + this._events.set(IncomingHeader.BADGE_REQUEST_FULFILLED, IsBadgeRequestFulfilledEvent); + this._events.set(IncomingHeader.USER_CLOTHING, FigureSetIdsMessageEvent); + 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); + 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_RECEIVED, PetReceivedMessageEvent); + this._events.set(IncomingHeader.PET_PLACING_ERROR, PetPlacingErrorEvent); + this._events.set(IncomingHeader.YOUTUBE_CONTROL_VIDEO, YoutubeControlVideoMessageEvent); + this._events.set(IncomingHeader.YOUTUBE_DISPLAY_PLAYLISTS, YoutubeDisplayPlaylistsEvent); + this._events.set(IncomingHeader.YOUTUBE_DISPLAY_VIDEO, YoutubeDisplayVideoMessageEvent); + + // 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); + this._events.set(IncomingHeader.TRADE_NO_SUCH_ITEM, TradingNoSuchItemEvent); + + // LANDING VIEW + this._events.set(IncomingHeader.COMMUNITY_GOAL_VOTE_EVENT, CommunityGoalVoteMessageEvent); + this._events.set(IncomingHeader.PROMO_ARTICLES, PromoArticlesMessageEvent); + + // MARKETPLACE + this._events.set(IncomingHeader.MARKETPLACE_AFTER_ORDER_STATUS, MarketplaceBuyOfferResultEvent); + this._events.set(IncomingHeader.MARKETPLACE_CANCEL_SALE, MarketplaceCancelOfferResultEvent); + this._events.set(IncomingHeader.MARKETPLACE_SELL_ITEM, MarketplaceCanMakeOfferResult); + this._events.set(IncomingHeader.MARKETPLACE_CONFIG, MarketplaceConfigurationEvent); + this._events.set(IncomingHeader.MARKETPLACE_ITEM_STATS, MarketplaceItemStatsEvent); + this._events.set(IncomingHeader.MARKETPLACE_ITEM_POSTED, MarketplaceMakeOfferResult); + this._events.set(IncomingHeader.MARKETPLACE_ITEMS_SEARCHED, MarketPlaceOffersEvent); + this._events.set(IncomingHeader.MARKETPLACE_OWN_ITEMS, MarketplaceOwnOffersEvent); + + // MODERATION + this._events.set(IncomingHeader.USER_BANNED, UserBannedMessageEvent); + this._events.set(IncomingHeader.MODERATION_CAUTION, ModeratorCautionEvent); + this._events.set(IncomingHeader.MODTOOL_ROOM_INFO, ModeratorRoomInfoEvent); + this._events.set(IncomingHeader.MODTOOL_USER_CHATLOG, UserChatlogEvent); + this._events.set(IncomingHeader.MODTOOL_ROOM_CHATLOG, RoomChatlogEvent); + this._events.set(IncomingHeader.MODERATION_USER_INFO, ModeratorUserInfoEvent); + this._events.set(IncomingHeader.MODERATION_TOOL, ModeratorInitMessageEvent); + this._events.set(IncomingHeader.MODTOOL_VISITED_ROOMS_USER, RoomVisitsEvent); + this._events.set(IncomingHeader.CFH_CHATLOG, CfhChatlogEvent); + this._events.set(IncomingHeader.ISSUE_DELETED, IssueDeletedMessageEvent); + this._events.set(IncomingHeader.ISSUE_INFO, IssueInfoMessageEvent); + this._events.set(IncomingHeader.ISSUE_PICK_FAILED, IssuePickFailedMessageEvent); + this._events.set(IncomingHeader.MODERATOR_ACTION_RESULT, ModeratorActionResultMessageEvent); + this._events.set(IncomingHeader.MODERATOR_MESSAGE, ModeratorMessageEvent); + this._events.set(IncomingHeader.MODERATOR_TOOL_PREFERENCES, ModeratorToolPreferencesEvent); + + // MYSTERY BOX + this._events.set(IncomingHeader.MYSTERY_BOX_KEYS, MysteryBoxKeysEvent); + this._events.set(IncomingHeader.GOTMYSTERYBOXPRIZEMESSAGE, GotMysteryBoxPrizeMessageEvent); + this._events.set(IncomingHeader.CANCELMYSTERYBOXWAITMESSAGE, CancelMysteryBoxWaitMessageEvent); + this._events.set(IncomingHeader.SHOWMYSTERYBOXWAITMESSAGE, ShowMysteryBoxWaitMessageEvent); + + // NAVIGATOR + this._events.set(IncomingHeader.CAN_CREATE_ROOM, CanCreateRoomEvent); + this._events.set(IncomingHeader.CAN_CREATE_ROOM_EVENT, CanCreateRoomEventEvent); + this._events.set(IncomingHeader.CATEGORIES_WITH_VISITOR_COUNT, CategoriesWithVisitorCountEvent); + this._events.set(IncomingHeader.COMPETITION_ROOMS_DATA, CompetitionRoomsDataMessageEvent); + this._events.set(IncomingHeader.CONVERTED_ROOM_ID, ConvertedRoomIdEvent); + this._events.set(IncomingHeader.ROOM_DOORBELL, DoorbellMessageEvent); + this._events.set(IncomingHeader.USER_FAVORITE_ROOM, FavouriteChangedEvent); + this._events.set(IncomingHeader.USER_FAVORITE_ROOM_COUNT, FavouritesEvent); + this._events.set(IncomingHeader.ROOM_DOORBELL_REJECTED, FlatAccessDeniedMessageEvent); + this._events.set(IncomingHeader.ROOM_CREATED, FlatCreatedEvent); + this._events.set(IncomingHeader.ROOM_INFO, GetGuestRoomResultEvent); + this._events.set(IncomingHeader.GUEST_ROOM_SEARCH_RESULT, GuestRoomSearchResultEvent); + this._events.set(IncomingHeader.USER_HOME_ROOM, NavigatorHomeRoomEvent); + this._events.set(IncomingHeader.ROOM_EVENT_CANCEL, RoomEventCancelEvent); + this._events.set(IncomingHeader.ROOM_EVENT, RoomEventEvent); + this._events.set(IncomingHeader.ROOM_INFO_UPDATED, RoomSettingsUpdatedEvent); + this._events.set(IncomingHeader.THUMBNAIL_UPDATE_RESULT, RoomThumbnailUpdateResultEvent); + this._events.set(IncomingHeader.NAVIGATOR_EVENT_CATEGORIES, UserEventCatsEvent); + this._events.set(IncomingHeader.NAVIGATOR_CATEGORIES, UserFlatCatsEvent); + + this._events.set(IncomingHeader.NAVIGATOR_COLLAPSED, NavigatorCollapsedEvent); + 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.UNSEEN_ITEMS, UnseenItemsEvent); + this._events.set(IncomingHeader.ACHIEVEMENT_NOTIFICATION, AchievementNotificationMessageEvent); + this._events.set(IncomingHeader.INFO_FEED_ENABLE, InfoFeedEnableMessageEvent); + this._events.set(IncomingHeader.CLUB_GIFT_NOTIFICATION, ClubGiftNotificationEvent); + this._events.set(IncomingHeader.ACTIVITY_POINT_NOTIFICATION, ActivityPointNotificationMessageEvent); + this._events.set(IncomingHeader.BOT_ERROR, BotErrorEvent); + this._events.set(IncomingHeader.PET_LEVEL_NOTIFICATION, PetLevelNotificationEvent); + this._events.set(IncomingHeader.NOTIFICATION_OFFER_REWARD_DELIVERED, OfferRewardDeliveredMessageEvent); + this._events.set(IncomingHeader.NOTIFICATION_SIMPLE_ALERT, SimpleAlertMessageEvent); + this._events.set(IncomingHeader.NOTIFICATION_ELEMENT_POINTER, ElementPointerMessageEvent); + + // PERK + this._events.set(IncomingHeader.USER_PERKS, PerkAllowancesMessageEvent); + + // PETS + this._events.set(IncomingHeader.PET_TRAINING_PANEL, PetTrainingPanelMessageEvent); + this._events.set(IncomingHeader.PET_LEVEL_UPDATE, PetLevelUpdateMessageEvent); + this._events.set(IncomingHeader.PET_SCRATCH_FAILED, PetScratchFailedMessageEvent); + this._events.set(IncomingHeader.PET_OPEN_PACKAGE_REQUESTED, OpenPetPackageRequestedMessageEvent); + this._events.set(IncomingHeader.PET_OPEN_PACKAGE_RESULT, OpenPetPackageResultMessageEvent); + this._events.set(IncomingHeader.PET_BREEDING_RESULT, PetBreedingResultEvent); + + // POLL + this._events.set(IncomingHeader.QUESTION, QuestionEvent); + this._events.set(IncomingHeader.POLL_CONTENTS, PollContentsEvent); + this._events.set(IncomingHeader.POLL_ERROR, PollErrorEvent); + this._events.set(IncomingHeader.POLL_OFFER, PollOfferEvent); + this._events.set(IncomingHeader.POLL_START_ROOM, StartRoomPollEvent); + this._events.set(IncomingHeader.QUESTION_ANSWERED, QuestionAnsweredEvent); + this._events.set(IncomingHeader.QUESTION_FINISHED, QuestionFinishedEvent); + this._events.set(IncomingHeader.POLL_ROOM_RESULT, RoomPollResultEvent); + + // QUEST + this._events.set(IncomingHeader.COMMUNITY_GOAL_EARNED_PRIZES, CommunityGoalEarnedPrizesMessageEvent); + this._events.set(IncomingHeader.COMMUNITY_GOAL_PROGRESS, CommunityGoalProgressMessageEvent); + this._events.set(IncomingHeader.CONCURRENT_USERS_GOAL_PROGRESS, ConcurrentUsersGoalProgressMessageEvent); + this._events.set(IncomingHeader.QUEST_DAILY, QuestDailyMessageEvent); + this._events.set(IncomingHeader.QUEST_CANCELLED, QuestCancelledMessageEvent); + this._events.set(IncomingHeader.QUEST_COMPLETED, QuestCompletedMessageEvent); + this._events.set(IncomingHeader.COMMUNITY_GOAL_HALL_OF_FAME, CommunityGoalHallOfFameMessageEvent); + this._events.set(IncomingHeader.EPIC_POPUP, EpicPopupMessageEvent); + this._events.set(IncomingHeader.SEASONAL_QUESTS, SeasonalQuestsMessageEvent); + this._events.set(IncomingHeader.QUESTS, QuestsMessageEvent); + this._events.set(IncomingHeader.QUEST, QuestMessageEvent); + + // ROOM + this._events.set(IncomingHeader.ROOM_ENTER_ERROR, RoomEnterErrorEvent); + this._events.set(IncomingHeader.ROOM_ENTER, RoomEnterEvent); + this._events.set(IncomingHeader.ROOM_FORWARD, RoomForwardEvent); + this._events.set(IncomingHeader.ROOM_DOORBELL_ACCEPTED, RoomDoorbellAcceptedEvent); + this._events.set(IncomingHeader.ROOM_RIGHTS_CLEAR, RoomRightsClearEvent); + this._events.set(IncomingHeader.ROOM_RIGHTS_OWNER, RoomRightsOwnerEvent); + this._events.set(IncomingHeader.ROOM_RIGHTS, RoomRightsEvent); + this._events.set(IncomingHeader.BOT_COMMAND_CONFIGURATION, BotCommandConfigurationEvent); + this._events.set(IncomingHeader.BOT_SKILL_LIST_UPDATE, BotSkillListUpdateEvent); + this._events.set(IncomingHeader.BOT_FORCE_OPEN_CONTEXT_MENU, BotForceOpenContextMenuEvent); + this._events.set(IncomingHeader.ROOM_SETTINGS_CHAT, RoomChatSettingsEvent); + this._events.set(IncomingHeader.ROOM_INFO_OWNER, RoomEntryInfoMessageEvent); + this._events.set(IncomingHeader.ROOM_SCORE, RoomScoreEvent); + this._events.set(IncomingHeader.ROOM_ROLLING, ObjectsRollingEvent); + 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); + 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); + this._events.set(IncomingHeader.FURNITURE_ALIASES, FurnitureAliasesEvent); + this._events.set(IncomingHeader.FURNITURE_DATA, FurnitureDataEvent); + this._events.set(IncomingHeader.FURNITURE_ITEMDATA, ItemDataUpdateMessageEvent); + this._events.set(IncomingHeader.ITEM_STACK_HELPER, FurnitureStackHeightEvent); + this._events.set(IncomingHeader.FURNITURE_STATE, OneWayDoorStatusMessageEvent); + this._events.set(IncomingHeader.ITEM_DIMMER_SETTINGS, RoomDimmerPresetsEvent); + this._events.set(IncomingHeader.FURNITURE_STATE_2, DiceValueMessageEvent); + 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); + this._events.set(IncomingHeader.OBJECTS_DATA_UPDATE, ObjectsDataUpdateEvent); + this._events.set(IncomingHeader.FURNITURE_GROUP_CONTEXT_MENU_INFO, GroupFurniContextMenuInfoMessageEvent); + this._events.set(IncomingHeader.FURNITURE_POSTIT_STICKY_POLE_OPEN, RequestSpamWallPostItMessageEvent); + this._events.set(IncomingHeader.ROOM_SPECTATOR, YouAreSpectatorMessageEvent); + this._events.set(IncomingHeader.CUSTOM_USER_NOTIFICATION, CustomUserNotificationMessageEvent); + this._events.set(IncomingHeader.ROOM_MESSAGE_NOTIFICATION, RoomMessageNotificationMessageEvent); + this._events.set(IncomingHeader.ROOM_POPULAR_TAGS_RESULT, PopularRoomTagsResultEvent); + + // ROOM SETTINGS + this._events.set(IncomingHeader.ROOM_RIGHTS_LIST, FlatControllersEvent); + this._events.set(IncomingHeader.ROOM_RIGHTS_LIST_ADD, FlatControllerAddedEvent); + this._events.set(IncomingHeader.ROOM_RIGHTS_LIST_REMOVE, FlatControllerRemovedEvent); + this._events.set(IncomingHeader.ROOM_BAN_LIST, BannedUsersFromRoomEvent); + + this._events.set(IncomingHeader.ROOM_SETTINGS_SAVE_ERROR, RoomSettingsSaveErrorEvent); + this._events.set(IncomingHeader.ROOM_SETTINGS, RoomSettingsDataEvent); + this._events.set(IncomingHeader.ROOM_SETTINGS_SAVE, RoomSettingsSavedEvent); + this._events.set(IncomingHeader.ROOM_SETTINGS_ERROR, RoomSettingsErrorEvent); + this._events.set(IncomingHeader.SHOW_ENFORCE_ROOM_CATEGORY, ShowEnforceRoomCategoryDialogEvent); + this._events.set(IncomingHeader.ROOM_BAN_REMOVE, UserUnbannedFromRoomEvent); + + this._events.set(IncomingHeader.ROOM_MUTED, MuteAllInRoomEvent); + this._events.set(IncomingHeader.NO_SUCH_FLAT, NoSuchFlatEvent); + + this._events.set(IncomingHeader.FAVORITE_GROUP_UDPATE, FavoriteMembershipUpdateMessageEvent); + + // MAPPING + this._events.set(IncomingHeader.ROOM_MODEL_DOOR, RoomEntryTileMessageEvent); + this._events.set(IncomingHeader.ROOM_HEIGHT_MAP, RoomHeightMapEvent); + this._events.set(IncomingHeader.ROOM_HEIGHT_MAP_UPDATE, RoomHeightMapUpdateEvent); + this._events.set(IncomingHeader.ROOM_MODEL, FloorHeightMapEvent); + this._events.set(IncomingHeader.ROOM_MODEL_NAME, RoomReadyMessageEvent); + this._events.set(IncomingHeader.ROOM_PAINT, RoomPaintEvent); + this._events.set(IncomingHeader.ROOM_THICKNESS, RoomVisualizationSettingsEvent); + this._events.set(IncomingHeader.ROOM_GET_FILTER_WORDS, RoomFilterSettingsMessageEvent); + this._events.set(IncomingHeader.ROOM_MODEL_BLOCKED_TILES, RoomOccupiedTilesMessageEvent); + this._events.set(IncomingHeader.PET_FIGURE_UPDATE, PetFigureUpdateEvent); + this._events.set(IncomingHeader.PET_INFO, PetInfoEvent); + this._events.set(IncomingHeader.PET_STATUS, PetStatusUpdateEvent); + this._events.set(IncomingHeader.PET_EXPERIENCE, PetExperienceEvent); + this._events.set(IncomingHeader.PLAYING_GAME, YouArePlayingGameEvent); + 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); + 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); + + // SECURITY + this._events.set(IncomingHeader.AUTHENTICATED, AuthenticatedEvent); + + // SOUNDS + this._events.set(IncomingHeader.JUKEBOX_PLAYLIST_FULL, JukeboxPlayListFullMessageEvent); + this._events.set(IncomingHeader.JUKEBOX_SONG_DISKS, JukeboxSongDisksMessageEvent); + this._events.set(IncomingHeader.NOW_PLAYING, NowPlayingMessageEvent); + this._events.set(IncomingHeader.OFFICIAL_SONG_ID, OfficialSongIdMessageEvent); + this._events.set(IncomingHeader.PLAYLIST, PlayListMessageEvent); + this._events.set(IncomingHeader.PLAYLIST_SONG_ADDED, PlayListSongAddedMessageEvent); + this._events.set(IncomingHeader.TRAX_SONG_INFO, TraxSongInfoMessageEvent); + this._events.set(IncomingHeader.USER_SONG_DISKS_INVENTORY, UserSongDisksInventoryMessageEvent); + + // TALENT + this._events.set(IncomingHeader.HELPER_TALENT_TRACK, TalentTrackMessageEvent); + this._events.set(IncomingHeader.TALENT_TRACK_LEVEL, TalentTrackLevelMessageEvent); + this._events.set(IncomingHeader.TALENT_TRACK_LEVEL_UP, TalentLevelUpEvent); + + // USER + this._events.set(IncomingHeader.IN_CLIENT_LINK, InClientLinkEvent); + this._events.set(IncomingHeader.USER_IGNORED, IgnoredUsersEvent); + this._events.set(IncomingHeader.USER_IGNORED_RESULT, IgnoreResultEvent); + this._events.set(IncomingHeader.USER_RESPECT, RespectReceivedEvent); + this._events.set(IncomingHeader.USER_PERMISSIONS, UserPermissionsEvent); + this._events.set(IncomingHeader.USER_BADGES_CURRENT, UserCurrentBadgesEvent); + 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, RelationshipStatusInfoEvent); + this._events.set(IncomingHeader.GIFT_OPENED, PresentOpenedMessageEvent); + this._events.set(IncomingHeader.USER_CREDITS, UserCreditsEvent); + this._events.set(IncomingHeader.USER_CURRENCY, UserCurrencyEvent); + this._events.set(IncomingHeader.USER_SUBSCRIPTION, UserSubscriptionEvent); + this._events.set(IncomingHeader.USER_WARDROBE_PAGE, UserWardrobePageEvent); + this._events.set(IncomingHeader.USER_CLASSIFICATION, UserClassificationMessageEvent); + this._events.set(IncomingHeader.GET_USER_TAGS, UserTagsMessageEvent); + this._events.set(IncomingHeader.SCR_SEND_KICKBACK_INFO, ScrSendKickbackInfoMessageEvent); + this._events.set(IncomingHeader.PET_RESPECTED, PetRespectNoficationEvent); + this._events.set(IncomingHeader.PET_SUPPLEMENT, PetSupplementedNotificationEvent); + this._events.set(IncomingHeader.ACCOUNT_SAFETY_LOCK_STATUS_CHANGE, AccountSafetyLockStatusChangeMessageEvent); + + this._events.set(IncomingHeader.GENERIC_ERROR, GenericErrorEvent); + this._events.set(IncomingHeader.GROUP_LIST, GuildMembershipsMessageEvent); + this._events.set(IncomingHeader.CATALOG_APPROVE_NAME_RESULT, ApproveNameMessageEvent); + this._events.set(IncomingHeader.CONNECTION_ERROR, ConnectionErrorEvent); + + // GUILD + this._events.set(IncomingHeader.GUILD_EDIT_FAILED, GuildEditFailedMessageEvent); + this._events.set(IncomingHeader.GUILD_MEMBER_MGMT_FAILED, GuildMemberMgmtFailedMessageEvent); + this._events.set(IncomingHeader.EXTENDED_PROFILE_CHANGED, ExtendedProfileChangedMessageEvent); + + // HANDSHAKE + this._events.set(IncomingHeader.NOOBNESS_LEVEL, NoobnessLevelMessageEvent); + this._events.set(IncomingHeader.DISCONNECT_REASON, DisconnectReasonEvent); + this._events.set(IncomingHeader.HANDSHAKE_INIT_DIFFIE, InitDiffieHandshakeEvent); + this._events.set(IncomingHeader.HANDSHAKE_COMPLETE_DIFFIE, CompleteDiffieHandshakeEvent); + this._events.set(IncomingHeader.HANDSHAKE_IDENTITY_ACCOUNT, IdentityAccountsEvent); + + // NUX + this._events.set(IncomingHeader.NEW_USER_EXPERIENCE_GIFT_OFFER, NewUserExperienceGiftOfferMessageEvent); + this._events.set(IncomingHeader.NEW_USER_EXPERIENCE_NOT_COMPLETE, NewUserExperienceNotCompleteEvent); + + // RESTORE CLIENT + this._events.set(IncomingHeader.RESTORE_CLIENT, RestoreClientMessageEvent); + + // FIREWORK + this._events.set(IncomingHeader.FIREWORK_CHARGE_DATA, FireworkChargeDataEvent); + + // PHONE + this._events.set(IncomingHeader.PHONE_COLLECTION_STATE, PhoneCollectionStateMessageEvent); + this._events.set(IncomingHeader.PHONE_TRY_NUMBER_RESULT, TryPhoneNumberResultMessageEvent); + this._events.set(IncomingHeader.PHONE_TRY_VERIFICATION_CODE_RESULT, TryVerificationCodeResultMessageEvent); + + // WELCOME + this._events.set(IncomingHeader.WELCOME_GIFT_CHANGE_EMAIL_RESULT, WelcomeGiftChangeEmailResultEvent); + this._events.set(IncomingHeader.WELCOME_GIFT_STATUS, WelcomeGiftStatusEvent); + // RENTABLE SPACE + this._events.set(IncomingHeader.RENTABLE_SPACE_RENT_OK, RentableSpaceRentOkMessageEvent); + this._events.set(IncomingHeader.RENTABLE_SPACE_STATUS, RentableSpaceStatusMessageEvent); + this._events.set(IncomingHeader.RENTABLE_SPACE_RENT_FAILED, RentableSpaceRentFailedMessageEvent); + // RECYCLER + this._events.set(IncomingHeader.RECYCLER_STATUS, RecyclerStatusMessageEvent); + this._events.set(IncomingHeader.RECYCLER_FINISHED, RecyclerFinishedMessageEvent); + // EMAIL + this._events.set(IncomingHeader.EMAIL_STATUS, EmailStatusResultEvent); + this._events.set(IncomingHeader.CHANGE_EMAIL_RESULT, ChangeEmailResultEvent); + + // RENTABLE FURNI + this._events.set(IncomingHeader.RENTABLE_FURNI_RENT_OR_BUYOUT_OFFER, FurniRentOrBuyoutOfferMessageEvent); + } + + private registerComposers(): void + { + // AUTHENTICATION + this._composers.set(OutgoingHeader.AUTHENTICATION, AuthenticationMessageComposer); + + // ADVERTISEMENT + this._composers.set(OutgoingHeader.INTERSTITIAL_SHOWN, InterstitialShownMessageComposer); + this._composers.set(OutgoingHeader.GET_INTERSTITIAL, GetInterstitialMessageComposer); + + // AVATAR + this._composers.set(OutgoingHeader.GET_WARDROBE, GetWardrobeMessageComposer); + this._composers.set(OutgoingHeader.SAVE_WARDROBE_OUTFIT, SaveWardrobeOutfitMessageComposer); + this._composers.set(OutgoingHeader.CHANGE_USERNAME, ChangeUserNameMessageComposer); + this._composers.set(OutgoingHeader.CHECK_USERNAME, CheckUserNameMessageComposer); + + // CAMERA + this._composers.set(OutgoingHeader.REQUEST_CAMERA_CONFIGURATION, RequestCameraConfigurationComposer); + this._composers.set(OutgoingHeader.RENDER_ROOM, RenderRoomMessageComposer); + this._composers.set(OutgoingHeader.RENDER_ROOM_THUMBNAIL, RenderRoomThumbnailMessageComposer); + this._composers.set(OutgoingHeader.PURCHASE_PHOTO, PurchasePhotoMessageComposer); + this._composers.set(OutgoingHeader.PUBLISH_PHOTO, PublishPhotoMessageComposer); + this._composers.set(OutgoingHeader.PHOTO_COMPETITION, PhotoCompetitionMessageComposer); + + // CAMPAIGN + this._composers.set(OutgoingHeader.OPEN_CAMPAIGN_CALENDAR_DOOR, OpenCampaignCalendarDoorComposer); + this._composers.set(OutgoingHeader.OPEN_CAMPAIGN_CALENDAR_DOOR_STAFF, OpenCampaignCalendarDoorAsStaffComposer); + + // CATALOG + this._composers.set(OutgoingHeader.BUILDERS_CLUB_PLACE_ROOM_ITEM, BuildersClubPlaceRoomItemMessageComposer); + this._composers.set(OutgoingHeader.BUILDERS_CLUB_PLACE_WALL_ITEM, BuildersClubPlaceWallItemMessageComposer); + this._composers.set(OutgoingHeader.BUILDERS_CLUB_QUERY_FURNI_COUNT, BuildersClubQueryFurniCountMessageComposer); + this._composers.set(OutgoingHeader.GET_CATALOG_INDEX, GetCatalogIndexComposer); + this._composers.set(OutgoingHeader.GET_CATALOG_PAGE, GetCatalogPageComposer); + this._composers.set(OutgoingHeader.CATALOG_PURCHASE, PurchaseFromCatalogComposer); + this._composers.set(OutgoingHeader.CATALOG_PURCHASE_GIFT, PurchaseFromCatalogAsGiftComposer); + this._composers.set(OutgoingHeader.GET_PRODUCT_OFFER, GetProductOfferComposer); + this._composers.set(OutgoingHeader.GET_CLUB_OFFERS, GetClubOffersMessageComposer); + this._composers.set(OutgoingHeader.GET_CLUB_GIFT_INFO, GetClubGiftInfo); + this._composers.set(OutgoingHeader.CATALOG_REDEEM_VOUCHER, RedeemVoucherMessageComposer); + this._composers.set(OutgoingHeader.GROUP_MEMBERSHIPS, CatalogGroupsComposer); + this._composers.set(OutgoingHeader.GET_GIFT_WRAPPING_CONFIG, GetGiftWrappingConfigurationComposer); + this._composers.set(OutgoingHeader.CATALOG_SELECT_VIP_GIFT, SelectClubGiftComposer); + this._composers.set(OutgoingHeader.CATALOG_REQUESET_PET_BREEDS, GetSellablePetPalettesComposer); + this._composers.set(OutgoingHeader.GET_BONUS_RARE_INFO, GetBonusRareInfoMessageComposer); + this._composers.set(OutgoingHeader.GET_BUNDLE_DISCOUNT_RULESET, GetBundleDiscountRulesetComposer); + this._composers.set(OutgoingHeader.GET_CATALOG_PAGE_EXPIRATION, GetCatalogPageExpirationComposer); + this._composers.set(OutgoingHeader.GET_CATALOG_PAGE_WITH_EARLIEST_EXP, GetCatalogPageWithEarliestExpiryComposer); + this._composers.set(OutgoingHeader.GET_DIRECT_CLUB_BUY_AVAILABLE, GetDirectClubBuyAvailableComposer); + this._composers.set(OutgoingHeader.GET_HABBO_BASIC_MEMBERSHIP_EXTEND_OFFER, GetHabboBasicMembershipExtendOfferComposer); + this._composers.set(OutgoingHeader.GET_HABBO_CLUB_EXTEND_OFFER, GetHabboClubExtendOfferMessageComposer); + this._composers.set(OutgoingHeader.GET_IS_OFFER_GIFTABLE, GetIsOfferGiftableComposer); + this._composers.set(OutgoingHeader.GET_LIMITED_OFFER_APPEARING_NEXT, GetLimitedOfferAppearingNextComposer); + this._composers.set(OutgoingHeader.GET_NEXT_TARGETED_OFFER, GetNextTargetedOfferComposer); + this._composers.set(OutgoingHeader.GET_ROOM_AD_PURCHASE_INFO, GetRoomAdPurchaseInfoComposer); + this._composers.set(OutgoingHeader.GET_SEASONAL_CALENDAR_DAILY_OFFER, GetSeasonalCalendarDailyOfferComposer); + this._composers.set(OutgoingHeader.GET_TARGETED_OFFER, GetTargetedOfferComposer); + this._composers.set(OutgoingHeader.MARK_CATALOG_NEW_ADDITIONS_PAGE_OPENED, MarkCatalogNewAdditionsPageOpenedComposer); + this._composers.set(OutgoingHeader.PURCHASE_BASIC_MEMBERSHIP_EXTENSION, PurchaseBasicMembershipExtensionComposer); + this._composers.set(OutgoingHeader.PURCHASE_ROOM_AD, PurchaseRoomAdMessageComposer); + this._composers.set(OutgoingHeader.PURCHASE_TARGETED_OFFER, PurchaseTargetedOfferComposer); + this._composers.set(OutgoingHeader.PURCHASE_VIP_MEMBERSHIP_EXTENSION, PurchaseVipMembershipExtensionComposer); + this._composers.set(OutgoingHeader.ROOM_AD_PURCHASE_INITIATED, RoomAdPurchaseInitiatedComposer); + this._composers.set(OutgoingHeader.SET_TARGETTED_OFFER_STATE, SetTargetedOfferStateComposer); + this._composers.set(OutgoingHeader.SHOP_TARGETED_OFFER_VIEWED, ShopTargetedOfferViewedComposer); + + // COMPETITION + this._composers.set(OutgoingHeader.FORWARD_TO_A_COMPETITION_ROOM, ForwardToACompetitionRoomMessageComposer); + this._composers.set(OutgoingHeader.FORWARD_TO_A_SUBMITTABLE_ROOM, ForwardToASubmittableRoomMessageComposer); + this._composers.set(OutgoingHeader.FORWARD_TO_RANDOM_COMPETITION_ROOM, ForwardToRandomCompetitionRoomMessageComposer); + this._composers.set(OutgoingHeader.GET_CURRENT_TIMING_CODE, GetCurrentTimingCodeMessageComposer); + this._composers.set(OutgoingHeader.GET_IS_USER_PART_OF_COMPETITION, GetIsUserPartOfCompetitionMessageComposer); + this._composers.set(OutgoingHeader.GET_SECONDS_UNTIL, GetSecondsUntilMessageComposer); + this._composers.set(OutgoingHeader.ROOM_COMPETITION_INIT, RoomCompetitionInitMessageComposer); + this._composers.set(OutgoingHeader.SUBMIT_ROOM_TO_COMPETITION, SubmitRoomToCompetitionMessageComposer); + this._composers.set(OutgoingHeader.VOTE_FOR_ROOM, VoteForRoomMessageComposer); + + // CRAFTING + this._composers.set(OutgoingHeader.CRAFT, CraftComposer); + this._composers.set(OutgoingHeader.CRAFT_SECRET, CraftSecretComposer); + this._composers.set(OutgoingHeader.GET_CRAFTABLE_PRODUCTS, GetCraftingRecipeComposer); + this._composers.set(OutgoingHeader.GET_CRAFTING_RECIPE, GetCraftableProductsComposer); + this._composers.set(OutgoingHeader.GET_CRAFTING_RECIPES_AVAILABLE, GetCraftingRecipesAvailableComposer); + + // FRIENDFURNI + this._composers.set(OutgoingHeader.FRIEND_FURNI_CONFIRM_LOCK, FriendFurniConfirmLockMessageComposer); + + // FRIENDLIST + this._composers.set(OutgoingHeader.ACCEPT_FRIEND, AcceptFriendMessageComposer); + this._composers.set(OutgoingHeader.DECLINE_FRIEND, DeclineFriendMessageComposer); + this._composers.set(OutgoingHeader.FIND_NEW_FRIENDS, FindNewFriendsMessageComposer); + this._composers.set(OutgoingHeader.FOLLOW_FRIEND, FollowFriendMessageComposer); + this._composers.set(OutgoingHeader.FRIEND_LIST_UPDATE, FriendListUpdateComposer); + this._composers.set(OutgoingHeader.GET_FRIEND_REQUESTS, GetFriendRequestsComposer); + this._composers.set(OutgoingHeader.HABBO_SEARCH, HabboSearchComposer); + this._composers.set(OutgoingHeader.MESSENGER_INIT, MessengerInitComposer); + this._composers.set(OutgoingHeader.REMOVE_FRIEND, RemoveFriendComposer); + this._composers.set(OutgoingHeader.REQUEST_FRIEND, RequestFriendComposer); + this._composers.set(OutgoingHeader.MESSENGER_CHAT, SendMessageComposer); + this._composers.set(OutgoingHeader.SEND_ROOM_INVITE, SendRoomInviteComposer); + this._composers.set(OutgoingHeader.SET_RELATIONSHIP_STATUS, SetRelationshipStatusComposer); + this._composers.set(OutgoingHeader.VISIT_USER, VisitUserComposer); + + // GAME + this._composers.set(OutgoingHeader.ACHIEVEMENT_RESOLUTION_OPEN, GetResolutionAchievementsMessageComposer); + this._composers.set(OutgoingHeader.ACCEPTGAMEINVITE, AcceptGameInviteMessageComposer); + this._composers.set(OutgoingHeader.GAMEUNLOADEDMESSAGE, GameUnloadedMessageComposer); + this._composers.set(OutgoingHeader.GETGAMEACHIEVEMENTSMESSAGE, GetGameAchievementsMessageComposer); + this._composers.set(OutgoingHeader.GAMES_LIST, GetGameListMessageComposer); + this._composers.set(OutgoingHeader.GETGAMESTATUSMESSAGE, GetGameStatusMessageComposer); + this._composers.set(OutgoingHeader.GETUSERGAMEACHIEVEMENTSMESSAGE, GetUserGameAchievementsMessageComposer); + this._composers.set(OutgoingHeader.JOINQUEUEMESSAGE, JoinQueueMessageComposer); + this._composers.set(OutgoingHeader.LEAVEQUEUEMESSAGE, LeaveQueueMessageComposer); + this._composers.set(OutgoingHeader.RESETRESOLUTIONACHIEVEMENTMESSAGE, ResetResolutionAchievementMessageComposer); + this._composers.set(OutgoingHeader.GAMES_INIT, GetWeeklyGameRewardComposer); + this._composers.set(OutgoingHeader.GETWEEKLYGAMEREWARDWINNERS, GetWeeklyGameRewardWinnersComposer); + this._composers.set(OutgoingHeader.GAME2GETACCOUNTGAMESTATUSMESSAGE, Game2GetAccountGameStatusMessageComposer); + this._composers.set(OutgoingHeader.GAME2CHECKGAMEDIRECTORYSTATUSMESSAGE, Game2CheckGameDirectoryStatusMessageComposer); + this._composers.set(OutgoingHeader.GAME2EXITGAMEMESSAGE, Game2ExitGameMessageComposer); + this._composers.set(OutgoingHeader.GAME2GAMECHATMESSAGE, Game2GameChatMessageComposer); + this._composers.set(OutgoingHeader.GAME2LOADSTAGEREADYMESSAGE, Game2LoadStageReadyMessageComposer); + this._composers.set(OutgoingHeader.GAME2PLAYAGAINMESSAGE, Game2PlayAgainMessageComposer); + this._composers.set(OutgoingHeader.GAME2REQUESTFULLSTATUSUPDATEMESSAGE, Game2RequestFullStatusUpdateMessageComposer); + this._composers.set(OutgoingHeader.GAME2GETWEEKLYFRIENDSLEADERBOARD, Game2GetWeeklyFriendsLeaderboardComposer); + this._composers.set(OutgoingHeader.GAME2GETWEEKLYLEADERBOARD, Game2GetWeeklyLeaderboardComposer); + + // GIFTS + this._composers.set(OutgoingHeader.GET_GIFT, GetGiftMessageComposer); + this._composers.set(OutgoingHeader.RESET_PHONE_NUMBER_STATE, ResetPhoneNumberStateMessageComposer); + this._composers.set(OutgoingHeader.SET_PHONE_NUMBER_VERIFICATION_STATUS, SetPhoneNumberVerificationStatusMessageComposer); + this._composers.set(OutgoingHeader.TRY_PHONE_NUMBER, TryPhoneNumberMessageComposer); + this._composers.set(OutgoingHeader.VERIFY_CODE, VerifyCodeMessageComposer); + + // GROUPFORUMS + this._composers.set(OutgoingHeader.GET_FORUM_STATS, GetForumStatsMessageComposer); + this._composers.set(OutgoingHeader.GET_FORUMS_LIST, GetForumsListMessageComposer); + this._composers.set(OutgoingHeader.GET_FORUM_MESSAGES, GetMessagesMessageComposer); + this._composers.set(OutgoingHeader.GET_FORUM_THREAD, GetThreadMessageComposer); + this._composers.set(OutgoingHeader.GET_FORUM_THREADS, GetThreadsMessageComposer); + this._composers.set(OutgoingHeader.GET_UNREAD_FORUMS_COUNT, GetUnreadForumsCountMessageComposer); + this._composers.set(OutgoingHeader.FORUM_MODERATE_MESSAGE, ModerateMessageMessageComposer); + this._composers.set(OutgoingHeader.FORUM_MODERATE_THREAD, ModerateThreadMessageComposer); + this._composers.set(OutgoingHeader.FORUM_POST_MESSAGE, PostMessageMessageComposer); + this._composers.set(OutgoingHeader.UPDATE_FORUM_READ_MARKER, UpdateForumReadMarkerMessageComposer); + this._composers.set(OutgoingHeader.UPDATE_FORUM_SETTINGS, UpdateForumSettingsMessageComposer); + this._composers.set(OutgoingHeader.FORUM_UPDATE_THREAD, UpdateThreadMessageComposer); + + // HANDSHAKE + this._composers.set(OutgoingHeader.CLIENT_PONG, PongMessageComposer); + this._composers.set(OutgoingHeader.RELEASE_VERSION, ClientHelloMessageComposer); + this._composers.set(OutgoingHeader.SECURITY_TICKET, SSOTicketMessageComposer); + this._composers.set(OutgoingHeader.USER_INFO, InfoRetrieveMessageComposer); + this._composers.set(OutgoingHeader.DISCONNECT, DisconnectMessageComposer); + this._composers.set(OutgoingHeader.SECURITY_MACHINE, UniqueIDMessageComposer); + this._composers.set(OutgoingHeader.CLIENT_VARIABLES, VersionCheckMessageComposer); + this._composers.set(OutgoingHeader.HANDSHAKE_INIT_DIFFIE, InitDiffieHandshakeMessageComposer); + this._composers.set(OutgoingHeader.HANDSHAKE_COMPLETE_DIFFIE, CompleteDiffieHandshakeMessageComposer); + + // HELP + this._composers.set(OutgoingHeader.CALL_FOR_HELP_FROM_FORUM_MESSAGE, CallForHelpFromForumMessageMessageComposer); + this._composers.set(OutgoingHeader.CALL_FOR_HELP_FROM_FORUM_THREAD, CallForHelpFromForumThreadMessageComposer); + this._composers.set(OutgoingHeader.CALL_FOR_HELP_FROM_IM, CallForHelpFromIMMessageComposer); + this._composers.set(OutgoingHeader.CALL_FOR_HELP_FROM_PHOTO, CallForHelpFromPhotoMessageComposer); + this._composers.set(OutgoingHeader.CALL_FOR_HELP_FROM_SELFIE, CallForHelpFromSelfieMessageComposer); + this._composers.set(OutgoingHeader.CALL_FOR_HELP, CallForHelpMessageComposer); + this._composers.set(OutgoingHeader.CHAT_REVIEW_GUIDE_DECIDES, ChatReviewGuideDecidesOnOfferMessageComposer); + this._composers.set(OutgoingHeader.CHAT_REVIEW_GUIDE_DETACHED, ChatReviewGuideDetachedMessageComposer); + this._composers.set(OutgoingHeader.CHAT_REVIEW_GUIDE_VOTE, ChatReviewGuideVoteMessageComposer); + this._composers.set(OutgoingHeader.CHAT_REVIEW_SESSION_CREATE, ChatReviewSessionCreateMessageComposer); + this._composers.set(OutgoingHeader.DELETE_PENDING_CALLS_FOR_HELP, DeletePendingCallsForHelpMessageComposer); + this._composers.set(OutgoingHeader.GET_CFH_STATUS, GetCfhStatusMessageComposer); + this._composers.set(OutgoingHeader.GET_FAQ_CATEGORY, GetFaqCategoryMessageComposer); + this._composers.set(OutgoingHeader.GET_FAQ_TEXT, GetFaqTextMessageComposer); + this._composers.set(OutgoingHeader.GET_GUIDE_REPORTING_STATUS, GetGuideReportingStatusMessageComposer); + this._composers.set(OutgoingHeader.GET_PENDING_CALLS_FOR_HELP, GetPendingCallsForHelpMessageComposer); + this._composers.set(OutgoingHeader.GET_QUIZ_QUESTIONS, GetQuizQuestionsComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_CREATE, GuideSessionCreateMessageComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_FEEDBACK, GuideSessionFeedbackMessageComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_GET_REQUESTER_ROOM, GuideSessionGetRequesterRoomMessageComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_GUIDE_DECIDES, GuideSessionGuideDecidesMessageComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_INVITE_REQUESTER, GuideSessionInviteRequesterMessageComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_IS_TYPING, GuideSessionIsTypingMessageComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_MESSAGE, GuideSessionMessageMessageComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_ON_DUTY_UPDATE, GuideSessionOnDutyUpdateMessageComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_REPORT, GuideSessionReportMessageComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_REQUESTER_CANCELS, GuideSessionRequesterCancelsMessageComposer); + this._composers.set(OutgoingHeader.GUIDE_SESSION_RESOLVED, GuideSessionResolvedMessageComposer); + this._composers.set(OutgoingHeader.POST_QUIZ_ANSWERS, PostQuizAnswersComposer); + this._composers.set(OutgoingHeader.SEARCH_FAQS, SearchFaqsMessageComposer); + + // DESKTOP + this._composers.set(OutgoingHeader.DESKTOP_VIEW, DesktopViewComposer); + + // 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); + this._composers.set(OutgoingHeader.GROUP_FAVORITE, GroupFavoriteComposer); + this._composers.set(OutgoingHeader.GROUP_UNFAVORITE, GroupUnfavoriteComposer); + this._composers.set(OutgoingHeader.GROUP_BADGES, GetHabboGroupBadgesMessageComposer); + this._composers.set(OutgoingHeader.APPROVE_ALL_MEMBERSHIP_REQUESTS, ApproveAllMembershipRequestsMessageComposer); + this._composers.set(OutgoingHeader.GROUP_UNBLOCK_MEMBER, UnblockGroupMemberMessageComposer); + + // NAVIGATOR + this._composers.set(OutgoingHeader.ROOM_FAVORITE, AddFavouriteRoomMessageComposer); + this._composers.set(OutgoingHeader.CAN_CREATE_ROOM, CanCreateRoomMessageComposer); + this._composers.set(OutgoingHeader.CANCEL_ROOM_EVENT, CancelEventMessageComposer); + this._composers.set(OutgoingHeader.CONVERT_GLOBAL_ROOM_ID, ConvertGlobalRoomIdMessageComposer); + this._composers.set(OutgoingHeader.COMPETITION_ROOM_SEARCH, CompetitionRoomsSearchMessageComposer); + this._composers.set(OutgoingHeader.ROOM_CREATE, CreateFlatMessageComposer); + this._composers.set(OutgoingHeader.GET_USER_FLAT_CATS, GetUserFlatCatsMessageComposer); + this._composers.set(OutgoingHeader.GET_USER_EVENT_CATS, GetUserEventCatsMessageComposer); + this._composers.set(OutgoingHeader.ROOM_FAVORITE_REMOVE, DeleteFavouriteRoomMessageComposer); + this._composers.set(OutgoingHeader.EDIT_ROOM_EVENT, EditEventMessageComposer); + this._composers.set(OutgoingHeader.FORWARD_TO_RANDOM_PROMOTED_ROOM, ForwardToARandomPromotedRoomMessageComposer); + this._composers.set(OutgoingHeader.FORWARD_TO_SOME_ROOM, ForwardToSomeRoomMessageComposer); + this._composers.set(OutgoingHeader.GET_CATEGORIES_WITH_USER_COUNT, GetCategoriesWithUserCountMessageComposer); + this._composers.set(OutgoingHeader.GET_GUEST_ROOM, GetGuestRoomMessageComposer); + this._composers.set(OutgoingHeader.GET_OFFICIAL_ROOMS, GetOfficialRoomsMessageComposer); + this._composers.set(OutgoingHeader.GET_POPULAR_ROOM_TAGS, GetPopularRoomTagsMessageComposer); + this._composers.set(OutgoingHeader.GUILD_BASE_SEARCH, GuildBaseSearchMessageComposer); + this._composers.set(OutgoingHeader.MY_FAVOURITE_ROOMS_SEARCH, MyFavouriteRoomsSearchMessageComposer); + this._composers.set(OutgoingHeader.MY_FREQUENT_ROOM_HISTORY_SEARCH, MyFrequentRoomHistorySearchMessageComposer); + this._composers.set(OutgoingHeader.MY_FRIENDS_ROOM_SEARCH, MyFriendsRoomsSearchMessageComposer); + this._composers.set(OutgoingHeader.MY_GUILD_BASES_SEARCH, MyGuildBasesSearchMessageComposer); + this._composers.set(OutgoingHeader.MY_RECOMMENDED_ROOMS, MyRecommendedRoomsMessageComposer); + this._composers.set(OutgoingHeader.MY_ROOM_HISTORY_SEARCH, MyRoomHistorySearchMessageComposer); + this._composers.set(OutgoingHeader.MY_ROOM_RIGHTS_SEARCH, MyRoomRightsSearchMessageComposer); + this._composers.set(OutgoingHeader.MY_ROOMS_SEARCH, MyRoomsSearchMessageComposer); + this._composers.set(OutgoingHeader.POPULAR_ROOMS_SEARCH, PopularRoomsSearchMessageComposer); + this._composers.set(OutgoingHeader.ROOM_LIKE, RateFlatMessageComposer); + this._composers.set(OutgoingHeader.ROOM_RIGHTS_REMOVE_OWN, RemoveOwnRoomRightsRoomMessageComposer); + this._composers.set(OutgoingHeader.ROOM_AD_EVENT_TAB_CLICKED, RoomAdEventTabAdClickedComposer); + this._composers.set(OutgoingHeader.ROOM_AD_EVENT_TAB_VIEWED, RoomAdEventTabViewedComposer); + this._composers.set(OutgoingHeader.ROOM_AD_SEARCH, RoomAdSearchMessageComposer); + this._composers.set(OutgoingHeader.ROOM_TEXT_SEARCH, RoomTextSearchMessageComposer); + this._composers.set(OutgoingHeader.ROOMS_WHERE_MY_FRIENDS_ARE, RoomsWhereMyFriendsAreSearchMessageComposer); + this._composers.set(OutgoingHeader.ROOMS_WITH_HIGHEST_SCORE_SEARCH, RoomsWithHighestScoreSearchMessageComposer); + this._composers.set(OutgoingHeader.SET_ROOM_SESSION_TAGS, SetRoomSessionTagsMessageComposer); + this._composers.set(OutgoingHeader.ROOM_STAFF_PICK, ToggleStaffPickMessageComposer); + this._composers.set(OutgoingHeader.ROOM_FILTER_WORDS, GetCustomRoomFilterMessageComposer); + this._composers.set(OutgoingHeader.ROOM_FILTER_WORDS_MODIFY, UpdateRoomFilterMessageComposer); + this._composers.set(OutgoingHeader.USER_HOME_ROOM, UpdateHomeRoomMessageComposer); + this._composers.set(OutgoingHeader.UPDATE_ROOM_THUMBNAIL, UpdateRoomThumbnailMessageComposer); + // NEW NAVIGATOR + 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_SAVE, NavigatorSettingsSaveComposer); + this._composers.set(OutgoingHeader.NAVIGATOR_CATEGORY_LIST_MODE, NavigatorCategoryListModeComposer); + this._composers.set(OutgoingHeader.NAVIGATOR_DELETE_SAVED_SEARCH, NavigatorDeleteSavedSearchComposer); + + // POLL + this._composers.set(OutgoingHeader.POLL_ANSWER, PollAnswerComposer); + this._composers.set(OutgoingHeader.POLL_REJECT, PollRejectComposer); + this._composers.set(OutgoingHeader.POLL_START, PollStartComposer); + this._composers.set(OutgoingHeader.POLL_VOTE_COUNTER, VotePollCounterMessageComposer); + + // INVENTORY + + // EFFECTS + this._composers.set(OutgoingHeader.USER_EFFECT_ACTIVATE, AvatarEffectActivatedComposer); + this._composers.set(OutgoingHeader.USER_EFFECT_ENABLE, AvatarEffectSelectedComposer); + + // BADGES + this._composers.set(OutgoingHeader.USER_BADGES, RequestBadgesComposer); + this._composers.set(OutgoingHeader.USER_BADGES_CURRENT_UPDATE, SetActivatedBadgesComposer); + this._composers.set(OutgoingHeader.GET_BADGE_POINTS_LIMITS, GetBadgePointLimitsComposer); + this._composers.set(OutgoingHeader.REQUESTABADGE, RequestABadgeComposer); + this._composers.set(OutgoingHeader.GETISBADGEREQUESTFULFILLED, GetIsBadgeRequestFulfilledComposer); + + // BOTS + this._composers.set(OutgoingHeader.USER_BOTS, GetBotInventoryComposer); + + // FURNI + this._composers.set(OutgoingHeader.USER_FURNITURE, FurnitureListComposer); + this._composers.set(OutgoingHeader.REQUESTFURNIINVENTORYWHENNOTINROOM, RequestFurniInventoryWhenNotInRoomComposer); + + // PETS + this._composers.set(OutgoingHeader.USER_PETS, RequestPetsComposer); + + // 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); + + // UNSEEN + this._composers.set(OutgoingHeader.UNSEEN_RESET_CATEGORY, UnseenResetCategoryComposer); + this._composers.set(OutgoingHeader.UNSEEN_RESET_ITEMS, UnseenResetItemsComposer); + + // ACHIVEMENTS + this._composers.set(OutgoingHeader.ACHIEVEMENT_LIST, RequestAchievementsMessageComposer); + + // PET + this._composers.set(OutgoingHeader.PET_MOUNT, PetMountComposer); + this._composers.set(OutgoingHeader.PET_RESPECT, PetRespectComposer); + this._composers.set(OutgoingHeader.PET_SUPPLEMENT, PetSupplementComposer); + this._composers.set(OutgoingHeader.REMOVE_PET_SADDLE, RemovePetSaddleComposer); + this._composers.set(OutgoingHeader.PET_INFO, RequestPetInfoComposer); + this._composers.set(OutgoingHeader.TOGGLE_PET_BREEDING, TogglePetBreedingComposer); + this._composers.set(OutgoingHeader.TOGGLE_PET_RIDING, TogglePetRidingComposer); + this._composers.set(OutgoingHeader.USE_PET_PRODUCT, UsePetProductComposer); + this._composers.set(OutgoingHeader.GET_PET_TRAINING_PANEL, GetPetCommandsComposer); + this._composers.set(OutgoingHeader.PET_OPEN_PACKAGE, OpenPetPackageMessageComposer); + this._composers.set(OutgoingHeader.PET_SELECTED, PetSelectedMessageComposer); + this._composers.set(OutgoingHeader.PETS_BREED, BreedPetsMessageComposer); + this._composers.set(OutgoingHeader.PET_CANCEL_BREEDING, CancelPetBreedingComposer); + this._composers.set(OutgoingHeader.PET_CONFIRM_BREEDING, ConfirmPetBreedingComposer); + + // ROOM + + // ACCESS + this._composers.set(OutgoingHeader.ROOM_ENTER, RoomEnterComposer); + this._composers.set(OutgoingHeader.ROOM_DOORBELL, RoomDoorbellAccessComposer); + this._composers.set(OutgoingHeader.GO_TO_FLAT, GoToFlatMessageComposer); + this._composers.set(OutgoingHeader.CHANGE_QUEUE, ChangeQueueMessageComposer); + + // 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_RIGHTS_REMOVE_ALL, RemoveAllRightsMessageComposer); + + this._composers.set(OutgoingHeader.ROOM_DELETE, RoomDeleteComposer); + + // DATA + 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); + this._composers.set(OutgoingHeader.ROOM_SETTINGS_UPDATE_ROOM_CATEGORY_AND_TRADE, UpdateRoomCategoryAndTradeSettingsComposer); + + // 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.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); + this._composers.set(OutgoingHeader.SET_ITEM_DATA, SetItemDataMessageComposer); + this._composers.set(OutgoingHeader.SET_OBJECT_DATA, SetObjectDataMessageComposer); + this._composers.set(OutgoingHeader.COMPOST_PLANT, CompostPlantMessageComposer); + this._composers.set(OutgoingHeader.HARVEST_PET, HarvestPetMessageComposer); + this._composers.set(OutgoingHeader.SET_CLOTHING_CHANGE_DATA, SetClothingChangeDataMessageComposer); + + // FURNITURE + this._composers.set(OutgoingHeader.FURNITURE_ALIASES, FurnitureAliasesComposer); + this._composers.set(OutgoingHeader.FURNITURE_GROUP_INFO, FurnitureGroupInfoComposer); + 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); + this._composers.set(OutgoingHeader.FURNITURE_POSTIT_SAVE_STICKY_POLE, AddSpamWallPostItMessageComposer); + this._composers.set(OutgoingHeader.CONTROL_YOUTUBE_DISPLAY_PLAYBACK, ControlYoutubeDisplayPlaybackMessageComposer); + this._composers.set(OutgoingHeader.GET_YOUTUBE_DISPLAY_STATUS, GetYoutubeDisplayStatusMessageComposer); + this._composers.set(OutgoingHeader.SET_YOUTUBE_DISPLAY_PLAYLIST, SetYoutubeDisplayPlaylistMessageComposer); + + // 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); + + // LAYOUT + this._composers.set(OutgoingHeader.ROOM_MODEL, GetRoomEntryDataMessageComposer); + this._composers.set(OutgoingHeader.GET_OCCUPIED_TILES, GetOccupiedTilesMessageComposer); + this._composers.set(OutgoingHeader.GET_ROOM_ENTRY_TILE, GetRoomEntryTileMessageComposer); + this._composers.set(OutgoingHeader.ROOM_MODEL_SAVE, UpdateFloorPropertiesMessageComposer); + + // 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_GIVE_HANDITEM_PET, RoomUnitGiveHandItemPetComposer); + 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.APPROVE_NAME, ApproveNameMessageComposer); + this._composers.set(OutgoingHeader.USER_RESPECT, UserRespectComposer); + this._composers.set(OutgoingHeader.SCR_GET_KICKBACK_INFO, ScrGetKickbackInfoMessageComposer); + + // USER CLASSIFICATION + this._composers.set(OutgoingHeader.PEER_USERS_CLASSIFICATION, PeerUsersClassificationMessageComposer); + this._composers.set(OutgoingHeader.USER_CLASSIFICATION, RoomUsersClassificationMessageComposer); + + // 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_MOTTO, UserMottoComposer); + this._composers.set(OutgoingHeader.USER_PROFILE, UserProfileComposer); + this._composers.set(OutgoingHeader.USER_PROFILE_BY_NAME, GetExtendedProfileByNameMessageComposer); + this._composers.set(OutgoingHeader.USER_TAGS, GetUserTagsComposer); + 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 + + // MARKETPLACE + this._composers.set(OutgoingHeader.MARKETPLACE_CONFIG, GetMarketplaceConfigurationMessageComposer); + this._composers.set(OutgoingHeader.MARKETPLACE_SELL_ITEM, MakeOfferMessageComposer); + this._composers.set(OutgoingHeader.MARKETPLACE_REQUEST_OWN_ITEMS, GetMarketplaceOwnOffersMessageComposer); + this._composers.set(OutgoingHeader.MARKETPLACE_TAKE_BACK_ITEM, CancelMarketplaceOfferMessageComposer); + this._composers.set(OutgoingHeader.MARKETPLACE_REQUEST_OFFERS, GetMarketplaceOffersMessageComposer); + this._composers.set(OutgoingHeader.MARKETPLACE_BUY_OFFER, BuyMarketplaceOfferMessageComposer); + this._composers.set(OutgoingHeader.MARKETPLACE_REDEEM_CREDITS, RedeemMarketplaceOfferCreditsMessageComposer); + this._composers.set(OutgoingHeader.MARKETPLACE_BUY_TOKENS, BuyMarketplaceTokensMessageComposer); + this._composers.set(OutgoingHeader.REQUEST_SELL_ITEM, GetMarketplaceCanMakeOfferComposer); + this._composers.set(OutgoingHeader.REQUEST_MARKETPLACE_ITEM_STATS, GetMarketplaceItemStatsComposer); + + // BOTS + this._composers.set(OutgoingHeader.USER_BOTS, GetBotInventoryComposer); + + // PETS + this._composers.set(OutgoingHeader.USER_PETS, RequestPetsComposer); + + // CURRENCY + this._composers.set(OutgoingHeader.USER_CURRENCY, UserCurrencyComposer); + + // SUBSCRIPTION + this._composers.set(OutgoingHeader.USER_SUBSCRIPTION, UserSubscriptionComposer); + + // MODERATION + this._composers.set(OutgoingHeader.MODTOOL_REQUEST_ROOM_INFO, GetModeratorRoomInfoMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_CHANGE_ROOM_SETTINGS, ModerateRoomMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_REQUEST_USER_CHATLOG, GetUserChatlogMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_REQUEST_ROOM_CHATLOG, GetRoomChatlogMessageComposer); + this._composers.set(OutgoingHeader.MOD_TOOL_USER_INFO, GetModeratorUserInfoMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION_ALERT, ModAlertMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION_BAN, ModBanMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION_KICK, ModKickMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION_TRADELOCK, ModTradingLockMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_ALERTEVENT, ModMessageMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION_MUTE, ModMuteMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_REQUEST_USER_ROOMS, GetRoomVisitsMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_ROOM_ALERT, ModeratorActionMessageComposer); + this._composers.set(OutgoingHeader.CLOSE_ISSUE_DEFAULT_ACTION, CloseIssueDefaultActionMessageComposer); + this._composers.set(OutgoingHeader.CLOSE_ISSUES, CloseIssuesMessageComposer); + this._composers.set(OutgoingHeader.DEFAULT_SANCTION, DefaultSanctionMessageComposer); + this._composers.set(OutgoingHeader.GET_CFH_CHATLOG, GetCfhChatlogMessageComposer); + this._composers.set(OutgoingHeader.MODTOOL_PREFERENCES, ModToolPreferencesComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION, ModToolSanctionComposer); + this._composers.set(OutgoingHeader.PICK_ISSUES, PickIssuesMessageComposer); + this._composers.set(OutgoingHeader.RELEASE_ISSUES, ReleaseIssuesMessageComposer); + + // MYSTERYBOX + this._composers.set(OutgoingHeader.MYSTERYBOXWAITINGCANCELEDMESSAGE, MysteryBoxWaitingCanceledMessageComposer); + this._composers.set(OutgoingHeader.MYSTERYBOX_OPEN_TROPHY, OpenMysteryTrophyMessageComposer); + + // 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); + + // LANDING VIEW + this._composers.set(OutgoingHeader.COMMUNITY_GOAL_VOTE_COMPOSER, CommunityGoalVoteMessageComposer); + this._composers.set(OutgoingHeader.GET_PROMO_ARTICLES, GetPromoArticlesComposer); + + // QUEST + this._composers.set(OutgoingHeader.ACCEPT_QUEST, AcceptQuestMessageComposer); + this._composers.set(OutgoingHeader.ACTIVATE_QUEST, ActivateQuestMessageComposer); + this._composers.set(OutgoingHeader.CANCEL_QUEST, CancelQuestMessageComposer); + this._composers.set(OutgoingHeader.FRIEND_REQUEST_QUEST_COMPLETE, FriendRequestQuestCompleteMessageComposer); + this._composers.set(OutgoingHeader.GET_COMMUNITY_GOAL_EARNED_PRIZES, GetCommunityGoalEarnedPrizesMessageComposer); + this._composers.set(OutgoingHeader.GET_COMMUNITY_GOAL_HALL_OF_FAME, GetCommunityGoalHallOfFameMessageComposer); + this._composers.set(OutgoingHeader.GET_COMMUNITY_GOAL_PROGRESS, GetCommunityGoalProgressMessageComposer); + this._composers.set(OutgoingHeader.GET_CONCURRENT_USERS_GOAL_PROGRESS, GetConcurrentUsersGoalProgressMessageComposer); + this._composers.set(OutgoingHeader.GET_CONCURRENT_USERS_REWARD, GetConcurrentUsersRewardMessageComposer); + this._composers.set(OutgoingHeader.GET_DAILY_QUEST, GetDailyQuestMessageComposer); + this._composers.set(OutgoingHeader.GET_QUESTS, GetQuestsMessageComposer); + this._composers.set(OutgoingHeader.GET_SEASONAL_QUESTS_ONLY, GetSeasonalQuestsOnlyMessageComposer); + this._composers.set(OutgoingHeader.OPEN_QUEST_TRACKER, OpenQuestTrackerMessageComposer); + this._composers.set(OutgoingHeader.REDEEM_COMMUNITY_GOAL_PRIZE, RedeemCommunityGoalPrizeMessageComposer); + this._composers.set(OutgoingHeader.REJECT_QUEST, RejectQuestMessageComposer); + this._composers.set(OutgoingHeader.START_CAMPAIGN, StartCampaignMessageComposer); + + // SOUNDS + this._composers.set(OutgoingHeader.GET_SOUND_SETTINGS, GetSoundSettingsComposer); + this._composers.set(OutgoingHeader.ADD_JUKEBOX_DISK, AddJukeboxDiskComposer); + this._composers.set(OutgoingHeader.GET_JUKEBOX_PLAYLIST, GetJukeboxPlayListMessageComposer); + this._composers.set(OutgoingHeader.GET_NOW_PLAYING, GetNowPlayingMessageComposer); + this._composers.set(OutgoingHeader.GET_OFFICIAL_SONG_ID, GetOfficialSongIdMessageComposer); + this._composers.set(OutgoingHeader.GET_SONG_INFO, GetSongInfoMessageComposer); + this._composers.set(OutgoingHeader.GET_SOUND_MACHINE_PLAYLIST, GetSoundMachinePlayListMessageComposer); + this._composers.set(OutgoingHeader.GET_USER_SONG_DISKS, GetUserSongDisksMessageComposer); + this._composers.set(OutgoingHeader.REMOVE_JUKEBOX_DISK, RemoveJukeboxDiskComposer); + + // TALENT + this._composers.set(OutgoingHeader.HELPER_TALENT_TRACK, TalentTrackComposer); + this._composers.set(OutgoingHeader.TALENT_TRACK_GET_LEVEL, GetTalentTrackLevelMessageComposer); + + //NUX + this._composers.set(OutgoingHeader.NEW_USER_EXPERIENCE_GET_GIFTS, NewUserExperienceGetGiftsComposer); + this._composers.set(OutgoingHeader.NEW_USER_EXPERIENCE_SCRIPT_PROCEED, NewUserExperienceScriptProceedComposer); + + // WELCOME + this._composers.set(OutgoingHeader.WELCOME_OPEN_GIFT, OpenWelcomeGiftComposer); + this._composers.set(OutgoingHeader.WELCOME_GIFT_CHANGE_EMAIL, WelcomeGiftChangeEmailComposer); + + // EMAIL + this._composers.set(OutgoingHeader.EMAIL_GET_STATUS, GetEmailStatusComposer); + this._composers.set(OutgoingHeader.EMAIL_CHANGE, ChangeEmailComposer); + // RENTABLE + this._composers.set(OutgoingHeader.RENTABLE_SPACE_CANCEL_RENT, RentableSpaceCancelRentMessageComposer); + this._composers.set(OutgoingHeader.RENTABLE_SPACE_RENT, RentableSpaceRentMessageComposer); + this._composers.set(OutgoingHeader.RENTABLE_SPACE_STATUS, RentableSpaceStatusMessageComposer); + // RECYCLER + this._composers.set(OutgoingHeader.RECYCLER_STATUS, GetRecyclerStatusMessageComposer); + this._composers.set(OutgoingHeader.RECYCLER_ITEMS, RecycleItemsMessageComposer); + + // TRACKING + this._composers.set(OutgoingHeader.TRACKING_PERFORMANCE_LOG, PerformanceLogMessageComposer); + this._composers.set(OutgoingHeader.TRACKING_LAG_WARNING_REPORT, LagWarningReportMessageComposer); + + // ROOM DIRECTORY + this._composers.set(OutgoingHeader.ROOM_DIRECTORY_ROOM_NETWORK_OPEN_CONNECTION, RoomNetworkOpenConnectionMessageComposer); + + // RENTABLE + this._composers.set(OutgoingHeader.RENTABLE_EXTEND_RENT_OR_BUYOUT_STRIP_ITEM, ExtendRentOrBuyoutStripItemMessageComposer); + this._composers.set(OutgoingHeader.RENTABLE_EXTEND_RENT_OR_BUYOUT_FURNI, ExtendRentOrBuyoutFurniMessageComposer); + this._composers.set(OutgoingHeader.RENTABLE_GET_RENT_OR_BUYOUT_OFFER, GetRentOrBuyoutOfferMessageComposer); + } + + public get events(): Map + { + return this._events; + } + + public get composers(): Map + { + return this._composers; + } +} diff --git a/packages/communication/src/SocketConnection.ts b/packages/communication/src/SocketConnection.ts new file mode 100644 index 0000000..5055295 --- /dev/null +++ b/packages/communication/src/SocketConnection.ts @@ -0,0 +1,261 @@ +import { ICodec, IConnection, IMessageComposer, IMessageConfiguration, IMessageDataWrapper, IMessageEvent, WebSocketEventEnum } from '@nitrots/api'; +import { GetEventDispatcher, NitroEvent, NitroEventType } from '@nitrots/events'; +import { NitroLogger } from '@nitrots/utils'; +import { EvaWireFormat } from './codec'; +import { MessageClassManager } from './messages'; + +export class SocketConnection implements IConnection +{ + private _socket: WebSocket = null; + private _messages: MessageClassManager = new MessageClassManager(); + private _codec: ICodec = new EvaWireFormat(); + private _dataBuffer: ArrayBuffer = null; + private _isReady: boolean = false; + + private _pendingClientMessages: IMessageComposer[] = []; + private _pendingServerMessages: IMessageDataWrapper[] = []; + + private _isAuthenticated: boolean = false; + + public init(socketUrl: string): void + { + if(!socketUrl || !socketUrl.length) return; + + this._dataBuffer = new ArrayBuffer(0); + + this._socket = new WebSocket(socketUrl); + this._socket.binaryType = 'arraybuffer'; + + this._socket.addEventListener(WebSocketEventEnum.CONNECTION_OPENED, event => GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SOCKET_OPENED))); + + this._socket.addEventListener(WebSocketEventEnum.CONNECTION_CLOSED, event => GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SOCKET_CLOSED))); + + this._socket.addEventListener(WebSocketEventEnum.CONNECTION_ERROR, event => GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SOCKET_ERROR))); + + this._socket.addEventListener(WebSocketEventEnum.CONNECTION_MESSAGE, (event: MessageEvent) => + { + this._dataBuffer = this.concatArrayBuffers(this._dataBuffer, event.data); + + this.processReceivedData(); + }); + } + + public ready(): 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 = []; + } + + public authenticated(): void + { + this._isAuthenticated = true; + } + + public send(...composers: IMessageComposer[]): boolean + { + if(!composers) return false; + + composers = [...composers]; + + if(this._isAuthenticated && !this._isReady) + { + this._pendingClientMessages.push(...composers); + + return false; + } + + for(const composer of composers) + { + if(!composer) continue; + + const header = this._messages.getComposerId(composer); + + if(header === -1) + { + NitroLogger.packets('Unknown Composer', composer.constructor.name); + + continue; + } + + const message = composer.getMessageArray(); + const encoded = this._codec.encode(header, message); + + if(!encoded) + { + NitroLogger.packets('Encoding Failed', composer.constructor.name); + + continue; + } + + NitroLogger.packets('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.error(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; + + NitroLogger.packets('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) + { + NitroLogger.packets('IncomingMessage', wrapper.header, 'UNREGISTERED', wrapper); + + return null; + } + + try + { + //@ts-ignore + const parser = new events[0].parserClass(); + + if(!parser || !parser.flush() || !parser.parse(wrapper)) return null; + + for(const event of events) (event.parser = parser); + } + + catch (e) + { + NitroLogger.error('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/packages/communication/src/codec/Byte.ts b/packages/communication/src/codec/Byte.ts new file mode 100644 index 0000000..dbcb29c --- /dev/null +++ b/packages/communication/src/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/packages/communication/src/codec/Short.ts b/packages/communication/src/codec/Short.ts new file mode 100644 index 0000000..f23125e --- /dev/null +++ b/packages/communication/src/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/packages/communication/src/codec/evawire/EvaWireDataWrapper.ts b/packages/communication/src/codec/evawire/EvaWireDataWrapper.ts new file mode 100644 index 0000000..06888c7 --- /dev/null +++ b/packages/communication/src/codec/evawire/EvaWireDataWrapper.ts @@ -0,0 +1,78 @@ +import { IBinaryReader, IMessageDataWrapper } from '@nitrots/api'; + +export class EvaWireDataWrapper implements IMessageDataWrapper +{ + private _header: number; + private _buffer: IBinaryReader; + + constructor(header: number, buffer: IBinaryReader) + { + this._header = header; + this._buffer = buffer; + } + + public readBytes(length: number): IBinaryReader + { + if(!this._buffer) return null; + + return this._buffer.readBytes(length); + } + + public readByte(): number + { + if(!this._buffer) return -1; + + return this._buffer.readByte(); + } + + 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 readFloat(): number + { + if(!this._buffer) return -1; + + return this._buffer.readFloat(); + } + + public readDouble(): number + { + if(!this._buffer) return -1; + + return this._buffer.readDouble(); + } + + 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)); + } +} diff --git a/packages/communication/src/codec/evawire/EvaWireFormat.ts b/packages/communication/src/codec/evawire/EvaWireFormat.ts new file mode 100644 index 0000000..1d3a72b --- /dev/null +++ b/packages/communication/src/codec/evawire/EvaWireFormat.ts @@ -0,0 +1,89 @@ +import { IBinaryWriter, ICodec, IConnection, IMessageDataWrapper } from '@nitrots/api'; +import { BinaryReader, BinaryWriter } from '@nitrots/utils'; +import { Byte } from '../Byte'; +import { Short } from '../Short'; +import { EvaWireDataWrapper } from './EvaWireDataWrapper'; + +export class EvaWireFormat implements ICodec +{ + public encode(header: number, messages: any[]): IBinaryWriter + { + 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'; + else if(value instanceof ArrayBuffer) type = 'arraybuffer'; + } + + switch(type) + { + case 'undefined': + 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; + case 'arraybuffer': + writer.writeBytes(value); + 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; + } +} diff --git a/packages/communication/src/codec/evawire/index.ts b/packages/communication/src/codec/evawire/index.ts new file mode 100644 index 0000000..6b63cda --- /dev/null +++ b/packages/communication/src/codec/evawire/index.ts @@ -0,0 +1,2 @@ +export * from './EvaWireDataWrapper'; +export * from './EvaWireFormat'; diff --git a/packages/communication/src/codec/index.ts b/packages/communication/src/codec/index.ts new file mode 100644 index 0000000..cb49e18 --- /dev/null +++ b/packages/communication/src/codec/index.ts @@ -0,0 +1,3 @@ +export * from './Byte'; +export * from './evawire'; +export * from './Short'; diff --git a/packages/communication/src/index.ts b/packages/communication/src/index.ts new file mode 100644 index 0000000..7fa2659 --- /dev/null +++ b/packages/communication/src/index.ts @@ -0,0 +1,235 @@ +export * from './CommunicationManager'; +export * from './GetCommunication'; +export * from './NitroMessages'; +export * from './SocketConnection'; +export * from './codec'; +export * from './codec/evawire'; +export * from './messages'; +export * from './messages/incoming'; +export * from './messages/incoming/advertisement'; +export * from './messages/incoming/availability'; +export * from './messages/incoming/avatar'; +export * from './messages/incoming/bots'; +export * from './messages/incoming/callforhelp'; +export * from './messages/incoming/camera'; +export * from './messages/incoming/campaign'; +export * from './messages/incoming/catalog'; +export * from './messages/incoming/client'; +export * from './messages/incoming/competition'; +export * from './messages/incoming/crafting'; +export * from './messages/incoming/desktop'; +export * from './messages/incoming/friendlist'; +export * from './messages/incoming/game'; +export * from './messages/incoming/game/directory'; +export * from './messages/incoming/game/lobby'; +export * from './messages/incoming/game/score'; +export * from './messages/incoming/generic'; +export * from './messages/incoming/gifts'; +export * from './messages/incoming/group'; +export * from './messages/incoming/groupforums'; +export * from './messages/incoming/handshake'; +export * from './messages/incoming/help'; +export * from './messages/incoming/inventory'; +export * from './messages/incoming/inventory/achievements'; +export * from './messages/incoming/inventory/avatareffect'; +export * from './messages/incoming/inventory/badges'; +export * from './messages/incoming/inventory/clothes'; +export * from './messages/incoming/inventory/furni'; +export * from './messages/incoming/inventory/furni/gifts'; +export * from './messages/incoming/inventory/pets'; +export * from './messages/incoming/inventory/trading'; +export * from './messages/incoming/landingview'; +export * from './messages/incoming/landingview/votes'; +export * from './messages/incoming/marketplace'; +export * from './messages/incoming/moderation'; +export * from './messages/incoming/mysterybox'; +export * from './messages/incoming/navigator'; +export * from './messages/incoming/notifications'; +export * from './messages/incoming/nux'; +export * from './messages/incoming/perk'; +export * from './messages/incoming/pet'; +export * from './messages/incoming/pet/breeding'; +export * from './messages/incoming/poll'; +export * from './messages/incoming/quest'; +export * from './messages/incoming/recycler'; +export * from './messages/incoming/room'; +export * from './messages/incoming/room/access'; +export * from './messages/incoming/room/access/doorbell'; +export * from './messages/incoming/room/access/rights'; +export * from './messages/incoming/room/bots'; +export * from './messages/incoming/room/data'; +export * from './messages/incoming/room/engine'; +export * from './messages/incoming/room/furniture'; +export * from './messages/incoming/room/furniture/floor'; +export * from './messages/incoming/room/furniture/wall'; +export * from './messages/incoming/room/furniture/youtube'; +export * from './messages/incoming/room/mapping'; +export * from './messages/incoming/room/pet'; +export * from './messages/incoming/room/session'; +export * from './messages/incoming/room/unit'; +export * from './messages/incoming/room/unit/chat'; +export * from './messages/incoming/roomevents'; +export * from './messages/incoming/roomsettings'; +export * from './messages/incoming/security'; +export * from './messages/incoming/sound'; +export * from './messages/incoming/talent'; +export * from './messages/incoming/user'; +export * from './messages/incoming/user/access'; +export * from './messages/incoming/user/data'; +export * from './messages/incoming/user/inventory'; +export * from './messages/incoming/user/inventory/currency'; +export * from './messages/incoming/user/inventory/subscription'; +export * from './messages/incoming/user/wardrobe'; +export * from './messages/incoming/userclassification'; +export * from './messages/outgoing'; +export * from './messages/outgoing/advertisement'; +export * from './messages/outgoing/avatar'; +export * from './messages/outgoing/camera'; +export * from './messages/outgoing/campaign'; +export * from './messages/outgoing/catalog'; +export * from './messages/outgoing/competition'; +export * from './messages/outgoing/crafting'; +export * from './messages/outgoing/desktop'; +export * from './messages/outgoing/friendfurni'; +export * from './messages/outgoing/friendlist'; +export * from './messages/outgoing/game'; +export * from './messages/outgoing/game/arena'; +export * from './messages/outgoing/game/directory'; +export * from './messages/outgoing/game/ingame'; +export * from './messages/outgoing/game/lobby'; +export * from './messages/outgoing/game/score'; +export * from './messages/outgoing/gifts'; +export * from './messages/outgoing/group'; +export * from './messages/outgoing/groupforums'; +export * from './messages/outgoing/handshake'; +export * from './messages/outgoing/help'; +export * from './messages/outgoing/inventory'; +export * from './messages/outgoing/inventory/avatareffect'; +export * from './messages/outgoing/inventory/badges'; +export * from './messages/outgoing/inventory/bots'; +export * from './messages/outgoing/inventory/furni'; +export * from './messages/outgoing/inventory/pets'; +export * from './messages/outgoing/inventory/trading'; +export * from './messages/outgoing/inventory/unseen'; +export * from './messages/outgoing/landingview'; +export * from './messages/outgoing/landingview/votes'; +export * from './messages/outgoing/marketplace'; +export * from './messages/outgoing/moderation'; +export * from './messages/outgoing/mysterybox'; +export * from './messages/outgoing/navigator'; +export * from './messages/outgoing/nux'; +export * from './messages/outgoing/pet'; +export * from './messages/outgoing/poll'; +export * from './messages/outgoing/quest'; +export * from './messages/outgoing/recycler'; +export * from './messages/outgoing/room'; +export * from './messages/outgoing/room/access'; +export * from './messages/outgoing/room/action'; +export * from './messages/outgoing/room/bots'; +export * from './messages/outgoing/room/data'; +export * from './messages/outgoing/room/engine'; +export * from './messages/outgoing/room/furniture'; +export * from './messages/outgoing/room/furniture/dimmer'; +export * from './messages/outgoing/room/furniture/floor'; +export * from './messages/outgoing/room/furniture/logic'; +export * from './messages/outgoing/room/furniture/mannequin'; +export * from './messages/outgoing/room/furniture/presents'; +export * from './messages/outgoing/room/furniture/toner'; +export * from './messages/outgoing/room/furniture/wall'; +export * from './messages/outgoing/room/furniture/youtube'; +export * from './messages/outgoing/room/layout'; +export * from './messages/outgoing/room/pets'; +export * from './messages/outgoing/room/session'; +export * from './messages/outgoing/room/unit'; +export * from './messages/outgoing/room/unit/chat'; +export * from './messages/outgoing/roomdirectory'; +export * from './messages/outgoing/roomevents'; +export * from './messages/outgoing/roomsettings'; +export * from './messages/outgoing/sound'; +export * from './messages/outgoing/talent'; +export * from './messages/outgoing/tracking'; +export * from './messages/outgoing/user'; +export * from './messages/outgoing/user/data'; +export * from './messages/outgoing/user/inventory'; +export * from './messages/outgoing/user/inventory/currency'; +export * from './messages/outgoing/user/inventory/subscription'; +export * from './messages/outgoing/user/settings'; +export * from './messages/outgoing/userclassification'; +export * from './messages/parser'; +export * from './messages/parser/advertisement'; +export * from './messages/parser/availability'; +export * from './messages/parser/avatar'; +export * from './messages/parser/bots'; +export * from './messages/parser/callforhelp'; +export * from './messages/parser/camera'; +export * from './messages/parser/campaign'; +export * from './messages/parser/catalog'; +export * from './messages/parser/client'; +export * from './messages/parser/competition'; +export * from './messages/parser/crafting'; +export * from './messages/parser/desktop'; +export * from './messages/parser/friendlist'; +export * from './messages/parser/game'; +export * from './messages/parser/game/directory'; +export * from './messages/parser/game/lobby'; +export * from './messages/parser/game/score'; +export * from './messages/parser/generic'; +export * from './messages/parser/gifts'; +export * from './messages/parser/group'; +export * from './messages/parser/group/utils'; +export * from './messages/parser/groupforums'; +export * from './messages/parser/handshake'; +export * from './messages/parser/help'; +export * from './messages/parser/inventory'; +export * from './messages/parser/inventory/achievements'; +export * from './messages/parser/inventory/avatareffect'; +export * from './messages/parser/inventory/badges'; +export * from './messages/parser/inventory/clothing'; +export * from './messages/parser/inventory/furniture'; +export * from './messages/parser/inventory/pets'; +export * from './messages/parser/inventory/purse'; +export * from './messages/parser/inventory/trading'; +export * from './messages/parser/landingview'; +export * from './messages/parser/landingview/votes'; +export * from './messages/parser/marketplace'; +export * from './messages/parser/moderation'; +export * from './messages/parser/mysterybox'; +export * from './messages/parser/navigator'; +export * from './messages/parser/navigator/utils'; +export * from './messages/parser/notifications'; +export * from './messages/parser/nux'; +export * from './messages/parser/perk'; +export * from './messages/parser/perk/common'; +export * from './messages/parser/pet'; +export * from './messages/parser/poll'; +export * from './messages/parser/quest'; +export * from './messages/parser/recycler'; +export * from './messages/parser/room'; +export * from './messages/parser/room/access'; +export * from './messages/parser/room/access/doorbell'; +export * from './messages/parser/room/access/rights'; +export * from './messages/parser/room/bots'; +export * from './messages/parser/room/data'; +export * from './messages/parser/room/engine'; +export * from './messages/parser/room/furniture'; +export * from './messages/parser/room/furniture/floor'; +export * from './messages/parser/room/furniture/wall'; +export * from './messages/parser/room/furniture/youtube'; +export * from './messages/parser/room/mapping'; +export * from './messages/parser/room/pet'; +export * from './messages/parser/room/session'; +export * from './messages/parser/room/unit'; +export * from './messages/parser/room/unit/chat'; +export * from './messages/parser/roomevents'; +export * from './messages/parser/roomsettings'; +export * from './messages/parser/security'; +export * from './messages/parser/sound'; +export * from './messages/parser/talent'; +export * from './messages/parser/user'; +export * from './messages/parser/user/access'; +export * from './messages/parser/user/data'; +export * from './messages/parser/user/inventory'; +export * from './messages/parser/user/inventory/currency'; +export * from './messages/parser/user/inventory/subscription'; +export * from './messages/parser/user/wardrobe'; +export * from './messages/parser/userclassification'; diff --git a/packages/communication/src/messages/MessageClassManager.ts b/packages/communication/src/messages/MessageClassManager.ts new file mode 100644 index 0000000..3de5e77 --- /dev/null +++ b/packages/communication/src/messages/MessageClassManager.ts @@ -0,0 +1,128 @@ +import { IMessageComposer, IMessageConfiguration, IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; + +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; + + this._messageIdByEvent.set(handler, header); + } + + private registerMessageComposerClass(header: number, handler: Function): void + { + if(!header || !handler) 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); + } + + 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/packages/communication/src/messages/incoming/IncomingHeader.ts b/packages/communication/src/messages/incoming/IncomingHeader.ts new file mode 100644 index 0000000..f7ae0fd --- /dev/null +++ b/packages/communication/src/messages/incoming/IncomingHeader.ts @@ -0,0 +1,473 @@ +export class IncomingHeader +{ + public static ACHIEVEMENT_LIST = 305; + public static AUTHENTICATED = 2491; + public static AUTHENTICATION = -1; + public static AVAILABILITY_STATUS = 2033; + public static BUILDERS_CLUB_EXPIRED = 1452; + public static CLUB_OFFERS = 2405; + public static CATALOG_PAGE = 804; + public static CATALOG_PAGE_LIST = 1032; + public static CATALOG_PURCHASE_OK = 869; + public static CATALOG_PURCHASE_ERROR = 1404; + public static CATALOG_PURCHASE_NOT_ALLOWED = 3770; + public static PRODUCT_OFFER = 3388; + public static LIMITED_SOLD_OUT = 377; + public static CATALOG_PUBLISHED = 1866; + public static CFH_RESULT_MESSAGE = 3635; + 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 BUNDLE_DISCOUNT_RULESET = 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 FURNITURE_GROUP_CONTEXT_MENU_INFO = 3293; + public static FURNITURE_POSTIT_STICKY_POLE_OPEN = 2366; + public static GAME_CENTER_ACHIEVEMENTS = 2265; + public static GAME_CENTER_GAME_LIST = 222; + public static GAME_CENTER_STATUS = 2893; + public static GAME_CENTER_IN_ARENA_QUEUE = 872; + public static GAME_CENTER_STOP_COUNTER = 3191; + public static GAME_CENTER_USER_LEFT_GAME = 3138; + public static GAME_CENTER_DIRECTORY_STATUS = 2246; + public static GAME_CENTER_STARTING_GAME_FAILED = 2142; + public static GAME_CENTER_JOINING_FAILED = 1730; + public static GAMESTATUSMESSAGE = 3805; + public static GAMEACHIEVEMENTS = 1689; + public static GAMEINVITE = 904; + public static JOININGQUEUEFAILED = 3035; + public static JOINEDQUEUEMESSAGE = 2260; + public static LEFTQUEUE = 1477; + public static LOAD_GAME_URL = 2624; + public static LOADGAME = 3654; + public static UNLOADGAME = 1715; + public static ACHIEVEMENTRESOLUTIONCOMPLETED = 740; + public static ACHIEVEMENTRESOLUTIONPROGRESS = 3370; + public static ACHIEVEMENTRESOLUTIONS = 66; + public static GENERIC_ALERT = 3801; + public static MODERATOR_MESSAGE = 2030; + public static GENERIC_ERROR = 1600; + public static GIFT_WRAPPER_CONFIG = 2234; + public static GROUP_BADGES = 2402; + public static GROUP_CREATE_OPTIONS = 2159; + public static GROUP_FORUM_DATA = 3011; + public static GROUP_FORUM_LIST = 3001; + public static GROUP_FORUM_THREADS = 1073; + public static GROUP_FORUM_POST = 2049; + public static GROUP_FORUM_POST_THREAD = 1862; + public static GROUP_FORUM_THREAD_MESSAGES = 509; + public static GROUP_FORUM_UNREAD_COUNT = 2379; + public static GROUP_FORUM_UPDATE_MESSAGE = 324; + public static GROUP_FORUM_UPDATE_THREAD = 2528; + 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_PURCHASED = 2808; + public static GROUP_SETTINGS = 3965; + public static GROUP_BADGE_PARTS = 2238; + public static GROUP_MEMBERSHIP_REQUESTED = 1180; + public static GROUP_DETAILS_CHANGED = 1459; + public static GROUP_HABBO_JOIN_FAILED = 762; + public static GUILD_EDIT_FAILED = 3988; + public static GUILD_MEMBER_MGMT_FAILED = 818; + 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 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_SEARCH = 973; + public static MESSENGER_UPDATE = 2800; + public static MODERATION_REPORT_DISABLED = 1651; + public static MODERATION_TOOL = 2696; + 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 THUMBNAIL_UPDATE_RESULT = 1927; + public static CAN_CREATE_ROOM = 378; + public static CATEGORIES_WITH_VISITOR_COUNT = 1455; + public static COMPETITION_ROOMS_DATA = 3954; + public static CONVERTED_ROOM_ID = 1331; + public static GUEST_ROOM_SEARCH_RESULT = 52; + public static NOTIFICATION_LIST = 1992; + public static NOTIFICATION_OFFER_REWARD_DELIVERED = 2125; + public static NOTIFICATION_SIMPLE_ALERT = 5100; + public static NOTIFICATION_ELEMENT_POINTER = 1787; + public static PET_FIGURE_UPDATE = 1924; + public static PET_INFO = 2901; + public static PET_TRAINING_PANEL = 1164; + public static PET_LEVEL_UPDATE = 2824; + public static PET_SCRATCH_FAILED = 1130; + public static PET_OPEN_PACKAGE_REQUESTED = 2380; + public static PET_OPEN_PACKAGE_RESULT = 546; + public static PET_BREEDING = 1746; + public static PET_CONFIRM_BREEDING_RESULT = 1625; + public static PET_GO_TO_BREEDING_NEST_FAILURE = 2621; + public static PET_NEST_BREEDING_SUCCESS = 2527; + public static PET_CONFIRM_BREEDING_REQUEST = 634; + public static PET_BREEDING_RESULT = 1553; + public static RECYCLER_PRIZES = 3164; + public static RECYCLER_STATUS = 3433; + public static RECYCLER_FINISHED = 468; + 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_INFO_UPDATED = 3297; + public static ROOM_SPECTATOR = 1033; + public static ROOM_THICKNESS = 3547; + public static ROOM_GET_FILTER_WORDS = 2937; + public static ROOM_MESSAGE_NOTIFICATION = 1634; + public static ROOM_POPULAR_TAGS_RESULT = 2012; + public static INFO_FEED_ENABLE = 3284; + public static SECURITY_MACHINE = 1488; + public static MYSTERY_BOX_KEYS = 2833; + public static GOTMYSTERYBOXPRIZEMESSAGE = 3712; + public static CANCELMYSTERYBOXWAITMESSAGE = 596; + public static SHOWMYSTERYBOXWAITMESSAGE = 3201; + 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 = 1254; + public static TRADE_YOU_NOT_ALLOWED = 3058; + public static TRADE_NO_SUCH_ITEM = 2873; + 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_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 ACTIVITY_POINT_NOTIFICATION = 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 ROOM_EVENT_CANCEL = 3479; + public static ROOM_EVENT = 1840; + 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 USER_CLASSIFICATION = 966; + public static GET_USER_TAGS = 1255; + 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 MODTOOL_VISITED_ROOMS_USER = 1752; + public static MODERATOR_ACTION_RESULT = 2335; + public static ISSUE_DELETED = 3192; + public static ISSUE_INFO = 3609; + public static ISSUE_PICK_FAILED = 3150; + public static CFH_CHATLOG = 607; + public static MODERATOR_TOOL_PREFERENCES = 1576; + 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 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 AVATAR_EFFECT_SELECTED = 3473; + public static CLUB_GIFT_INFO = 619; + public static REDEEM_VOUCHER_ERROR = 714; + public static REDEEM_VOUCHER_OK = 3336; + public static IN_CLIENT_LINK = 2023; + public static BOT_COMMAND_CONFIGURATION = 1618; + public static BOT_SKILL_LIST_UPDATE = 69; + public static BOT_FORCE_OPEN_CONTEXT_MENU = 296; + public static HAND_ITEM_RECEIVED = 354; + public static PET_PLACING_ERROR = 2913; + public static BOT_ERROR = 639; + public static MARKETPLACE_SELL_ITEM = 54; + public static MARKETPLACE_ITEM_STATS = 725; + public static MARKETPLACE_OWN_ITEMS = 3884; + public static MARKETPLACE_CANCEL_SALE = 3264; + public static MARKETPLACE_ITEM_POSTED = 1359; + public static MARKETPLACE_ITEMS_SEARCHED = 680; + public static MARKETPLACE_AFTER_ORDER_STATUS = 2032; + public static CATALOG_RECEIVE_PET_BREEDS = 3331; + public static CATALOG_APPROVE_NAME_RESULT = 1503; + public static OBJECTS_DATA_UPDATE = 1453; + public static PET_EXPERIENCE = 2156; + public static COMMUNITY_GOAL_VOTE_EVENT = 1435; + public static PROMO_ARTICLES = 286; + public static COMMUNITY_GOAL_EARNED_PRIZES = 3319; + public static COMMUNITY_GOAL_PROGRESS = 2525; + public static CONCURRENT_USERS_GOAL_PROGRESS = 2737; + public static QUEST_DAILY = 1878; + public static QUEST_CANCELLED = 3027; + public static QUEST_COMPLETED = 949; + public static COMMUNITY_GOAL_HALL_OF_FAME = 3005; + public static EPIC_POPUP = 3945; + public static SEASONAL_QUESTS = 1122; + public static QUESTS = 3625; + public static QUEST = 230; + public static BONUS_RARE_INFO = 1533; + public static CRAFTABLE_PRODUCTS = 1000; + public static CRAFTING_RECIPE = 2774; + public static CRAFTING_RECIPES_AVAILABLE = 2124; + public static CRAFTING_RESULT = 618; + public static CAMERA_PUBLISH_STATUS = 2057; + public static CAMERA_PURCHASE_OK = 2783; + public static CAMERA_STORAGE_URL = 3696; + public static CAMERA_SNAPSHOT = 463; + public static COMPETITION_STATUS = 133; + public static INIT_CAMERA = 3878; + public static THUMBNAIL_STATUS = 3595; + public static ACHIEVEMENT_NOTIFICATION = 806; + public static CLUB_GIFT_NOTIFICATION = 2188; + public static INTERSTITIAL_MESSAGE = 1808; + public static ROOM_AD_ERROR = 1759; + public static AVAILABILITY_TIME = 600; + public static HOTEL_CLOSED_AND_OPENS = 3728; + public static HOTEL_CLOSES_AND_OPENS_AT = 2771; + public static HOTEL_WILL_CLOSE_MINUTES = 1050; + public static HOTEL_MAINTENANCE = 1350; + public static JUKEBOX_PLAYLIST_FULL = 105; + public static JUKEBOX_SONG_DISKS = 34; + public static NOW_PLAYING = 469; + public static OFFICIAL_SONG_ID = 1381; + public static PLAYLIST = 1748; + public static PLAYLIST_SONG_ADDED = 1140; + public static TRAX_SONG_INFO = 3365; + public static USER_SONG_DISKS_INVENTORY = 2602; + public static CHECK_USER_NAME = 563; + public static CFH_SANCTION = 2782; + public static CFH_TOPICS = 325; + public static CFH_SANCTION_STATUS = 2221; + public static CAMPAIGN_CALENDAR_DATA = 2531; + public static CAMPAIGN_CALENDAR_DOOR_OPENED = 2551; + public static BUILDERS_CLUB_FURNI_COUNT = 3828; + public static BUILDERS_CLUB_SUBSCRIPTION = 1452; + public static CATALOG_PAGE_EXPIRATION = 2668; + public static CATALOG_EARLIEST_EXPIRY = 2515; + public static CLUB_GIFT_SELECTED = 659; + public static TARGET_OFFER_NOT_FOUND = 1237; + public static TARGET_OFFER = 119; + public static DIRECT_SMS_CLUB_BUY = 195; + public static ROOM_AD_PURCHASE = 2468; + public static NOT_ENOUGH_BALANCE = 3914; + public static LIMITED_OFFER_APPEARING_NEXT = 44; + public static IS_OFFER_GIFTABLE = 761; + public static CLUB_EXTENDED_OFFER = 3964; + public static SEASONAL_CALENDAR_OFFER = 1889; + public static COMPETITION_ENTRY_SUBMIT = 1177; + public static COMPETITION_VOTING_INFO = 3506; + public static COMPETITION_TIMING_CODE = 1745; + public static COMPETITION_USER_PART_OF = 3841; + public static COMPETITION_NO_OWNED_ROOMS = 2064; + public static COMPETITION_SECONDS_UNTIL = 3926; + public static BADGE_POINT_LIMITS = 2501; + public static BADGE_REQUEST_FULFILLED = 2998; + public static HELPER_TALENT_TRACK = 3406; + public static TALENT_TRACK_LEVEL = 1203; + public static TALENT_TRACK_LEVEL_UP = 638; + public static USER_BANNED = 1683; + public static BOT_RECEIVED = 3684; + public static PET_LEVEL_NOTIFICATION = 859; + public static PET_RECEIVED = 1111; + public static MODERATION_CAUTION = 1890; + public static YOUTUBE_CONTROL_VIDEO = 1554; + public static YOUTUBE_DISPLAY_PLAYLISTS = 1112; + public static YOUTUBE_DISPLAY_VIDEO = 1411; + public static CFH_DISABLED_NOTIFY = 1651; + public static QUESTION = 2665; + public static POLL_CONTENTS = 2997; + public static POLL_ERROR = 662; + public static POLL_OFFER = 3785; + public static POLL_ROOM_RESULT = 5201; + public static POLL_START_ROOM = 5200; + public static QUESTION_ANSWERED = 2589; + public static QUESTION_FINISHED = 1066; + public static CFH_PENDING_CALLS = 1121; + public static GUIDE_ON_DUTY_STATUS = 1548; + public static GUIDE_SESSION_ATTACHED = 1591; + public static GUIDE_SESSION_DETACHED = 138; + public static GUIDE_SESSION_ENDED = 1456; + public static GUIDE_SESSION_ERROR = 673; + public static GUIDE_SESSION_INVITED_TO_GUIDE_ROOM = 219; + public static GUIDE_SESSION_MESSAGE = 841; + public static GUIDE_SESSION_PARTNER_IS_TYPING = 1016; + public static GUIDE_SESSION_REQUESTER_ROOM = 1847; + public static GUIDE_SESSION_STARTED = 3209; + public static GUIDE_TICKET_CREATION_RESULT = 3285; + public static GUIDE_TICKET_RESOLUTION = 2674; + public static GUIDE_REPORTING_STATUS = 3463; + public static HOTEL_MERGE_NAME_CHANGE = 1663; + public static ISSUE_CLOSE_NOTIFICATION = 934; + public static QUIZ_DATA = 2927; + public static QUIZ_RESULTS = 2772; + public static CFH_PENDING_CALLS_DELETED = 77; + public static CFH_REPLY = 3796; + public static CHAT_REVIEW_SESSION_DETACHED = 30; + public static CHAT_REVIEW_SESSION_OFFERED_TO_GUIDE = 735; + public static CHAT_REVIEW_SESSION_RESULTS = 3276; + public static CHAT_REVIEW_SESSION_STARTED = 143; + public static CHAT_REVIEW_SESSION_VOTING_STATUS = 1829; + public static SCR_SEND_KICKBACK_INFO = 3277; + public static PET_STATUS = 1907; + public static GROUP_DEACTIVATE = 3129; + public static PET_RESPECTED = 2788; + public static PET_SUPPLEMENT = 3441; + public static NOOBNESS_LEVEL = 3738; + public static DISCONNECT_REASON = 4000; + public static CAN_CREATE_ROOM_EVENT = 2599; + public static FAVORITE_GROUP_UDPATE = 3403; + public static NO_SUCH_FLAT = 84; + public static ROOM_SETTINGS_ERROR = 2897; + public static SHOW_ENFORCE_ROOM_CATEGORY = 3896; + public static CUSTOM_USER_NOTIFICATION = 909; + public static NEW_USER_EXPERIENCE_GIFT_OFFER = 3575; + public static RESTORE_CLIENT = 426; + public static FIREWORK_CHARGE_DATA = 5210; + public static NEW_USER_EXPERIENCE_NOT_COMPLETE = 3639; + public static CONNECTION_ERROR = 1004; + public static ACCOUNT_SAFETY_LOCK_STATUS_CHANGE = 1243; + public static PHONE_COLLECTION_STATE = 2890; + public static PHONE_TRY_NUMBER_RESULT = 800; + public static PHONE_TRY_VERIFICATION_CODE_RESULT = 91; + public static EXTENDED_PROFILE_CHANGED = 876; + public static WELCOME_GIFT_CHANGE_EMAIL_RESULT = 2293; + public static WELCOME_GIFT_STATUS = 2707; + public static HANDSHAKE_INIT_DIFFIE = 1347; + public static HANDSHAKE_COMPLETE_DIFFIE = 3885; + public static RENTABLE_SPACE_RENT_OK = 2046; + public static RENTABLE_SPACE_STATUS = 3559; + public static RENTABLE_SPACE_RENT_FAILED = 1868; + public static EMAIL_STATUS = 612; + public static CHANGE_EMAIL_RESULT = 1815; + public static WEEKLY_GAME_REWARD = 2641; + public static WEEKLY_GAME_REWARD_WINNERS = 3097; + public static WEEKLY_COMPETITIVE_LEADERBOARD = 3512; + public static WEEKLY_COMPETITIVE_FRIENDS_LEADERBOARD = 3560; + public static WEEKLY_GAME2_FRIENDS_LEADERBOARD = 2270; + public static WEEKLY_GAME2_LEADERBOARD = 2196; + public static RENTABLE_FURNI_RENT_OR_BUYOUT_OFFER = 35; + public static HANDSHAKE_IDENTITY_ACCOUNT = 3523; +} diff --git a/packages/communication/src/messages/incoming/advertisement/InterstitialMessageEvent.ts b/packages/communication/src/messages/incoming/advertisement/InterstitialMessageEvent.ts new file mode 100644 index 0000000..7fd5f29 --- /dev/null +++ b/packages/communication/src/messages/incoming/advertisement/InterstitialMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { InterstitialMessageParser } from '../../parser'; + +export class InterstitialMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, InterstitialMessageParser); + } + + public getParser(): InterstitialMessageParser + { + return this.parser as InterstitialMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/advertisement/RoomAdErrorEvent.ts b/packages/communication/src/messages/incoming/advertisement/RoomAdErrorEvent.ts new file mode 100644 index 0000000..1bee1d4 --- /dev/null +++ b/packages/communication/src/messages/incoming/advertisement/RoomAdErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomAdErrorMessageParser } from '../../parser'; + +export class RoomAdErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomAdErrorMessageParser); + } + + public getParser(): RoomAdErrorMessageParser + { + return this.parser as RoomAdErrorMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/advertisement/index.ts b/packages/communication/src/messages/incoming/advertisement/index.ts new file mode 100644 index 0000000..7727ffc --- /dev/null +++ b/packages/communication/src/messages/incoming/advertisement/index.ts @@ -0,0 +1,2 @@ +export * from './InterstitialMessageEvent'; +export * from './RoomAdErrorEvent'; diff --git a/packages/communication/src/messages/incoming/availability/AvailabilityStatusMessageEvent.ts b/packages/communication/src/messages/incoming/availability/AvailabilityStatusMessageEvent.ts new file mode 100644 index 0000000..3cd147d --- /dev/null +++ b/packages/communication/src/messages/incoming/availability/AvailabilityStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AvailabilityStatusMessageParser } from '../../parser'; + +export class AvailabilityStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvailabilityStatusMessageParser); + } + + public getParser(): AvailabilityStatusMessageParser + { + return this.parser as AvailabilityStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/availability/AvailabilityTimeMessageEvent.ts b/packages/communication/src/messages/incoming/availability/AvailabilityTimeMessageEvent.ts new file mode 100644 index 0000000..06ea6f8 --- /dev/null +++ b/packages/communication/src/messages/incoming/availability/AvailabilityTimeMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AvailabilityTimeMessageParser } from '../../parser'; + +export class AvailabilityTimeMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvailabilityTimeMessageParser); + } + + public getParser(): AvailabilityTimeMessageParser + { + return this.parser as AvailabilityTimeMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/availability/HotelClosedAndOpensEvent.ts b/packages/communication/src/messages/incoming/availability/HotelClosedAndOpensEvent.ts new file mode 100644 index 0000000..ab8e15b --- /dev/null +++ b/packages/communication/src/messages/incoming/availability/HotelClosedAndOpensEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HotelClosedAndOpensMessageParser } from '../../parser'; + +export class HotelClosedAndOpensEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HotelClosedAndOpensMessageParser); + } + + public getParser(): HotelClosedAndOpensMessageParser + { + return this.parser as HotelClosedAndOpensMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/availability/HotelClosesAndWillOpenAtEvent.ts b/packages/communication/src/messages/incoming/availability/HotelClosesAndWillOpenAtEvent.ts new file mode 100644 index 0000000..615f631 --- /dev/null +++ b/packages/communication/src/messages/incoming/availability/HotelClosesAndWillOpenAtEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HotelClosesAndWillOpenAtMessageParser } from '../../parser'; + +export class HotelClosesAndWillOpenAtEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HotelClosesAndWillOpenAtMessageParser); + } + + public getParser(): HotelClosesAndWillOpenAtMessageParser + { + return this.parser as HotelClosesAndWillOpenAtMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/availability/HotelWillCloseInMinutesEvent.ts b/packages/communication/src/messages/incoming/availability/HotelWillCloseInMinutesEvent.ts new file mode 100644 index 0000000..c79dde8 --- /dev/null +++ b/packages/communication/src/messages/incoming/availability/HotelWillCloseInMinutesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HotelWillCloseInMinutesMessageParser } from '../../parser'; + +export class HotelWillCloseInMinutesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HotelWillCloseInMinutesMessageParser); + } + + public getParser(): HotelWillCloseInMinutesMessageParser + { + return this.parser as HotelWillCloseInMinutesMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/availability/MaintenanceStatusMessageEvent.ts b/packages/communication/src/messages/incoming/availability/MaintenanceStatusMessageEvent.ts new file mode 100644 index 0000000..dbfdf32 --- /dev/null +++ b/packages/communication/src/messages/incoming/availability/MaintenanceStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MaintenanceStatusMessageParser } from '../../parser'; + +export class MaintenanceStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MaintenanceStatusMessageParser); + } + + public getParser(): MaintenanceStatusMessageParser + { + return this.parser as MaintenanceStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/availability/index.ts b/packages/communication/src/messages/incoming/availability/index.ts new file mode 100644 index 0000000..8d657b5 --- /dev/null +++ b/packages/communication/src/messages/incoming/availability/index.ts @@ -0,0 +1,6 @@ +export * from './AvailabilityStatusMessageEvent'; +export * from './AvailabilityTimeMessageEvent'; +export * from './HotelClosedAndOpensEvent'; +export * from './HotelClosesAndWillOpenAtEvent'; +export * from './HotelWillCloseInMinutesEvent'; +export * from './MaintenanceStatusMessageEvent'; diff --git a/packages/communication/src/messages/incoming/avatar/ChangeUserNameResultMessageEvent.ts b/packages/communication/src/messages/incoming/avatar/ChangeUserNameResultMessageEvent.ts new file mode 100644 index 0000000..f913b81 --- /dev/null +++ b/packages/communication/src/messages/incoming/avatar/ChangeUserNameResultMessageEvent.ts @@ -0,0 +1,25 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ChangeUserNameResultMessageParser } from '../../parser'; + +export class ChangeUserNameResultMessageEvent extends MessageEvent implements IMessageEvent +{ + public static NAME_OK: number = 0; + public static ERROR_NAME_REQUIRED: number = 1; + public static ERROR_NAME_TOO_SHORT: number = 2; + public static ERROR_NAME_TOO_LONG: number = 3; + public static ERROR_NAME_NOT_VALID: number = 4; + public static ERROR_NAME_IN_USE: number = 5; + public static ERROR_NAME_CHANGE_NOT_ALLOWED: number = 6; + public static ERROR_MERGE_HOTEL_DOWN: number = 7; + + constructor(callBack: Function) + { + super(callBack, ChangeUserNameResultMessageParser); + } + + public getParser(): ChangeUserNameResultMessageParser + { + return this.parser as ChangeUserNameResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/avatar/CheckUserNameResultMessageEvent.ts b/packages/communication/src/messages/incoming/avatar/CheckUserNameResultMessageEvent.ts new file mode 100644 index 0000000..8227c67 --- /dev/null +++ b/packages/communication/src/messages/incoming/avatar/CheckUserNameResultMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CheckUserNameResultMessageParser } from '../../parser'; + +export class CheckUserNameResultMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CheckUserNameResultMessageParser); + } + + public getParser(): CheckUserNameResultMessageParser + { + return this.parser as CheckUserNameResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/avatar/FigureUpdateEvent.ts b/packages/communication/src/messages/incoming/avatar/FigureUpdateEvent.ts new file mode 100644 index 0000000..fe5fa9f --- /dev/null +++ b/packages/communication/src/messages/incoming/avatar/FigureUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FigureUpdateParser } from '../../parser'; + +export class FigureUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FigureUpdateParser); + } + + public getParser(): FigureUpdateParser + { + return this.parser as FigureUpdateParser; + } +} diff --git a/packages/communication/src/messages/incoming/avatar/WardrobeMessageEvent.ts b/packages/communication/src/messages/incoming/avatar/WardrobeMessageEvent.ts new file mode 100644 index 0000000..c814a7c --- /dev/null +++ b/packages/communication/src/messages/incoming/avatar/WardrobeMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WardrobeMessageParser } from '../../parser'; + +export class WardrobeMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WardrobeMessageParser); + } + + public getParser(): WardrobeMessageParser + { + return this.parser as WardrobeMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/avatar/index.ts b/packages/communication/src/messages/incoming/avatar/index.ts new file mode 100644 index 0000000..45a727e --- /dev/null +++ b/packages/communication/src/messages/incoming/avatar/index.ts @@ -0,0 +1,4 @@ +export * from './ChangeUserNameResultMessageEvent'; +export * from './CheckUserNameResultMessageEvent'; +export * from './FigureUpdateEvent'; +export * from './WardrobeMessageEvent'; diff --git a/packages/communication/src/messages/incoming/bots/BotAddedToInventoryEvent.ts b/packages/communication/src/messages/incoming/bots/BotAddedToInventoryEvent.ts new file mode 100644 index 0000000..29c2055 --- /dev/null +++ b/packages/communication/src/messages/incoming/bots/BotAddedToInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BotAddedToInventoryParser } from '../../parser'; + +export class BotAddedToInventoryEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotAddedToInventoryParser); + } + + public getParser(): BotAddedToInventoryParser + { + return this.parser as BotAddedToInventoryParser; + } +} diff --git a/packages/communication/src/messages/incoming/bots/BotInventoryMessageEvent.ts b/packages/communication/src/messages/incoming/bots/BotInventoryMessageEvent.ts new file mode 100644 index 0000000..70dd754 --- /dev/null +++ b/packages/communication/src/messages/incoming/bots/BotInventoryMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BotInventoryMessageParser } from '../../parser'; + +export class BotInventoryMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotInventoryMessageParser); + } + + public getParser(): BotInventoryMessageParser + { + return this.parser as BotInventoryMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/bots/BotReceivedMessageEvent.ts b/packages/communication/src/messages/incoming/bots/BotReceivedMessageEvent.ts new file mode 100644 index 0000000..533e81c --- /dev/null +++ b/packages/communication/src/messages/incoming/bots/BotReceivedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BotReceivedMessageParser } from '../../parser'; + +export class BotReceivedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotReceivedMessageParser); + } + + public getParser(): BotReceivedMessageParser + { + return this.parser as BotReceivedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/bots/BotRemovedFromInventoryEvent.ts b/packages/communication/src/messages/incoming/bots/BotRemovedFromInventoryEvent.ts new file mode 100644 index 0000000..dbbf6f5 --- /dev/null +++ b/packages/communication/src/messages/incoming/bots/BotRemovedFromInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BotRemovedFromInventoryParser } from '../../parser'; + +export class BotRemovedFromInventoryEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotRemovedFromInventoryParser); + } + + public getParser(): BotRemovedFromInventoryParser + { + return this.parser as BotRemovedFromInventoryParser; + } +} diff --git a/packages/communication/src/messages/incoming/bots/index.ts b/packages/communication/src/messages/incoming/bots/index.ts new file mode 100644 index 0000000..dde10bf --- /dev/null +++ b/packages/communication/src/messages/incoming/bots/index.ts @@ -0,0 +1,4 @@ +export * from './BotAddedToInventoryEvent'; +export * from './BotInventoryMessageEvent'; +export * from './BotReceivedMessageEvent'; +export * from './BotRemovedFromInventoryEvent'; diff --git a/packages/communication/src/messages/incoming/callforhelp/CfhSanctionMessageEvent.ts b/packages/communication/src/messages/incoming/callforhelp/CfhSanctionMessageEvent.ts new file mode 100644 index 0000000..9f15e10 --- /dev/null +++ b/packages/communication/src/messages/incoming/callforhelp/CfhSanctionMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CfhSanctionMessageParser } from '../../parser'; + +export class CfhSanctionMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CfhSanctionMessageParser); + } + + public getParser(): CfhSanctionMessageParser + { + return this.parser as CfhSanctionMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/callforhelp/CfhTopicsInitEvent.ts b/packages/communication/src/messages/incoming/callforhelp/CfhTopicsInitEvent.ts new file mode 100644 index 0000000..29aa4e2 --- /dev/null +++ b/packages/communication/src/messages/incoming/callforhelp/CfhTopicsInitEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CfhTopicsInitMessageParser } from '../../parser'; + +export class CfhTopicsInitEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CfhTopicsInitMessageParser); + } + + public getParser(): CfhTopicsInitMessageParser + { + return this.parser as CfhTopicsInitMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/callforhelp/SanctionStatusEvent.ts b/packages/communication/src/messages/incoming/callforhelp/SanctionStatusEvent.ts new file mode 100644 index 0000000..d3e7116 --- /dev/null +++ b/packages/communication/src/messages/incoming/callforhelp/SanctionStatusEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { SanctionStatusMessageParser } from '../../parser'; + +export class SanctionStatusEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, SanctionStatusMessageParser); + } + + public getParser(): SanctionStatusMessageParser + { + return this.parser as SanctionStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/callforhelp/index.ts b/packages/communication/src/messages/incoming/callforhelp/index.ts new file mode 100644 index 0000000..9b60cfb --- /dev/null +++ b/packages/communication/src/messages/incoming/callforhelp/index.ts @@ -0,0 +1,3 @@ +export * from './CfhSanctionMessageEvent'; +export * from './CfhTopicsInitEvent'; +export * from './SanctionStatusEvent'; diff --git a/packages/communication/src/messages/incoming/camera/CameraPublishStatusMessageEvent.ts b/packages/communication/src/messages/incoming/camera/CameraPublishStatusMessageEvent.ts new file mode 100644 index 0000000..21a95a4 --- /dev/null +++ b/packages/communication/src/messages/incoming/camera/CameraPublishStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CameraPublishStatusMessageParser } from '../../parser'; + +export class CameraPublishStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CameraPublishStatusMessageParser); + } + + public getParser(): CameraPublishStatusMessageParser + { + return this.parser as CameraPublishStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/camera/CameraPurchaseOKMessageEvent.ts b/packages/communication/src/messages/incoming/camera/CameraPurchaseOKMessageEvent.ts new file mode 100644 index 0000000..22efe88 --- /dev/null +++ b/packages/communication/src/messages/incoming/camera/CameraPurchaseOKMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CameraPurchaseOKMessageParser } from '../../parser'; + +export class CameraPurchaseOKMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CameraPurchaseOKMessageParser); + } + + public getParser(): CameraPurchaseOKMessageParser + { + return this.parser as CameraPurchaseOKMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/camera/CameraSnapshotMessageEvent.ts b/packages/communication/src/messages/incoming/camera/CameraSnapshotMessageEvent.ts new file mode 100644 index 0000000..921bbe8 --- /dev/null +++ b/packages/communication/src/messages/incoming/camera/CameraSnapshotMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CameraSnapshotMessageParser } from '../../parser'; + +export class CameraSnapshotMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CameraSnapshotMessageParser); + } + + public getParser(): CameraSnapshotMessageParser + { + return this.parser as CameraSnapshotMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/camera/CameraStorageUrlMessageEvent.ts b/packages/communication/src/messages/incoming/camera/CameraStorageUrlMessageEvent.ts new file mode 100644 index 0000000..d123d6e --- /dev/null +++ b/packages/communication/src/messages/incoming/camera/CameraStorageUrlMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CameraStorageUrlMessageParser } from '../../parser'; + +export class CameraStorageUrlMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CameraStorageUrlMessageParser); + } + + public getParser(): CameraStorageUrlMessageParser + { + return this.parser as CameraStorageUrlMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/camera/CompetitionStatusMessageEvent.ts b/packages/communication/src/messages/incoming/camera/CompetitionStatusMessageEvent.ts new file mode 100644 index 0000000..21fc635 --- /dev/null +++ b/packages/communication/src/messages/incoming/camera/CompetitionStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CompetitionStatusMessageParser } from '../../parser'; + +export class CompetitionStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CompetitionStatusMessageParser); + } + + public getParser(): CompetitionStatusMessageParser + { + return this.parser as CompetitionStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/camera/InitCameraMessageEvent.ts b/packages/communication/src/messages/incoming/camera/InitCameraMessageEvent.ts new file mode 100644 index 0000000..6fbe482 --- /dev/null +++ b/packages/communication/src/messages/incoming/camera/InitCameraMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { InitCameraMessageParser } from '../../parser'; + +export class InitCameraMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, InitCameraMessageParser); + } + + public getParser(): InitCameraMessageParser + { + return this.parser as InitCameraMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/camera/ThumbnailStatusMessageEvent.ts b/packages/communication/src/messages/incoming/camera/ThumbnailStatusMessageEvent.ts new file mode 100644 index 0000000..7adb729 --- /dev/null +++ b/packages/communication/src/messages/incoming/camera/ThumbnailStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ThumbnailStatusMessageParser } from '../../parser'; + +export class ThumbnailStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ThumbnailStatusMessageParser); + } + + public getParser(): ThumbnailStatusMessageParser + { + return this.parser as ThumbnailStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/camera/index.ts b/packages/communication/src/messages/incoming/camera/index.ts new file mode 100644 index 0000000..03df06b --- /dev/null +++ b/packages/communication/src/messages/incoming/camera/index.ts @@ -0,0 +1,7 @@ +export * from './CameraPublishStatusMessageEvent'; +export * from './CameraPurchaseOKMessageEvent'; +export * from './CameraSnapshotMessageEvent'; +export * from './CameraStorageUrlMessageEvent'; +export * from './CompetitionStatusMessageEvent'; +export * from './InitCameraMessageEvent'; +export * from './ThumbnailStatusMessageEvent'; diff --git a/packages/communication/src/messages/incoming/campaign/CampaignCalendarDataMessageEvent.ts b/packages/communication/src/messages/incoming/campaign/CampaignCalendarDataMessageEvent.ts new file mode 100644 index 0000000..4f1da37 --- /dev/null +++ b/packages/communication/src/messages/incoming/campaign/CampaignCalendarDataMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CampaignCalendarDataMessageParser } from '../../parser'; + +export class CampaignCalendarDataMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CampaignCalendarDataMessageParser); + } + + public getParser(): CampaignCalendarDataMessageParser + { + return this.parser as CampaignCalendarDataMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/campaign/CampaignCalendarDoorOpenedMessageEvent.ts b/packages/communication/src/messages/incoming/campaign/CampaignCalendarDoorOpenedMessageEvent.ts new file mode 100644 index 0000000..70d660d --- /dev/null +++ b/packages/communication/src/messages/incoming/campaign/CampaignCalendarDoorOpenedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CampaignCalendarDoorOpenedMessageParser } from '../../parser'; + +export class CampaignCalendarDoorOpenedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CampaignCalendarDoorOpenedMessageParser); + } + + public getParser(): CampaignCalendarDoorOpenedMessageParser + { + return this.parser as CampaignCalendarDoorOpenedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/campaign/index.ts b/packages/communication/src/messages/incoming/campaign/index.ts new file mode 100644 index 0000000..a6263ae --- /dev/null +++ b/packages/communication/src/messages/incoming/campaign/index.ts @@ -0,0 +1,2 @@ +export * from './CampaignCalendarDataMessageEvent'; +export * from './CampaignCalendarDoorOpenedMessageEvent'; diff --git a/packages/communication/src/messages/incoming/catalog/BonusRareInfoMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/BonusRareInfoMessageEvent.ts new file mode 100644 index 0000000..efc19c3 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/BonusRareInfoMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BonusRareInfoMessageParser } from '../../parser'; + +export class BonusRareInfoMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BonusRareInfoMessageParser); + } + + public getParser(): BonusRareInfoMessageParser + { + return this.parser as BonusRareInfoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/BuildersClubFurniCountMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/BuildersClubFurniCountMessageEvent.ts new file mode 100644 index 0000000..33c7c6e --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/BuildersClubFurniCountMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BuildersClubFurniCountMessageParser } from '../../parser'; + +export class BuildersClubFurniCountMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BuildersClubFurniCountMessageParser); + } + + public getParser(): BuildersClubFurniCountMessageParser + { + return this.parser as BuildersClubFurniCountMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/BuildersClubSubscriptionStatusMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/BuildersClubSubscriptionStatusMessageEvent.ts new file mode 100644 index 0000000..0de5ba0 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/BuildersClubSubscriptionStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BuildersClubSubscriptionStatusMessageParser } from '../../parser'; + +export class BuildersClubSubscriptionStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BuildersClubSubscriptionStatusMessageParser); + } + + public getParser(): BuildersClubSubscriptionStatusMessageParser + { + return this.parser as BuildersClubSubscriptionStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/BundleDiscountRulesetMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/BundleDiscountRulesetMessageEvent.ts new file mode 100644 index 0000000..cf70c1c --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/BundleDiscountRulesetMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BundleDiscountRulesetMessageParser } from '../../parser'; + +export class BundleDiscountRulesetMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BundleDiscountRulesetMessageParser); + } + + public getParser(): BundleDiscountRulesetMessageParser + { + return this.parser as BundleDiscountRulesetMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/CatalogPageExpirationEvent.ts b/packages/communication/src/messages/incoming/catalog/CatalogPageExpirationEvent.ts new file mode 100644 index 0000000..1093a3c --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/CatalogPageExpirationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CatalogPageExpirationParser } from '../../parser'; + +export class CatalogPageExpirationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogPageExpirationParser); + } + + public getParser(): CatalogPageExpirationParser + { + return this.parser as CatalogPageExpirationParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/CatalogPageMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/CatalogPageMessageEvent.ts new file mode 100644 index 0000000..437fb8f --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/CatalogPageMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CatalogPageMessageParser } from '../../parser'; + +export class CatalogPageMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogPageMessageParser); + } + + public getParser(): CatalogPageMessageParser + { + return this.parser as CatalogPageMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/CatalogPageWithEarliestExpiryMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/CatalogPageWithEarliestExpiryMessageEvent.ts new file mode 100644 index 0000000..4868360 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/CatalogPageWithEarliestExpiryMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CatalogPageWithEarliestExpiryMessageParser } from '../../parser'; + +export class CatalogPageWithEarliestExpiryMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogPageWithEarliestExpiryMessageParser); + } + + public getParser(): CatalogPageWithEarliestExpiryMessageParser + { + return this.parser as CatalogPageWithEarliestExpiryMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/CatalogPagesListEvent.ts b/packages/communication/src/messages/incoming/catalog/CatalogPagesListEvent.ts new file mode 100644 index 0000000..4baad7a --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/CatalogPagesListEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CatalogIndexMessageParser } from '../../parser'; + +export class CatalogPagesListEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogIndexMessageParser); + } + + public getParser(): CatalogIndexMessageParser + { + return this.parser as CatalogIndexMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/CatalogPublishedMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/CatalogPublishedMessageEvent.ts new file mode 100644 index 0000000..5b8cdab --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/CatalogPublishedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CatalogPublishedMessageParser } from '../../parser'; + +export class CatalogPublishedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogPublishedMessageParser); + } + + public getParser(): CatalogPublishedMessageParser + { + return this.parser as CatalogPublishedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/ClubGiftInfoEvent.ts b/packages/communication/src/messages/incoming/catalog/ClubGiftInfoEvent.ts new file mode 100644 index 0000000..d604afd --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/ClubGiftInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ClubGiftInfoParser } from '../../parser'; + +export class ClubGiftInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ClubGiftInfoParser); + } + + public getParser(): ClubGiftInfoParser + { + return this.parser as ClubGiftInfoParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/ClubGiftSelectedEvent.ts b/packages/communication/src/messages/incoming/catalog/ClubGiftSelectedEvent.ts new file mode 100644 index 0000000..08afb29 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/ClubGiftSelectedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ClubGiftSelectedParser } from '../../parser'; + +export class ClubGiftSelectedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ClubGiftSelectedParser); + } + + public getParser(): ClubGiftSelectedParser + { + return this.parser as ClubGiftSelectedParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/DirectSMSClubBuyAvailableMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/DirectSMSClubBuyAvailableMessageEvent.ts new file mode 100644 index 0000000..8e073bd --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/DirectSMSClubBuyAvailableMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { DirectSMSClubBuyAvailableMessageParser } from '../../parser'; + +export class DirectSMSClubBuyAvailableMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, DirectSMSClubBuyAvailableMessageParser); + } + + public getParser(): DirectSMSClubBuyAvailableMessageParser + { + return this.parser as DirectSMSClubBuyAvailableMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/FireworkChargeDataEvent.ts b/packages/communication/src/messages/incoming/catalog/FireworkChargeDataEvent.ts new file mode 100644 index 0000000..a79da5d --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/FireworkChargeDataEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FireworkChargeDataParser } from '../../parser'; + +export class FireworkChargeDataEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FireworkChargeDataParser); + } + + public getParser(): FireworkChargeDataParser + { + return this.parser as FireworkChargeDataParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/GiftReceiverNotFoundEvent.ts b/packages/communication/src/messages/incoming/catalog/GiftReceiverNotFoundEvent.ts new file mode 100644 index 0000000..cb3d7dc --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/GiftReceiverNotFoundEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GiftReceiverNotFoundParser } from '../../parser'; + +export class GiftReceiverNotFoundEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GiftReceiverNotFoundParser); + } + + public getParser(): GiftReceiverNotFoundParser + { + return this.parser as GiftReceiverNotFoundParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/GiftWrappingConfigurationEvent.ts b/packages/communication/src/messages/incoming/catalog/GiftWrappingConfigurationEvent.ts new file mode 100644 index 0000000..16ef9e8 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/GiftWrappingConfigurationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GiftWrappingConfigurationParser } from '../../parser'; + +export class GiftWrappingConfigurationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GiftWrappingConfigurationParser); + } + + public getParser(): GiftWrappingConfigurationParser + { + return this.parser as GiftWrappingConfigurationParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/HabboClubExtendOfferMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/HabboClubExtendOfferMessageEvent.ts new file mode 100644 index 0000000..331acc2 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/HabboClubExtendOfferMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HabboClubExtendOfferMessageParser } from '../../parser'; + +export class HabboClubExtendOfferMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HabboClubExtendOfferMessageParser); + } + + public getParser(): HabboClubExtendOfferMessageParser + { + return this.parser as HabboClubExtendOfferMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/HabboClubOffersMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/HabboClubOffersMessageEvent.ts new file mode 100644 index 0000000..dc92866 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/HabboClubOffersMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HabboClubOffersMessageParser } from '../../parser'; + +export class HabboClubOffersMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HabboClubOffersMessageParser); + } + + public getParser(): HabboClubOffersMessageParser + { + return this.parser as HabboClubOffersMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/IsOfferGiftableMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/IsOfferGiftableMessageEvent.ts new file mode 100644 index 0000000..55bcaae --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/IsOfferGiftableMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { IsOfferGiftableMessageParser } from '../../parser'; + +export class IsOfferGiftableMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IsOfferGiftableMessageParser); + } + + public getParser(): IsOfferGiftableMessageParser + { + return this.parser as IsOfferGiftableMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/LimitedEditionSoldOutEvent.ts b/packages/communication/src/messages/incoming/catalog/LimitedEditionSoldOutEvent.ts new file mode 100644 index 0000000..42791b5 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/LimitedEditionSoldOutEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { LimitedEditionSoldOutParser } from '../../parser'; + +export class LimitedEditionSoldOutEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LimitedEditionSoldOutParser); + } + + public getParser(): LimitedEditionSoldOutParser + { + return this.parser as LimitedEditionSoldOutParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/LimitedOfferAppearingNextMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/LimitedOfferAppearingNextMessageEvent.ts new file mode 100644 index 0000000..00ad392 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/LimitedOfferAppearingNextMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { LimitedOfferAppearingNextMessageParser } from '../../parser'; + +export class LimitedOfferAppearingNextMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LimitedOfferAppearingNextMessageParser); + } + + public getParser(): LimitedOfferAppearingNextMessageParser + { + return this.parser as LimitedOfferAppearingNextMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/NotEnoughBalanceMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/NotEnoughBalanceMessageEvent.ts new file mode 100644 index 0000000..14bd25b --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/NotEnoughBalanceMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NotEnoughBalanceMessageParser } from '../../parser'; + +export class NotEnoughBalanceMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NotEnoughBalanceMessageParser); + } + + public getParser(): NotEnoughBalanceMessageParser + { + return this.parser as NotEnoughBalanceMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/ProductOfferEvent.ts b/packages/communication/src/messages/incoming/catalog/ProductOfferEvent.ts new file mode 100644 index 0000000..0778949 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/ProductOfferEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ProductOfferMessageParser } from '../../parser'; + +export class ProductOfferEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ProductOfferMessageParser); + } + + public getParser(): ProductOfferMessageParser + { + return this.parser as ProductOfferMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/PurchaseErrorMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/PurchaseErrorMessageEvent.ts new file mode 100644 index 0000000..9fb533e --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/PurchaseErrorMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PurchaseErrorMessageParser } from '../../parser'; + +export class PurchaseErrorMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PurchaseErrorMessageParser); + } + + public getParser(): PurchaseErrorMessageParser + { + return this.parser as PurchaseErrorMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/PurchaseNotAllowedMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/PurchaseNotAllowedMessageEvent.ts new file mode 100644 index 0000000..399f822 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/PurchaseNotAllowedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PurchaseNotAllowedMessageParser } from '../../parser'; + +export class PurchaseNotAllowedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PurchaseNotAllowedMessageParser); + } + + public getParser(): PurchaseNotAllowedMessageParser + { + return this.parser as PurchaseNotAllowedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/PurchaseOKMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/PurchaseOKMessageEvent.ts new file mode 100644 index 0000000..9c2e6b5 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/PurchaseOKMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PurchaseOKMessageParser } from '../../parser'; + +export class PurchaseOKMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PurchaseOKMessageParser); + } + + public getParser(): PurchaseOKMessageParser + { + return this.parser as PurchaseOKMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/RoomAdPurchaseInfoEvent.ts b/packages/communication/src/messages/incoming/catalog/RoomAdPurchaseInfoEvent.ts new file mode 100644 index 0000000..38c0b5f --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/RoomAdPurchaseInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomAdPurchaseInfoEventParser } from '../../parser'; + +export class RoomAdPurchaseInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomAdPurchaseInfoEventParser); + } + + public getParser(): RoomAdPurchaseInfoEventParser + { + return this.parser as RoomAdPurchaseInfoEventParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/SeasonalCalendarDailyOfferMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/SeasonalCalendarDailyOfferMessageEvent.ts new file mode 100644 index 0000000..f39f26e --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/SeasonalCalendarDailyOfferMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { SeasonalCalendarDailyOfferMessageParser } from '../../parser'; + +export class SeasonalCalendarDailyOfferMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, SeasonalCalendarDailyOfferMessageParser); + } + + public getParser(): SeasonalCalendarDailyOfferMessageParser + { + return this.parser as SeasonalCalendarDailyOfferMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/SellablePetPalettesMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/SellablePetPalettesMessageEvent.ts new file mode 100644 index 0000000..0da7215 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/SellablePetPalettesMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { SellablePetPalettesParser } from '../../parser'; + +export class SellablePetPalettesMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, SellablePetPalettesParser); + } + + public getParser(): SellablePetPalettesParser + { + return this.parser as SellablePetPalettesParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/TargetedOfferEvent.ts b/packages/communication/src/messages/incoming/catalog/TargetedOfferEvent.ts new file mode 100644 index 0000000..633484b --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/TargetedOfferEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TargetedOfferParser } from '../../parser'; + +export class TargetedOfferEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TargetedOfferParser); + } + + public getParser(): TargetedOfferParser + { + return this.parser as TargetedOfferParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/TargetedOfferNotFoundEvent.ts b/packages/communication/src/messages/incoming/catalog/TargetedOfferNotFoundEvent.ts new file mode 100644 index 0000000..2d7e743 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/TargetedOfferNotFoundEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TargetedOfferNotFoundParser } from '../../parser'; + +export class TargetedOfferNotFoundEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TargetedOfferNotFoundParser); + } + + public getParser(): TargetedOfferNotFoundParser + { + return this.parser as TargetedOfferNotFoundParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/VoucherRedeemErrorMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/VoucherRedeemErrorMessageEvent.ts new file mode 100644 index 0000000..b3d8e4b --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/VoucherRedeemErrorMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { VoucherRedeemErrorMessageParser } from '../../parser'; + +export class VoucherRedeemErrorMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, VoucherRedeemErrorMessageParser); + } + + public getParser(): VoucherRedeemErrorMessageParser + { + return this.parser as VoucherRedeemErrorMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/VoucherRedeemOkMessageEvent.ts b/packages/communication/src/messages/incoming/catalog/VoucherRedeemOkMessageEvent.ts new file mode 100644 index 0000000..6717243 --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/VoucherRedeemOkMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { VoucherRedeemOkMessageParser } from '../../parser'; + +export class VoucherRedeemOkMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, VoucherRedeemOkMessageParser); + } + + public getParser(): VoucherRedeemOkMessageParser + { + return this.parser as VoucherRedeemOkMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/catalog/index.ts b/packages/communication/src/messages/incoming/catalog/index.ts new file mode 100644 index 0000000..c7a281c --- /dev/null +++ b/packages/communication/src/messages/incoming/catalog/index.ts @@ -0,0 +1,32 @@ +export * from './BonusRareInfoMessageEvent'; +export * from './BuildersClubFurniCountMessageEvent'; +export * from './BuildersClubSubscriptionStatusMessageEvent'; +export * from './BundleDiscountRulesetMessageEvent'; +export * from './CatalogPageExpirationEvent'; +export * from './CatalogPageMessageEvent'; +export * from './CatalogPagesListEvent'; +export * from './CatalogPageWithEarliestExpiryMessageEvent'; +export * from './CatalogPublishedMessageEvent'; +export * from './ClubGiftInfoEvent'; +export * from './ClubGiftSelectedEvent'; +export * from './DirectSMSClubBuyAvailableMessageEvent'; +export * from './FireworkChargeDataEvent'; +export * from './GiftReceiverNotFoundEvent'; +export * from './GiftWrappingConfigurationEvent'; +export * from './HabboClubExtendOfferMessageEvent'; +export * from './HabboClubOffersMessageEvent'; +export * from './IsOfferGiftableMessageEvent'; +export * from './LimitedEditionSoldOutEvent'; +export * from './LimitedOfferAppearingNextMessageEvent'; +export * from './NotEnoughBalanceMessageEvent'; +export * from './ProductOfferEvent'; +export * from './PurchaseErrorMessageEvent'; +export * from './PurchaseNotAllowedMessageEvent'; +export * from './PurchaseOKMessageEvent'; +export * from './RoomAdPurchaseInfoEvent'; +export * from './SeasonalCalendarDailyOfferMessageEvent'; +export * from './SellablePetPalettesMessageEvent'; +export * from './TargetedOfferEvent'; +export * from './TargetedOfferNotFoundEvent'; +export * from './VoucherRedeemErrorMessageEvent'; +export * from './VoucherRedeemOkMessageEvent'; diff --git a/packages/communication/src/messages/incoming/client/ClientPingEvent.ts b/packages/communication/src/messages/incoming/client/ClientPingEvent.ts new file mode 100644 index 0000000..38b063f --- /dev/null +++ b/packages/communication/src/messages/incoming/client/ClientPingEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ClientPingParser } from '../../parser'; + +export class ClientPingEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ClientPingParser); + } + + public getParser(): ClientPingParser + { + return this.parser as ClientPingParser; + } +} diff --git a/packages/communication/src/messages/incoming/client/index.ts b/packages/communication/src/messages/incoming/client/index.ts new file mode 100644 index 0000000..deaf34e --- /dev/null +++ b/packages/communication/src/messages/incoming/client/index.ts @@ -0,0 +1 @@ +export * from './ClientPingEvent'; diff --git a/packages/communication/src/messages/incoming/competition/CompetitionEntrySubmitResultEvent.ts b/packages/communication/src/messages/incoming/competition/CompetitionEntrySubmitResultEvent.ts new file mode 100644 index 0000000..e38ab0e --- /dev/null +++ b/packages/communication/src/messages/incoming/competition/CompetitionEntrySubmitResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CompetitionEntrySubmitResultMessageParser } from '../../parser'; + +export class CompetitionEntrySubmitResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CompetitionEntrySubmitResultMessageParser); + } + + public getParser(): CompetitionEntrySubmitResultMessageParser + { + return this.parser as CompetitionEntrySubmitResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/competition/CompetitionVotingInfoMessageEvent.ts b/packages/communication/src/messages/incoming/competition/CompetitionVotingInfoMessageEvent.ts new file mode 100644 index 0000000..a1b2b77 --- /dev/null +++ b/packages/communication/src/messages/incoming/competition/CompetitionVotingInfoMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CompetitionVotingInfoMessageParser } from '../../parser'; + +export class CompetitionVotingInfoMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CompetitionVotingInfoMessageParser); + } + + public getParser(): CompetitionVotingInfoMessageParser + { + return this.parser as CompetitionVotingInfoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/competition/CurrentTimingCodeMessageEvent.ts b/packages/communication/src/messages/incoming/competition/CurrentTimingCodeMessageEvent.ts new file mode 100644 index 0000000..9842f77 --- /dev/null +++ b/packages/communication/src/messages/incoming/competition/CurrentTimingCodeMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CurrentTimingCodeMessageParser } from '../../parser'; + +export class CurrentTimingCodeMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CurrentTimingCodeMessageParser); + } + + public getParser(): CurrentTimingCodeMessageParser + { + return this.parser as CurrentTimingCodeMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/competition/IsUserPartOfCompetitionMessageEvent.ts b/packages/communication/src/messages/incoming/competition/IsUserPartOfCompetitionMessageEvent.ts new file mode 100644 index 0000000..331ee20 --- /dev/null +++ b/packages/communication/src/messages/incoming/competition/IsUserPartOfCompetitionMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { IsUserPartOfCompetitionMessageParser } from '../../parser'; + +export class IsUserPartOfCompetitionMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IsUserPartOfCompetitionMessageParser); + } + + public getParser(): IsUserPartOfCompetitionMessageParser + { + return this.parser as IsUserPartOfCompetitionMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/competition/NoOwnedRoomsAlertMessageEvent.ts b/packages/communication/src/messages/incoming/competition/NoOwnedRoomsAlertMessageEvent.ts new file mode 100644 index 0000000..000cb7d --- /dev/null +++ b/packages/communication/src/messages/incoming/competition/NoOwnedRoomsAlertMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NoOwnedRoomsAlertMessageParser } from '../../parser'; + +export class NoOwnedRoomsAlertMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NoOwnedRoomsAlertMessageParser); + } + + public getParser(): NoOwnedRoomsAlertMessageParser + { + return this.parser as NoOwnedRoomsAlertMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/competition/SecondsUntilMessageEvent.ts b/packages/communication/src/messages/incoming/competition/SecondsUntilMessageEvent.ts new file mode 100644 index 0000000..5691262 --- /dev/null +++ b/packages/communication/src/messages/incoming/competition/SecondsUntilMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { SecondsUntilMessageParser } from '../../parser'; + +export class SecondsUntilMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, SecondsUntilMessageParser); + } + + public getParser(): SecondsUntilMessageParser + { + return this.parser as SecondsUntilMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/competition/index.ts b/packages/communication/src/messages/incoming/competition/index.ts new file mode 100644 index 0000000..7c2b70a --- /dev/null +++ b/packages/communication/src/messages/incoming/competition/index.ts @@ -0,0 +1,6 @@ +export * from './CompetitionEntrySubmitResultEvent'; +export * from './CompetitionVotingInfoMessageEvent'; +export * from './CurrentTimingCodeMessageEvent'; +export * from './IsUserPartOfCompetitionMessageEvent'; +export * from './NoOwnedRoomsAlertMessageEvent'; +export * from './SecondsUntilMessageEvent'; diff --git a/packages/communication/src/messages/incoming/crafting/CraftableProductsEvent.ts b/packages/communication/src/messages/incoming/crafting/CraftableProductsEvent.ts new file mode 100644 index 0000000..d186c19 --- /dev/null +++ b/packages/communication/src/messages/incoming/crafting/CraftableProductsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CraftableProductsMessageParser } from '../../parser'; + +export class CraftableProductsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CraftableProductsMessageParser); + } + + public getParser(): CraftableProductsMessageParser + { + return this.parser as CraftableProductsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/crafting/CraftingRecipeEvent.ts b/packages/communication/src/messages/incoming/crafting/CraftingRecipeEvent.ts new file mode 100644 index 0000000..c7ebd4a --- /dev/null +++ b/packages/communication/src/messages/incoming/crafting/CraftingRecipeEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CraftingRecipeMessageParser } from '../../parser'; + +export class CraftingRecipeEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CraftingRecipeMessageParser); + } + + public getParser(): CraftingRecipeMessageParser + { + return this.parser as CraftingRecipeMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/crafting/CraftingRecipesAvailableEvent.ts b/packages/communication/src/messages/incoming/crafting/CraftingRecipesAvailableEvent.ts new file mode 100644 index 0000000..b8497c2 --- /dev/null +++ b/packages/communication/src/messages/incoming/crafting/CraftingRecipesAvailableEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CraftingRecipesAvailableMessageParser } from '../../parser'; + +export class CraftingRecipesAvailableEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CraftingRecipesAvailableMessageParser); + } + + public getParser(): CraftingRecipesAvailableMessageParser + { + return this.parser as CraftingRecipesAvailableMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/crafting/CraftingResultEvent.ts b/packages/communication/src/messages/incoming/crafting/CraftingResultEvent.ts new file mode 100644 index 0000000..91ec874 --- /dev/null +++ b/packages/communication/src/messages/incoming/crafting/CraftingResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CraftingResultMessageParser } from '../../parser'; + +export class CraftingResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CraftingResultMessageParser); + } + + public getParser(): CraftingResultMessageParser + { + return this.parser as CraftingResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/crafting/index.ts b/packages/communication/src/messages/incoming/crafting/index.ts new file mode 100644 index 0000000..cf26449 --- /dev/null +++ b/packages/communication/src/messages/incoming/crafting/index.ts @@ -0,0 +1,4 @@ +export * from './CraftableProductsEvent'; +export * from './CraftingRecipeEvent'; +export * from './CraftingRecipesAvailableEvent'; +export * from './CraftingResultEvent'; diff --git a/packages/communication/src/messages/incoming/desktop/DesktopViewEvent.ts b/packages/communication/src/messages/incoming/desktop/DesktopViewEvent.ts new file mode 100644 index 0000000..31bc346 --- /dev/null +++ b/packages/communication/src/messages/incoming/desktop/DesktopViewEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { DesktopViewParser } from '../../parser'; + +export class DesktopViewEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, DesktopViewParser); + } + + public getParser(): DesktopViewParser + { + return this.parser as DesktopViewParser; + } +} diff --git a/packages/communication/src/messages/incoming/desktop/index.ts b/packages/communication/src/messages/incoming/desktop/index.ts new file mode 100644 index 0000000..2c0758c --- /dev/null +++ b/packages/communication/src/messages/incoming/desktop/index.ts @@ -0,0 +1 @@ +export * from './DesktopViewEvent'; diff --git a/packages/communication/src/messages/incoming/friendlist/AcceptFriendResultEvent.ts b/packages/communication/src/messages/incoming/friendlist/AcceptFriendResultEvent.ts new file mode 100644 index 0000000..a87e4e8 --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/AcceptFriendResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AcceptFriendResultParser } from '../../parser'; + +export class AcceptFriendResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AcceptFriendResultParser); + } + + public getParser(): AcceptFriendResultParser + { + return this.parser as AcceptFriendResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/FindFriendsProcessResultEvent.ts b/packages/communication/src/messages/incoming/friendlist/FindFriendsProcessResultEvent.ts new file mode 100644 index 0000000..70cd013 --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/FindFriendsProcessResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FindFriendsProcessResultParser } from '../../parser'; + +export class FindFriendsProcessResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FindFriendsProcessResultParser); + } + + public getParser(): FindFriendsProcessResultParser + { + return this.parser as FindFriendsProcessResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/FollowFriendFailedEvent.ts b/packages/communication/src/messages/incoming/friendlist/FollowFriendFailedEvent.ts new file mode 100644 index 0000000..2e6eb5e --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/FollowFriendFailedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FollowFriendFailedParser } from '../../parser'; + +export class FollowFriendFailedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FollowFriendFailedParser); + } + + public getParser(): FollowFriendFailedParser + { + return this.parser as FollowFriendFailedParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/FriendListFragmentEvent.ts b/packages/communication/src/messages/incoming/friendlist/FriendListFragmentEvent.ts new file mode 100644 index 0000000..2ddc473 --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/FriendListFragmentEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FriendListFragmentParser } from '../../parser'; + +export class FriendListFragmentEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FriendListFragmentParser); + } + + public getParser(): FriendListFragmentParser + { + return this.parser as FriendListFragmentParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/FriendListUpdateEvent.ts b/packages/communication/src/messages/incoming/friendlist/FriendListUpdateEvent.ts new file mode 100644 index 0000000..b5a1bda --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/FriendListUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FriendListUpdateParser } from '../../parser'; + +export class FriendListUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FriendListUpdateParser); + } + + public getParser(): FriendListUpdateParser + { + return this.parser as FriendListUpdateParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/FriendNotificationEvent.ts b/packages/communication/src/messages/incoming/friendlist/FriendNotificationEvent.ts new file mode 100644 index 0000000..0f5f7e3 --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/FriendNotificationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FriendNotificationParser } from '../../parser'; + +export class FriendNotificationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FriendNotificationParser); + } + + public getParser(): FriendNotificationParser + { + return this.parser as FriendNotificationParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/FriendRequestsEvent.ts b/packages/communication/src/messages/incoming/friendlist/FriendRequestsEvent.ts new file mode 100644 index 0000000..5ddf0e0 --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/FriendRequestsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FriendRequestsParser } from '../../parser'; + +export class FriendRequestsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FriendRequestsParser); + } + + public getParser(): FriendRequestsParser + { + return this.parser as FriendRequestsParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/HabboSearchResultEvent.ts b/packages/communication/src/messages/incoming/friendlist/HabboSearchResultEvent.ts new file mode 100644 index 0000000..ed49241 --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/HabboSearchResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HabboSearchResultParser } from '../../parser'; + +export class HabboSearchResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HabboSearchResultParser); + } + + public getParser(): HabboSearchResultParser + { + return this.parser as HabboSearchResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/InstantMessageErrorEvent.ts b/packages/communication/src/messages/incoming/friendlist/InstantMessageErrorEvent.ts new file mode 100644 index 0000000..61ef0db --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/InstantMessageErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { InstantMessageErrorParser } from '../../parser'; + +export class InstantMessageErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, InstantMessageErrorParser); + } + + public getParser(): InstantMessageErrorParser + { + return this.parser as InstantMessageErrorParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/MessageErrorEvent.ts b/packages/communication/src/messages/incoming/friendlist/MessageErrorEvent.ts new file mode 100644 index 0000000..bbeb6a7 --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/MessageErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MessageErrorParser } from '../../parser'; + +export class MessageErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MessageErrorParser); + } + + public getParser(): MessageErrorParser + { + return this.parser as MessageErrorParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/MessengerInitEvent.ts b/packages/communication/src/messages/incoming/friendlist/MessengerInitEvent.ts new file mode 100644 index 0000000..da8320c --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/MessengerInitEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MessengerInitParser } from '../../parser'; + +export class MessengerInitEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MessengerInitParser); + } + + public getParser(): MessengerInitParser + { + return this.parser as MessengerInitParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/MiniMailNewMessageEvent.ts b/packages/communication/src/messages/incoming/friendlist/MiniMailNewMessageEvent.ts new file mode 100644 index 0000000..35bc9eb --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/MiniMailNewMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MiniMailNewMessageParser } from '../../parser'; + +export class MiniMailNewMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MiniMailNewMessageParser); + } + + public getParser(): MiniMailNewMessageParser + { + return this.parser as MiniMailNewMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/MiniMailUnreadCountEvent.ts b/packages/communication/src/messages/incoming/friendlist/MiniMailUnreadCountEvent.ts new file mode 100644 index 0000000..8a78238 --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/MiniMailUnreadCountEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MiniMailUnreadCountParser } from '../../parser'; + +export class MiniMailUnreadCountEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MiniMailUnreadCountParser); + } + + public getParser(): MiniMailUnreadCountParser + { + return this.parser as MiniMailUnreadCountParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/NewConsoleMessageEvent.ts b/packages/communication/src/messages/incoming/friendlist/NewConsoleMessageEvent.ts new file mode 100644 index 0000000..c88687f --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/NewConsoleMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NewConsoleMessageParser } from '../../parser'; + +export class NewConsoleMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NewConsoleMessageParser); + } + + public getParser(): NewConsoleMessageParser + { + return this.parser as NewConsoleMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/NewFriendRequestEvent.ts b/packages/communication/src/messages/incoming/friendlist/NewFriendRequestEvent.ts new file mode 100644 index 0000000..58a875f --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/NewFriendRequestEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NewFriendRequestParser } from '../../parser'; + +export class NewFriendRequestEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NewFriendRequestParser); + } + + public getParser(): NewFriendRequestParser + { + return this.parser as NewFriendRequestParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/RoomInviteErrorEvent.ts b/packages/communication/src/messages/incoming/friendlist/RoomInviteErrorEvent.ts new file mode 100644 index 0000000..80f56d9 --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/RoomInviteErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomInviteErrorParser } from '../../parser'; + +export class RoomInviteErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomInviteErrorParser); + } + + public getParser(): RoomInviteErrorParser + { + return this.parser as RoomInviteErrorParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/RoomInviteEvent.ts b/packages/communication/src/messages/incoming/friendlist/RoomInviteEvent.ts new file mode 100644 index 0000000..26faa00 --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/RoomInviteEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomInviteParser } from '../../parser'; + +export class RoomInviteEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomInviteParser); + } + + public getParser(): RoomInviteParser + { + return this.parser as RoomInviteParser; + } +} diff --git a/packages/communication/src/messages/incoming/friendlist/index.ts b/packages/communication/src/messages/incoming/friendlist/index.ts new file mode 100644 index 0000000..47c991c --- /dev/null +++ b/packages/communication/src/messages/incoming/friendlist/index.ts @@ -0,0 +1,17 @@ +export * from './AcceptFriendResultEvent'; +export * from './FindFriendsProcessResultEvent'; +export * from './FollowFriendFailedEvent'; +export * from './FriendListFragmentEvent'; +export * from './FriendListUpdateEvent'; +export * from './FriendNotificationEvent'; +export * from './FriendRequestsEvent'; +export * from './HabboSearchResultEvent'; +export * from './InstantMessageErrorEvent'; +export * from './MessageErrorEvent'; +export * from './MessengerInitEvent'; +export * from './MiniMailNewMessageEvent'; +export * from './MiniMailUnreadCountEvent'; +export * from './NewConsoleMessageEvent'; +export * from './NewFriendRequestEvent'; +export * from './RoomInviteErrorEvent'; +export * from './RoomInviteEvent'; diff --git a/packages/communication/src/messages/incoming/game/directory/Game2AccountGameStatusMessageEvent.ts b/packages/communication/src/messages/incoming/game/directory/Game2AccountGameStatusMessageEvent.ts new file mode 100644 index 0000000..b7789f7 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/directory/Game2AccountGameStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2AccountGameStatusMessageParser } from '../../../parser'; + +export class Game2AccountGameStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2AccountGameStatusMessageParser); + } + + public getParser(): Game2AccountGameStatusMessageParser + { + return this.parser as Game2AccountGameStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/directory/Game2GameDirectoryStatusMessageEvent.ts b/packages/communication/src/messages/incoming/game/directory/Game2GameDirectoryStatusMessageEvent.ts new file mode 100644 index 0000000..0707c99 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/directory/Game2GameDirectoryStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2GameDirectoryStatusMessageParser } from '../../../parser'; + +export class Game2GameDirectoryStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2GameDirectoryStatusMessageParser); + } + + public getParser(): Game2GameDirectoryStatusMessageParser + { + return this.parser as Game2GameDirectoryStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/directory/Game2InArenaQueueMessageEvent.ts b/packages/communication/src/messages/incoming/game/directory/Game2InArenaQueueMessageEvent.ts new file mode 100644 index 0000000..de7ef5d --- /dev/null +++ b/packages/communication/src/messages/incoming/game/directory/Game2InArenaQueueMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2InArenaQueueMessageParser } from '../../../parser'; + +export class Game2InArenaQueueMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2InArenaQueueMessageParser); + } + + public getParser(): Game2InArenaQueueMessageParser + { + return this.parser as Game2InArenaQueueMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/directory/Game2JoiningGameFailedMessageEvent.ts b/packages/communication/src/messages/incoming/game/directory/Game2JoiningGameFailedMessageEvent.ts new file mode 100644 index 0000000..134f7d2 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/directory/Game2JoiningGameFailedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2JoiningGameFailedMessageParser } from '../../../parser'; + +export class Game2JoiningGameFailedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2JoiningGameFailedMessageParser); + } + + public getParser(): Game2JoiningGameFailedMessageParser + { + return this.parser as Game2JoiningGameFailedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/directory/Game2StartingGameFailedMessageEvent.ts b/packages/communication/src/messages/incoming/game/directory/Game2StartingGameFailedMessageEvent.ts new file mode 100644 index 0000000..f52bc24 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/directory/Game2StartingGameFailedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2StartingGameFailedMessageParser } from '../../../parser'; + +export class Game2StartingGameFailedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2StartingGameFailedMessageParser); + } + + public getParser(): Game2StartingGameFailedMessageParser + { + return this.parser as Game2StartingGameFailedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/directory/Game2StopCounterMessageEvent.ts b/packages/communication/src/messages/incoming/game/directory/Game2StopCounterMessageEvent.ts new file mode 100644 index 0000000..b12d81b --- /dev/null +++ b/packages/communication/src/messages/incoming/game/directory/Game2StopCounterMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2InArenaQueueMessageParser, Game2StopCounterMessageParser } from '../../../parser'; + +export class Game2StopCounterMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2StopCounterMessageParser); + } + + public getParser(): Game2InArenaQueueMessageParser + { + return this.parser as Game2InArenaQueueMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/directory/Game2UserLeftGameMessageEvent.ts b/packages/communication/src/messages/incoming/game/directory/Game2UserLeftGameMessageEvent.ts new file mode 100644 index 0000000..b949573 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/directory/Game2UserLeftGameMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2UserLeftGameMessageParser } from '../../../parser'; + +export class Game2UserLeftGameMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2UserLeftGameMessageParser); + } + + public getParser(): Game2UserLeftGameMessageParser + { + return this.parser as Game2UserLeftGameMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/directory/index.ts b/packages/communication/src/messages/incoming/game/directory/index.ts new file mode 100644 index 0000000..8724315 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/directory/index.ts @@ -0,0 +1,7 @@ +export * from './Game2AccountGameStatusMessageEvent'; +export * from './Game2GameDirectoryStatusMessageEvent'; +export * from './Game2InArenaQueueMessageEvent'; +export * from './Game2JoiningGameFailedMessageEvent'; +export * from './Game2StartingGameFailedMessageEvent'; +export * from './Game2StopCounterMessageEvent'; +export * from './Game2UserLeftGameMessageEvent'; diff --git a/packages/communication/src/messages/incoming/game/index.ts b/packages/communication/src/messages/incoming/game/index.ts new file mode 100644 index 0000000..779f388 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/index.ts @@ -0,0 +1,3 @@ +export * from './directory'; +export * from './lobby'; +export * from './score'; diff --git a/packages/communication/src/messages/incoming/game/lobby/AchievementResolutionCompletedMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/AchievementResolutionCompletedMessageEvent.ts new file mode 100644 index 0000000..55223fc --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/AchievementResolutionCompletedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AchievementResolutionCompletedMessageParser } from '../../../parser'; + +export class AchievementResolutionCompletedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AchievementResolutionCompletedMessageParser); + } + + public getParser(): AchievementResolutionCompletedMessageParser + { + return this.parser as AchievementResolutionCompletedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/AchievementResolutionProgressMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/AchievementResolutionProgressMessageEvent.ts new file mode 100644 index 0000000..03a0b43 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/AchievementResolutionProgressMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AchievementResolutionProgressMessageParser } from '../../../parser'; + +export class AchievementResolutionProgressMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AchievementResolutionProgressMessageParser); + } + + public getParser(): AchievementResolutionProgressMessageParser + { + return this.parser as AchievementResolutionProgressMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/AchievementResolutionsMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/AchievementResolutionsMessageEvent.ts new file mode 100644 index 0000000..fffd7ac --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/AchievementResolutionsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AchievementResolutionsMessageParser } from '../../../parser'; + +export class AchievementResolutionsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AchievementResolutionsMessageParser); + } + + public getParser(): AchievementResolutionsMessageParser + { + return this.parser as AchievementResolutionsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/GameAchievementsMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/GameAchievementsMessageEvent.ts new file mode 100644 index 0000000..cb6cebd --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/GameAchievementsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GameAchievementsMessageParser } from '../../../parser'; + +export class GameAchievementsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GameAchievementsMessageParser); + } + + public getParser(): GameAchievementsMessageParser + { + return this.parser as GameAchievementsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/GameInviteMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/GameInviteMessageEvent.ts new file mode 100644 index 0000000..53c1dc8 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/GameInviteMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GameInviteMessageParser } from '../../../parser'; + +export class GameInviteMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GameInviteMessageParser); + } + + public getParser(): GameInviteMessageParser + { + return this.parser as GameInviteMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/GameListMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/GameListMessageEvent.ts new file mode 100644 index 0000000..c628ece --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/GameListMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GameListMessageParser } from '../../../parser'; + +export class GameListMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GameListMessageParser); + } + + public getParser(): GameListMessageParser + { + return this.parser as GameListMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/GameStatusMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/GameStatusMessageEvent.ts new file mode 100644 index 0000000..a75e148 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/GameStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GameStatusMessageParser } from '../../../parser'; + +export class GameStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GameStatusMessageParser); + } + + public getParser(): GameStatusMessageParser + { + return this.parser as GameStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/JoinedQueueMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/JoinedQueueMessageEvent.ts new file mode 100644 index 0000000..56dc1f6 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/JoinedQueueMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { JoinedQueueMessageParser } from '../../../parser'; + +export class JoinedQueueMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, JoinedQueueMessageParser); + } + + public getParser(): JoinedQueueMessageParser + { + return this.parser as JoinedQueueMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/JoiningQueueFailedMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/JoiningQueueFailedMessageEvent.ts new file mode 100644 index 0000000..7eb147b --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/JoiningQueueFailedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { JoiningQueueFailedMessageParser } from '../../../parser'; + +export class JoiningQueueFailedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, JoiningQueueFailedMessageParser); + } + + public getParser(): JoiningQueueFailedMessageParser + { + return this.parser as JoiningQueueFailedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/LeftQueueMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/LeftQueueMessageEvent.ts new file mode 100644 index 0000000..8f970ed --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/LeftQueueMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { LeftQueueMessageParser } from '../../../parser'; + +export class LeftQueueMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LeftQueueMessageParser); + } + + public getParser(): LeftQueueMessageParser + { + return this.parser as LeftQueueMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/LoadGameMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/LoadGameMessageEvent.ts new file mode 100644 index 0000000..73ba11c --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/LoadGameMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { LoadGameMessageParser } from '../../../parser'; + +export class LoadGameMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LoadGameMessageParser); + } + + public getParser(): LoadGameMessageParser + { + return this.parser as LoadGameMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/LoadGameUrlEvent.ts b/packages/communication/src/messages/incoming/game/lobby/LoadGameUrlEvent.ts new file mode 100644 index 0000000..a2abde1 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/LoadGameUrlEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { LoadGameUrlParser } from '../../../parser'; + +export class LoadGameUrlEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LoadGameUrlParser); + } + + public getParser(): LoadGameUrlParser + { + return this.parser as LoadGameUrlParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/UnloadGameMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/UnloadGameMessageEvent.ts new file mode 100644 index 0000000..7681a28 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/UnloadGameMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UnloadGameMessageParser } from '../../../parser'; + +export class UnloadGameMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UnloadGameMessageParser); + } + + public getParser(): UnloadGameMessageParser + { + return this.parser as UnloadGameMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/UserGameAchievementsMessageEvent.ts b/packages/communication/src/messages/incoming/game/lobby/UserGameAchievementsMessageEvent.ts new file mode 100644 index 0000000..b89ef68 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/UserGameAchievementsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserGameAchievementsMessageParser } from '../../../parser'; + +export class UserGameAchievementsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserGameAchievementsMessageParser); + } + + public getParser(): UserGameAchievementsMessageParser + { + return this.parser as UserGameAchievementsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/lobby/index.ts b/packages/communication/src/messages/incoming/game/lobby/index.ts new file mode 100644 index 0000000..13421db --- /dev/null +++ b/packages/communication/src/messages/incoming/game/lobby/index.ts @@ -0,0 +1,14 @@ +export * from './AchievementResolutionCompletedMessageEvent'; +export * from './AchievementResolutionProgressMessageEvent'; +export * from './AchievementResolutionsMessageEvent'; +export * from './GameAchievementsMessageEvent'; +export * from './GameInviteMessageEvent'; +export * from './GameListMessageEvent'; +export * from './GameStatusMessageEvent'; +export * from './JoinedQueueMessageEvent'; +export * from './JoiningQueueFailedMessageEvent'; +export * from './LeftQueueMessageEvent'; +export * from './LoadGameMessageEvent'; +export * from './LoadGameUrlEvent'; +export * from './UnloadGameMessageEvent'; +export * from './UserGameAchievementsMessageEvent'; diff --git a/packages/communication/src/messages/incoming/game/score/Game2WeeklyFriendsLeaderboardEvent.ts b/packages/communication/src/messages/incoming/game/score/Game2WeeklyFriendsLeaderboardEvent.ts new file mode 100644 index 0000000..bd2edf3 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/score/Game2WeeklyFriendsLeaderboardEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2WeeklyLeaderboardParser } from '../../../parser'; + +export class Game2WeeklyFriendsLeaderboardEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2WeeklyLeaderboardParser); + } + + public getParser(): Game2WeeklyLeaderboardParser + { + return this.parser as Game2WeeklyLeaderboardParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/score/Game2WeeklyLeaderboardEvent.ts b/packages/communication/src/messages/incoming/game/score/Game2WeeklyLeaderboardEvent.ts new file mode 100644 index 0000000..1a18abd --- /dev/null +++ b/packages/communication/src/messages/incoming/game/score/Game2WeeklyLeaderboardEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2WeeklyLeaderboardParser } from '../../../parser'; + +export class Game2WeeklyLeaderboardEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2WeeklyLeaderboardParser); + } + + public getParser(): Game2WeeklyLeaderboardParser + { + return this.parser as Game2WeeklyLeaderboardParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/score/WeeklyCompetitiveFriendsLeaderboardEvent.ts b/packages/communication/src/messages/incoming/game/score/WeeklyCompetitiveFriendsLeaderboardEvent.ts new file mode 100644 index 0000000..280cccf --- /dev/null +++ b/packages/communication/src/messages/incoming/game/score/WeeklyCompetitiveFriendsLeaderboardEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2WeeklyLeaderboardParser } from '../../../parser'; + +export class WeeklyCompetitiveFriendsLeaderboardEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2WeeklyLeaderboardParser); + } + + public getParser(): Game2WeeklyLeaderboardParser + { + return this.parser as Game2WeeklyLeaderboardParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/score/WeeklyCompetitiveLeaderboardEvent.ts b/packages/communication/src/messages/incoming/game/score/WeeklyCompetitiveLeaderboardEvent.ts new file mode 100644 index 0000000..bcc73bf --- /dev/null +++ b/packages/communication/src/messages/incoming/game/score/WeeklyCompetitiveLeaderboardEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { Game2WeeklyLeaderboardParser } from '../../../parser'; + +export class WeeklyCompetitiveLeaderboardEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, Game2WeeklyLeaderboardParser); + } + + public getParser(): Game2WeeklyLeaderboardParser + { + return this.parser as Game2WeeklyLeaderboardParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/score/WeeklyGameRewardEvent.ts b/packages/communication/src/messages/incoming/game/score/WeeklyGameRewardEvent.ts new file mode 100644 index 0000000..7aa8531 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/score/WeeklyGameRewardEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WeeklyGameRewardParser } from '../../../parser'; + +export class WeeklyGameRewardEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WeeklyGameRewardParser); + } + + public getParser(): WeeklyGameRewardParser + { + return this.parser as WeeklyGameRewardParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/score/WeeklyGameRewardWinnersEvent.ts b/packages/communication/src/messages/incoming/game/score/WeeklyGameRewardWinnersEvent.ts new file mode 100644 index 0000000..5a18a10 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/score/WeeklyGameRewardWinnersEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WeeklyGameRewardWinnersParser } from '../../../parser'; + +export class WeeklyGameRewardWinnersEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WeeklyGameRewardWinnersParser); + } + + public getParser(): WeeklyGameRewardWinnersParser + { + return this.parser as WeeklyGameRewardWinnersParser; + } +} diff --git a/packages/communication/src/messages/incoming/game/score/index.ts b/packages/communication/src/messages/incoming/game/score/index.ts new file mode 100644 index 0000000..546b5a3 --- /dev/null +++ b/packages/communication/src/messages/incoming/game/score/index.ts @@ -0,0 +1,6 @@ +export * from './Game2WeeklyFriendsLeaderboardEvent'; +export * from './Game2WeeklyLeaderboardEvent'; +export * from './WeeklyCompetitiveFriendsLeaderboardEvent'; +export * from './WeeklyCompetitiveLeaderboardEvent'; +export * from './WeeklyGameRewardEvent'; +export * from './WeeklyGameRewardWinnersEvent'; diff --git a/packages/communication/src/messages/incoming/generic/GenericErrorEvent.ts b/packages/communication/src/messages/incoming/generic/GenericErrorEvent.ts new file mode 100644 index 0000000..9ac6bc4 --- /dev/null +++ b/packages/communication/src/messages/incoming/generic/GenericErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GenericErrorParser } from '../../parser'; + +export class GenericErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GenericErrorParser); + } + + public getParser(): GenericErrorParser + { + return this.parser as GenericErrorParser; + } +} diff --git a/packages/communication/src/messages/incoming/generic/index.ts b/packages/communication/src/messages/incoming/generic/index.ts new file mode 100644 index 0000000..08ed38e --- /dev/null +++ b/packages/communication/src/messages/incoming/generic/index.ts @@ -0,0 +1 @@ +export * from './GenericErrorEvent'; diff --git a/packages/communication/src/messages/incoming/gifts/PhoneCollectionStateMessageEvent.ts b/packages/communication/src/messages/incoming/gifts/PhoneCollectionStateMessageEvent.ts new file mode 100644 index 0000000..40a6832 --- /dev/null +++ b/packages/communication/src/messages/incoming/gifts/PhoneCollectionStateMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PhoneCollectionStateParser } from '../../parser'; + +export class PhoneCollectionStateMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PhoneCollectionStateParser); + } + + public getParser(): PhoneCollectionStateParser + { + return this.parser as PhoneCollectionStateParser; + } +} diff --git a/packages/communication/src/messages/incoming/gifts/TryPhoneNumberResultMessageEvent.ts b/packages/communication/src/messages/incoming/gifts/TryPhoneNumberResultMessageEvent.ts new file mode 100644 index 0000000..08999f2 --- /dev/null +++ b/packages/communication/src/messages/incoming/gifts/TryPhoneNumberResultMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TryPhoneNumberResultParser } from '../../parser'; + +export class TryPhoneNumberResultMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TryPhoneNumberResultParser); + } + + public getParser(): TryPhoneNumberResultParser + { + return this.parser as TryPhoneNumberResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/gifts/TryVerificationCodeResultMessageEvent.ts b/packages/communication/src/messages/incoming/gifts/TryVerificationCodeResultMessageEvent.ts new file mode 100644 index 0000000..5ad52a2 --- /dev/null +++ b/packages/communication/src/messages/incoming/gifts/TryVerificationCodeResultMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TryVerificationCodeResultParser } from '../../parser'; + +export class TryVerificationCodeResultMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TryVerificationCodeResultParser); + } + + public getParser(): TryVerificationCodeResultParser + { + return this.parser as TryVerificationCodeResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/gifts/index.ts b/packages/communication/src/messages/incoming/gifts/index.ts new file mode 100644 index 0000000..ee498b9 --- /dev/null +++ b/packages/communication/src/messages/incoming/gifts/index.ts @@ -0,0 +1,3 @@ +export * from './PhoneCollectionStateMessageEvent'; +export * from './TryPhoneNumberResultMessageEvent'; +export * from './TryVerificationCodeResultMessageEvent'; diff --git a/packages/communication/src/messages/incoming/group/GroupBadgePartsEvent.ts b/packages/communication/src/messages/incoming/group/GroupBadgePartsEvent.ts new file mode 100644 index 0000000..b4bebd7 --- /dev/null +++ b/packages/communication/src/messages/incoming/group/GroupBadgePartsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GroupBadgePartsParser } from '../../parser'; + +export class GroupBadgePartsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupBadgePartsParser); + } + + public getParser(): GroupBadgePartsParser + { + return this.parser as GroupBadgePartsParser; + } +} diff --git a/packages/communication/src/messages/incoming/group/GroupBuyDataEvent.ts b/packages/communication/src/messages/incoming/group/GroupBuyDataEvent.ts new file mode 100644 index 0000000..8452ad6 --- /dev/null +++ b/packages/communication/src/messages/incoming/group/GroupBuyDataEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GroupBuyDataParser } from '../../parser'; + +export class GroupBuyDataEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupBuyDataParser); + } + + public getParser(): GroupBuyDataParser + { + return this.parser as GroupBuyDataParser; + } +} diff --git a/packages/communication/src/messages/incoming/group/GroupConfirmMemberRemoveEvent.ts b/packages/communication/src/messages/incoming/group/GroupConfirmMemberRemoveEvent.ts new file mode 100644 index 0000000..f85f919 --- /dev/null +++ b/packages/communication/src/messages/incoming/group/GroupConfirmMemberRemoveEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GroupConfirmMemberRemoveParser } from '../../parser'; + +export class GroupConfirmMemberRemoveEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupConfirmMemberRemoveParser); + } + + public getParser(): GroupConfirmMemberRemoveParser + { + return this.parser as GroupConfirmMemberRemoveParser; + } +} diff --git a/packages/communication/src/messages/incoming/group/GroupInformationEvent.ts b/packages/communication/src/messages/incoming/group/GroupInformationEvent.ts new file mode 100644 index 0000000..7ede203 --- /dev/null +++ b/packages/communication/src/messages/incoming/group/GroupInformationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GroupInformationParser } from '../../parser'; + +export class GroupInformationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupInformationParser); + } + + public getParser(): GroupInformationParser + { + return this.parser as GroupInformationParser; + } +} diff --git a/packages/communication/src/messages/incoming/group/GroupMembersEvent.ts b/packages/communication/src/messages/incoming/group/GroupMembersEvent.ts new file mode 100644 index 0000000..660561b --- /dev/null +++ b/packages/communication/src/messages/incoming/group/GroupMembersEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GroupMembersParser } from '../../parser'; + +export class GroupMembersEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupMembersParser); + } + + public getParser(): GroupMembersParser + { + return this.parser as GroupMembersParser; + } +} diff --git a/packages/communication/src/messages/incoming/group/GroupPurchasedEvent.ts b/packages/communication/src/messages/incoming/group/GroupPurchasedEvent.ts new file mode 100644 index 0000000..469b417 --- /dev/null +++ b/packages/communication/src/messages/incoming/group/GroupPurchasedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GroupPurchasedParser } from '../../parser'; + +export class GroupPurchasedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupPurchasedParser); + } + + public getParser(): GroupPurchasedParser + { + return this.parser as GroupPurchasedParser; + } +} diff --git a/packages/communication/src/messages/incoming/group/GroupSettingsEvent.ts b/packages/communication/src/messages/incoming/group/GroupSettingsEvent.ts new file mode 100644 index 0000000..b8f895a --- /dev/null +++ b/packages/communication/src/messages/incoming/group/GroupSettingsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GroupSettingsParser } from '../../parser'; + +export class GroupSettingsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupSettingsParser); + } + + public getParser(): GroupSettingsParser + { + return this.parser as GroupSettingsParser; + } +} diff --git a/packages/communication/src/messages/incoming/group/HabboGroupDeactivatedMessageEvent.ts b/packages/communication/src/messages/incoming/group/HabboGroupDeactivatedMessageEvent.ts new file mode 100644 index 0000000..ff2090b --- /dev/null +++ b/packages/communication/src/messages/incoming/group/HabboGroupDeactivatedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HabboGroupDeactivatedMessageParser } from '../../parser'; + +export class HabboGroupDeactivatedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HabboGroupDeactivatedMessageParser); + } + + public getParser(): HabboGroupDeactivatedMessageParser + { + return this.parser as HabboGroupDeactivatedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/group/index.ts b/packages/communication/src/messages/incoming/group/index.ts new file mode 100644 index 0000000..5fc4853 --- /dev/null +++ b/packages/communication/src/messages/incoming/group/index.ts @@ -0,0 +1,8 @@ +export * from './GroupBadgePartsEvent'; +export * from './GroupBuyDataEvent'; +export * from './GroupConfirmMemberRemoveEvent'; +export * from './GroupInformationEvent'; +export * from './GroupMembersEvent'; +export * from './GroupPurchasedEvent'; +export * from './GroupSettingsEvent'; +export * from './HabboGroupDeactivatedMessageEvent'; diff --git a/packages/communication/src/messages/incoming/groupforums/ForumDataMessageEvent.ts b/packages/communication/src/messages/incoming/groupforums/ForumDataMessageEvent.ts new file mode 100644 index 0000000..9bd073b --- /dev/null +++ b/packages/communication/src/messages/incoming/groupforums/ForumDataMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ForumDataMessageParser } from '../../parser'; + +export class ForumDataMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ForumDataMessageParser); + } + + public getParser(): ForumDataMessageParser + { + return this.parser as ForumDataMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/groupforums/ForumsListMessageEvent.ts b/packages/communication/src/messages/incoming/groupforums/ForumsListMessageEvent.ts new file mode 100644 index 0000000..7d8553f --- /dev/null +++ b/packages/communication/src/messages/incoming/groupforums/ForumsListMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GetForumsListMessageParser } from '../../parser'; + +export class ForumsListMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GetForumsListMessageParser); + } + + public getParser(): GetForumsListMessageParser + { + return this.parser as GetForumsListMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/groupforums/GuildForumThreadsEvent.ts b/packages/communication/src/messages/incoming/groupforums/GuildForumThreadsEvent.ts new file mode 100644 index 0000000..171685b --- /dev/null +++ b/packages/communication/src/messages/incoming/groupforums/GuildForumThreadsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuildForumThreadsParser } from '../../parser'; + +export class GuildForumThreadsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuildForumThreadsParser); + } + + public getParser(): GuildForumThreadsParser + { + return this.parser as GuildForumThreadsParser; + } +} diff --git a/packages/communication/src/messages/incoming/groupforums/PostMessageMessageEvent.ts b/packages/communication/src/messages/incoming/groupforums/PostMessageMessageEvent.ts new file mode 100644 index 0000000..76bc553 --- /dev/null +++ b/packages/communication/src/messages/incoming/groupforums/PostMessageMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PostMessageMessageParser } from '../../parser'; + +export class PostMessageMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PostMessageMessageParser); + } + + public getParser(): PostMessageMessageParser + { + return this.parser as PostMessageMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/groupforums/PostThreadMessageEvent.ts b/packages/communication/src/messages/incoming/groupforums/PostThreadMessageEvent.ts new file mode 100644 index 0000000..caa22c8 --- /dev/null +++ b/packages/communication/src/messages/incoming/groupforums/PostThreadMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PostThreadMessageParser } from '../../parser'; + +export class PostThreadMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PostThreadMessageParser); + } + + public getParser(): PostThreadMessageParser + { + return this.parser as PostThreadMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/groupforums/ThreadMessagesMessageEvent.ts b/packages/communication/src/messages/incoming/groupforums/ThreadMessagesMessageEvent.ts new file mode 100644 index 0000000..0665d88 --- /dev/null +++ b/packages/communication/src/messages/incoming/groupforums/ThreadMessagesMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ThreadMessagesMessageParser } from '../../parser'; + +export class ThreadMessagesMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ThreadMessagesMessageParser); + } + + public getParser(): ThreadMessagesMessageParser + { + return this.parser as ThreadMessagesMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/groupforums/UnreadForumsCountMessageEvent.ts b/packages/communication/src/messages/incoming/groupforums/UnreadForumsCountMessageEvent.ts new file mode 100644 index 0000000..2284ccc --- /dev/null +++ b/packages/communication/src/messages/incoming/groupforums/UnreadForumsCountMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UnreadForumsCountMessageParser } from '../../parser'; + +export class UnreadForumsCountMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UnreadForumsCountMessageParser); + } + + public getParser(): UnreadForumsCountMessageParser + { + return this.parser as UnreadForumsCountMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/groupforums/UpdateMessageMessageEvent.ts b/packages/communication/src/messages/incoming/groupforums/UpdateMessageMessageEvent.ts new file mode 100644 index 0000000..b7a9684 --- /dev/null +++ b/packages/communication/src/messages/incoming/groupforums/UpdateMessageMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UpdateMessageMessageParser } from '../../parser'; + +export class UpdateMessageMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UpdateMessageMessageParser); + } + + public getParser(): UpdateMessageMessageParser + { + return this.parser as UpdateMessageMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/groupforums/UpdateThreadMessageEvent.ts b/packages/communication/src/messages/incoming/groupforums/UpdateThreadMessageEvent.ts new file mode 100644 index 0000000..2a834c5 --- /dev/null +++ b/packages/communication/src/messages/incoming/groupforums/UpdateThreadMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UpdateThreadMessageParser } from '../../parser'; + +export class UpdateThreadMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UpdateThreadMessageParser); + } + + public getParser(): UpdateThreadMessageParser + { + return this.parser as UpdateThreadMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/groupforums/index.ts b/packages/communication/src/messages/incoming/groupforums/index.ts new file mode 100644 index 0000000..53566b9 --- /dev/null +++ b/packages/communication/src/messages/incoming/groupforums/index.ts @@ -0,0 +1,9 @@ +export * from './ForumDataMessageEvent'; +export * from './ForumsListMessageEvent'; +export * from './GuildForumThreadsEvent'; +export * from './PostMessageMessageEvent'; +export * from './PostThreadMessageEvent'; +export * from './ThreadMessagesMessageEvent'; +export * from './UnreadForumsCountMessageEvent'; +export * from './UpdateMessageMessageEvent'; +export * from './UpdateThreadMessageEvent'; diff --git a/packages/communication/src/messages/incoming/handshake/CompleteDiffieHandshakeEvent.ts b/packages/communication/src/messages/incoming/handshake/CompleteDiffieHandshakeEvent.ts new file mode 100644 index 0000000..3256284 --- /dev/null +++ b/packages/communication/src/messages/incoming/handshake/CompleteDiffieHandshakeEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CompleteDiffieHandshakeParser } from '../../parser'; + +export class CompleteDiffieHandshakeEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CompleteDiffieHandshakeParser); + } + + public getParser(): CompleteDiffieHandshakeParser + { + return this.parser as CompleteDiffieHandshakeParser; + } +} diff --git a/packages/communication/src/messages/incoming/handshake/DisconnectReasonEnum.ts b/packages/communication/src/messages/incoming/handshake/DisconnectReasonEnum.ts new file mode 100644 index 0000000..dcd50df --- /dev/null +++ b/packages/communication/src/messages/incoming/handshake/DisconnectReasonEnum.ts @@ -0,0 +1,46 @@ +export class DisconnectReasonEnum +{ + public static readonly LOGOUT: number = 0; + public static readonly JUST_BANNED: number = 1; + public static readonly CONCURRENT_LOGIN: number = 2; + public static readonly CONNECTION_LOST_TO_PEER: number = 3; + public static readonly AVATAR_IDENTITY_CHANGE: number = 4; + public static readonly REMOVE_FURNITURE_TOOL: number = 5; + public static readonly STILL_BANNED: number = 10; + public static readonly DUAL_LOGIN_BY_USERID: number = 11; + public static readonly HOTEL_CLOSED: number = 12; + public static readonly DUAL_LOGIN_BY_IP: number = 13; + public static readonly PEER_CONNECTION_MISSING: number = 16; + public static readonly NO_LOGIN_PERMISSION: number = 17; + public static readonly DUPLICATE_CONNECTION: number = 18; + public static readonly HOTEL_CLOSING: number = 19; + public static readonly INCORRECT_PASSWORD: number = 20; + public static readonly INVALID_LOGIN_TICKET: number = 22; + public static readonly VERSION_CHECK_URL: number = 23; + public static readonly VERSION_CHECK_PROPERTY: number = 24; + public static readonly VERSION_CHECK_MACHINE_ID: number = 25; + public static readonly NO_MESSENGER_SESSION: number = 26; + public static readonly USER_NOT_FOUND: number = 27; + public static readonly CRYPTO_NOT_INITIALIZED: number = 28; + public static readonly DEV_CRYPTO_NOT_ALLOWED: number = 29; + public static readonly DUPLICATE_UUID_DETECTED: number = 100; + public static readonly OLD_SESSION_IN_PROXY: number = 101; + public static readonly PUBLIC_KEY_NOT_NUMERIC: number = 102; + public static readonly PUBLIC_KEY_TOO_SHORT: number = 103; + public static readonly SOCKET_READ_GENERIC: number = 104; + public static readonly SOCKET_READ_FIRST_BYTE: number = 105; + public static readonly SOCKET_READ_LENGTH: number = 106; + public static readonly SOCKET_READ_BODY: number = 107; + public static readonly SOCKET_READ_POLICY: number = 108; + public static readonly SOCKET_IO_EXCEPTION: number = 109; + public static readonly SOCKET_WRONG_CRYPTO: number = 110; + public static readonly PROXY_RUNTIME_EXCEPTION: number = 111; + public static readonly IDLE_CONNECTION: number = 112; + public static readonly PONG_TIMEOUT: number = 113; + public static readonly IDLE_CONNECTION_NOT_AUTH: number = 114; + public static readonly IDLE_CONNECTION_NO_USER_ID: number = 115; + public static readonly WRITE_CLOSED_CHANNEL: number = 116; + public static readonly SOCKET_WRITE_EXCEPTION_1: number = 117; + public static readonly SOCKET_WRITE_EXCEPTION_2: number = 118; + public static readonly SOCKET_WRITE_EXCEPTION_3: number = 119; +} diff --git a/packages/communication/src/messages/incoming/handshake/DisconnectReasonEvent.ts b/packages/communication/src/messages/incoming/handshake/DisconnectReasonEvent.ts new file mode 100644 index 0000000..07be776 --- /dev/null +++ b/packages/communication/src/messages/incoming/handshake/DisconnectReasonEvent.ts @@ -0,0 +1,33 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { DisconnectReasonParser } from '../../parser'; +import { DisconnectReasonEnum } from './DisconnectReasonEnum'; + +export class DisconnectReasonEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, DisconnectReasonParser); + } + + public getParser(): DisconnectReasonParser + { + return this.parser as DisconnectReasonParser; + } + + public get reasonString(): string + { + switch(this.getParser().reason) + { + case DisconnectReasonEnum.JUST_BANNED: + case DisconnectReasonEnum.STILL_BANNED: + return 'banned'; + case DisconnectReasonEnum.CONCURRENT_LOGIN: + return 'concurrentlogin'; + case DisconnectReasonEnum.INCORRECT_PASSWORD: + return 'incorrectpassword'; + default: + return 'logout'; + } + } +} diff --git a/packages/communication/src/messages/incoming/handshake/IdentityAccountsEvent.ts b/packages/communication/src/messages/incoming/handshake/IdentityAccountsEvent.ts new file mode 100644 index 0000000..b9c74b8 --- /dev/null +++ b/packages/communication/src/messages/incoming/handshake/IdentityAccountsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { IdentityAccountsParser } from '../../parser'; + +export class IdentityAccountsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IdentityAccountsParser); + } + + public getParser(): IdentityAccountsParser + { + return this.parser as IdentityAccountsParser; + } +} diff --git a/packages/communication/src/messages/incoming/handshake/InitDiffieHandshakeEvent.ts b/packages/communication/src/messages/incoming/handshake/InitDiffieHandshakeEvent.ts new file mode 100644 index 0000000..87a57dc --- /dev/null +++ b/packages/communication/src/messages/incoming/handshake/InitDiffieHandshakeEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { InitDiffieHandshakeParser } from '../../parser'; + +export class InitDiffieHandshakeEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, InitDiffieHandshakeParser); + } + + public getParser(): InitDiffieHandshakeParser + { + return this.parser as InitDiffieHandshakeParser; + } +} diff --git a/packages/communication/src/messages/incoming/handshake/NoobnessLevelMessageEvent.ts b/packages/communication/src/messages/incoming/handshake/NoobnessLevelMessageEvent.ts new file mode 100644 index 0000000..72fc16e --- /dev/null +++ b/packages/communication/src/messages/incoming/handshake/NoobnessLevelMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NoobnessLevelMessageParser } from '../../parser'; + +export class NoobnessLevelMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NoobnessLevelMessageParser); + } + + public getParser(): NoobnessLevelMessageParser + { + return this.parser as NoobnessLevelMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/handshake/index.ts b/packages/communication/src/messages/incoming/handshake/index.ts new file mode 100644 index 0000000..81bb67a --- /dev/null +++ b/packages/communication/src/messages/incoming/handshake/index.ts @@ -0,0 +1,6 @@ +export * from './CompleteDiffieHandshakeEvent'; +export * from './DisconnectReasonEnum'; +export * from './DisconnectReasonEvent'; +export * from './IdentityAccountsEvent'; +export * from './InitDiffieHandshakeEvent'; +export * from './NoobnessLevelMessageEvent'; diff --git a/packages/communication/src/messages/incoming/help/CallForHelpDisabledNotifyMessageEvent.ts b/packages/communication/src/messages/incoming/help/CallForHelpDisabledNotifyMessageEvent.ts new file mode 100644 index 0000000..7d8d9d7 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/CallForHelpDisabledNotifyMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CallForHelpDisabledNotifyMessageParser } from '../../parser'; + +export class CallForHelpDisabledNotifyMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CallForHelpDisabledNotifyMessageParser); + } + + public getParser(): CallForHelpDisabledNotifyMessageParser + { + return this.parser as CallForHelpDisabledNotifyMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/CallForHelpPendingCallsDeletedMessageEvent.ts b/packages/communication/src/messages/incoming/help/CallForHelpPendingCallsDeletedMessageEvent.ts new file mode 100644 index 0000000..b43211e --- /dev/null +++ b/packages/communication/src/messages/incoming/help/CallForHelpPendingCallsDeletedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CallForHelpPendingCallsDeletedMessageParser } from '../../parser'; + +export class CallForHelpPendingCallsDeletedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CallForHelpPendingCallsDeletedMessageParser); + } + + public getParser(): CallForHelpPendingCallsDeletedMessageParser + { + return this.parser as CallForHelpPendingCallsDeletedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/CallForHelpPendingCallsMessageEvent.ts b/packages/communication/src/messages/incoming/help/CallForHelpPendingCallsMessageEvent.ts new file mode 100644 index 0000000..c159cb5 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/CallForHelpPendingCallsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CallForHelpPendingCallsMessageParser } from '../../parser'; + +export class CallForHelpPendingCallsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CallForHelpPendingCallsMessageParser); + } + + public getParser(): CallForHelpPendingCallsMessageParser + { + return this.parser as CallForHelpPendingCallsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/CallForHelpReplyMessageEvent.ts b/packages/communication/src/messages/incoming/help/CallForHelpReplyMessageEvent.ts new file mode 100644 index 0000000..9259fca --- /dev/null +++ b/packages/communication/src/messages/incoming/help/CallForHelpReplyMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CallForHelpReplyMessageParser } from '../../parser'; + +export class CallForHelpReplyMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CallForHelpReplyMessageParser); + } + + public getParser(): CallForHelpReplyMessageParser + { + return this.parser as CallForHelpReplyMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/CallForHelpResultMessageEvent.ts b/packages/communication/src/messages/incoming/help/CallForHelpResultMessageEvent.ts new file mode 100644 index 0000000..cc8973f --- /dev/null +++ b/packages/communication/src/messages/incoming/help/CallForHelpResultMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CallForHelpResultMessageParser } from '../../parser'; + +export class CallForHelpResultMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CallForHelpResultMessageParser); + } + + public getParser(): CallForHelpResultMessageParser + { + return this.parser as CallForHelpResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/ChatReviewSessionDetachedMessageEvent.ts b/packages/communication/src/messages/incoming/help/ChatReviewSessionDetachedMessageEvent.ts new file mode 100644 index 0000000..90f558e --- /dev/null +++ b/packages/communication/src/messages/incoming/help/ChatReviewSessionDetachedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ChatReviewSessionDetachedMessageParser } from '../../parser'; + +export class ChatReviewSessionDetachedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ChatReviewSessionDetachedMessageParser); + } + + public getParser(): ChatReviewSessionDetachedMessageParser + { + return this.parser as ChatReviewSessionDetachedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/ChatReviewSessionOfferedToGuideMessageEvent.ts b/packages/communication/src/messages/incoming/help/ChatReviewSessionOfferedToGuideMessageEvent.ts new file mode 100644 index 0000000..89b3d8b --- /dev/null +++ b/packages/communication/src/messages/incoming/help/ChatReviewSessionOfferedToGuideMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ChatReviewSessionOfferedToGuideMessageParser } from '../../parser'; + +export class ChatReviewSessionOfferedToGuideMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ChatReviewSessionOfferedToGuideMessageParser); + } + + public getParser(): ChatReviewSessionOfferedToGuideMessageParser + { + return this.parser as ChatReviewSessionOfferedToGuideMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/ChatReviewSessionResultsMessageEvent.ts b/packages/communication/src/messages/incoming/help/ChatReviewSessionResultsMessageEvent.ts new file mode 100644 index 0000000..8a7149f --- /dev/null +++ b/packages/communication/src/messages/incoming/help/ChatReviewSessionResultsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ChatReviewSessionResultsMessageParser } from '../../parser'; + +export class ChatReviewSessionResultsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ChatReviewSessionResultsMessageParser); + } + + public getParser(): ChatReviewSessionResultsMessageParser + { + return this.parser as ChatReviewSessionResultsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/ChatReviewSessionStartedMessageEvent.ts b/packages/communication/src/messages/incoming/help/ChatReviewSessionStartedMessageEvent.ts new file mode 100644 index 0000000..8252d67 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/ChatReviewSessionStartedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ChatReviewSessionStartedMessageParser } from '../../parser'; + +export class ChatReviewSessionStartedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ChatReviewSessionStartedMessageParser); + } + + public getParser(): ChatReviewSessionStartedMessageParser + { + return this.parser as ChatReviewSessionStartedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/ChatReviewSessionVotingStatusMessageEvent.ts b/packages/communication/src/messages/incoming/help/ChatReviewSessionVotingStatusMessageEvent.ts new file mode 100644 index 0000000..874b35a --- /dev/null +++ b/packages/communication/src/messages/incoming/help/ChatReviewSessionVotingStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ChatReviewSessionVotingStatusMessageParser } from '../../parser'; + +export class ChatReviewSessionVotingStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ChatReviewSessionVotingStatusMessageParser); + } + + public getParser(): ChatReviewSessionVotingStatusMessageParser + { + return this.parser as ChatReviewSessionVotingStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideOnDutyStatusMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideOnDutyStatusMessageEvent.ts new file mode 100644 index 0000000..ab40fd0 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideOnDutyStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideOnDutyStatusMessageParser } from '../../parser'; + +export class GuideOnDutyStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideOnDutyStatusMessageParser); + } + + public getParser(): GuideOnDutyStatusMessageParser + { + return this.parser as GuideOnDutyStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideReportingStatusMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideReportingStatusMessageEvent.ts new file mode 100644 index 0000000..4d5b298 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideReportingStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideReportingStatusMessageParser } from './../../parser'; + +export class GuideReportingStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideReportingStatusMessageParser); + } + + public getParser(): GuideReportingStatusMessageParser + { + return this.parser as GuideReportingStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideSessionAttachedMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideSessionAttachedMessageEvent.ts new file mode 100644 index 0000000..9c3be87 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideSessionAttachedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideSessionAttachedMessageParser } from '../../parser'; + +export class GuideSessionAttachedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideSessionAttachedMessageParser); + } + + public getParser(): GuideSessionAttachedMessageParser + { + return this.parser as GuideSessionAttachedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideSessionDetachedMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideSessionDetachedMessageEvent.ts new file mode 100644 index 0000000..146a49e --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideSessionDetachedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideSessionDetachedMessageParser } from '../../parser'; + +export class GuideSessionDetachedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideSessionDetachedMessageParser); + } + + public getParser(): GuideSessionDetachedMessageParser + { + return this.parser as GuideSessionDetachedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideSessionEndedMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideSessionEndedMessageEvent.ts new file mode 100644 index 0000000..1de4f5c --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideSessionEndedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideSessionEndedMessageParser } from '../../parser'; + +export class GuideSessionEndedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideSessionEndedMessageParser); + } + + public getParser(): GuideSessionEndedMessageParser + { + return this.parser as GuideSessionEndedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideSessionErrorMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideSessionErrorMessageEvent.ts new file mode 100644 index 0000000..b505471 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideSessionErrorMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideSessionErrorMessageParser } from '../../parser'; + +export class GuideSessionErrorMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideSessionErrorMessageParser); + } + + public getParser(): GuideSessionErrorMessageParser + { + return this.parser as GuideSessionErrorMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideSessionInvitedToGuideRoomMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideSessionInvitedToGuideRoomMessageEvent.ts new file mode 100644 index 0000000..ba9e01a --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideSessionInvitedToGuideRoomMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideSessionInvitedToGuideRoomMessageParser } from '../../parser'; + +export class GuideSessionInvitedToGuideRoomMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideSessionInvitedToGuideRoomMessageParser); + } + + public getParser(): GuideSessionInvitedToGuideRoomMessageParser + { + return this.parser as GuideSessionInvitedToGuideRoomMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideSessionMessageMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideSessionMessageMessageEvent.ts new file mode 100644 index 0000000..7e7a2cb --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideSessionMessageMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideSessionMessageMessageParser } from '../../parser'; + +export class GuideSessionMessageMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideSessionMessageMessageParser); + } + + public getParser(): GuideSessionMessageMessageParser + { + return this.parser as GuideSessionMessageMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideSessionPartnerIsTypingMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideSessionPartnerIsTypingMessageEvent.ts new file mode 100644 index 0000000..5406640 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideSessionPartnerIsTypingMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideSessionPartnerIsTypingMessageParser } from '../../parser'; + +export class GuideSessionPartnerIsTypingMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideSessionPartnerIsTypingMessageParser); + } + + public getParser(): GuideSessionPartnerIsTypingMessageParser + { + return this.parser as GuideSessionPartnerIsTypingMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideSessionRequesterRoomMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideSessionRequesterRoomMessageEvent.ts new file mode 100644 index 0000000..3ab6c1c --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideSessionRequesterRoomMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideSessionRequesterRoomMessageParser } from '../../parser'; + +export class GuideSessionRequesterRoomMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideSessionRequesterRoomMessageParser); + } + + public getParser(): GuideSessionRequesterRoomMessageParser + { + return this.parser as GuideSessionRequesterRoomMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideSessionStartedMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideSessionStartedMessageEvent.ts new file mode 100644 index 0000000..1f139d9 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideSessionStartedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideSessionStartedMessageParser } from '../../parser'; + +export class GuideSessionStartedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideSessionStartedMessageParser); + } + + public getParser(): GuideSessionStartedMessageParser + { + return this.parser as GuideSessionStartedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideTicketCreationResultMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideTicketCreationResultMessageEvent.ts new file mode 100644 index 0000000..730f887 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideTicketCreationResultMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideTicketCreationResultMessageParser } from '../../parser'; + +export class GuideTicketCreationResultMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideTicketCreationResultMessageParser); + } + + public getParser(): GuideTicketCreationResultMessageParser + { + return this.parser as GuideTicketCreationResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/GuideTicketResolutionMessageEvent.ts b/packages/communication/src/messages/incoming/help/GuideTicketResolutionMessageEvent.ts new file mode 100644 index 0000000..4e8ae55 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/GuideTicketResolutionMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuideTicketResolutionMessageParser } from '../../parser'; + +export class GuideTicketResolutionMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuideTicketResolutionMessageParser); + } + + public getParser(): GuideTicketResolutionMessageParser + { + return this.parser as GuideTicketResolutionMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/HotelMergeNameChangeEvent.ts b/packages/communication/src/messages/incoming/help/HotelMergeNameChangeEvent.ts new file mode 100644 index 0000000..ab9dd38 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/HotelMergeNameChangeEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HotelMergeNameChangeParser } from '../../parser'; + +export class HotelMergeNameChangeEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HotelMergeNameChangeParser); + } + + public getParser(): HotelMergeNameChangeParser + { + return this.parser as HotelMergeNameChangeParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/IssueCloseNotificationMessageEvent.ts b/packages/communication/src/messages/incoming/help/IssueCloseNotificationMessageEvent.ts new file mode 100644 index 0000000..5610d31 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/IssueCloseNotificationMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { IssueCloseNotificationMessageParser } from '../../parser'; + +export class IssueCloseNotificationMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IssueCloseNotificationMessageParser); + } + + public getParser(): IssueCloseNotificationMessageParser + { + return this.parser as IssueCloseNotificationMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/QuizDataMessageEvent.ts b/packages/communication/src/messages/incoming/help/QuizDataMessageEvent.ts new file mode 100644 index 0000000..6e8c2d4 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/QuizDataMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { QuizDataMessageParser } from '../../parser'; + +export class QuizDataMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, QuizDataMessageParser); + } + + public getParser(): QuizDataMessageParser + { + return this.parser as QuizDataMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/QuizResultsMessageEvent.ts b/packages/communication/src/messages/incoming/help/QuizResultsMessageEvent.ts new file mode 100644 index 0000000..a063136 --- /dev/null +++ b/packages/communication/src/messages/incoming/help/QuizResultsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { QuizResultsMessageParser } from '../../parser'; + +export class QuizResultsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, QuizResultsMessageParser); + } + + public getParser(): QuizResultsMessageParser + { + return this.parser as QuizResultsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/help/index.ts b/packages/communication/src/messages/incoming/help/index.ts new file mode 100644 index 0000000..029319e --- /dev/null +++ b/packages/communication/src/messages/incoming/help/index.ts @@ -0,0 +1,27 @@ +export * from './CallForHelpDisabledNotifyMessageEvent'; +export * from './CallForHelpPendingCallsDeletedMessageEvent'; +export * from './CallForHelpPendingCallsMessageEvent'; +export * from './CallForHelpReplyMessageEvent'; +export * from './CallForHelpResultMessageEvent'; +export * from './ChatReviewSessionDetachedMessageEvent'; +export * from './ChatReviewSessionOfferedToGuideMessageEvent'; +export * from './ChatReviewSessionResultsMessageEvent'; +export * from './ChatReviewSessionStartedMessageEvent'; +export * from './ChatReviewSessionVotingStatusMessageEvent'; +export * from './GuideOnDutyStatusMessageEvent'; +export * from './GuideReportingStatusMessageEvent'; +export * from './GuideSessionAttachedMessageEvent'; +export * from './GuideSessionDetachedMessageEvent'; +export * from './GuideSessionEndedMessageEvent'; +export * from './GuideSessionErrorMessageEvent'; +export * from './GuideSessionInvitedToGuideRoomMessageEvent'; +export * from './GuideSessionMessageMessageEvent'; +export * from './GuideSessionPartnerIsTypingMessageEvent'; +export * from './GuideSessionRequesterRoomMessageEvent'; +export * from './GuideSessionStartedMessageEvent'; +export * from './GuideTicketCreationResultMessageEvent'; +export * from './GuideTicketResolutionMessageEvent'; +export * from './HotelMergeNameChangeEvent'; +export * from './IssueCloseNotificationMessageEvent'; +export * from './QuizDataMessageEvent'; +export * from './QuizResultsMessageEvent'; diff --git a/packages/communication/src/messages/incoming/index.ts b/packages/communication/src/messages/incoming/index.ts new file mode 100644 index 0000000..a247dbc --- /dev/null +++ b/packages/communication/src/messages/incoming/index.ts @@ -0,0 +1,76 @@ +export * from './IncomingHeader'; +export * from './advertisement'; +export * from './availability'; +export * from './avatar'; +export * from './bots'; +export * from './callforhelp'; +export * from './camera'; +export * from './campaign'; +export * from './catalog'; +export * from './client'; +export * from './competition'; +export * from './crafting'; +export * from './desktop'; +export * from './friendlist'; +export * from './game'; +export * from './game/directory'; +export * from './game/lobby'; +export * from './game/score'; +export * from './generic'; +export * from './gifts'; +export * from './group'; +export * from './groupforums'; +export * from './handshake'; +export * from './help'; +export * from './inventory'; +export * from './inventory/achievements'; +export * from './inventory/avatareffect'; +export * from './inventory/badges'; +export * from './inventory/clothes'; +export * from './inventory/furni'; +export * from './inventory/furni/gifts'; +export * from './inventory/pets'; +export * from './inventory/trading'; +export * from './landingview'; +export * from './landingview/votes'; +export * from './marketplace'; +export * from './moderation'; +export * from './mysterybox'; +export * from './navigator'; +export * from './notifications'; +export * from './nux'; +export * from './perk'; +export * from './pet'; +export * from './pet/breeding'; +export * from './poll'; +export * from './quest'; +export * from './recycler'; +export * from './room'; +export * from './room/access'; +export * from './room/access/doorbell'; +export * from './room/access/rights'; +export * from './room/bots'; +export * from './room/data'; +export * from './room/engine'; +export * from './room/furniture'; +export * from './room/furniture/floor'; +export * from './room/furniture/wall'; +export * from './room/furniture/youtube'; +export * from './room/mapping'; +export * from './room/pet'; +export * from './room/session'; +export * from './room/unit'; +export * from './room/unit/chat'; +export * from './roomevents'; +export * from './roomsettings'; +export * from './security'; +export * from './sound'; +export * from './talent'; +export * from './user'; +export * from './user/access'; +export * from './user/data'; +export * from './user/inventory'; +export * from './user/inventory/currency'; +export * from './user/inventory/subscription'; +export * from './user/wardrobe'; +export * from './userclassification'; diff --git a/packages/communication/src/messages/incoming/inventory/achievements/AchievementEvent.ts b/packages/communication/src/messages/incoming/inventory/achievements/AchievementEvent.ts new file mode 100644 index 0000000..6ab0166 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/achievements/AchievementEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AchievementParser } from '../../../parser'; + +export class AchievementEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AchievementParser); + } + + public getParser(): AchievementParser + { + return this.parser as AchievementParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/achievements/AchievementsEvent.ts b/packages/communication/src/messages/incoming/inventory/achievements/AchievementsEvent.ts new file mode 100644 index 0000000..e47ef52 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/achievements/AchievementsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AchievementsParser } from '../../../parser'; + +export class AchievementsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AchievementsParser); + } + + public getParser(): AchievementsParser + { + return this.parser as AchievementsParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/achievements/AchievementsScoreEvent.ts b/packages/communication/src/messages/incoming/inventory/achievements/AchievementsScoreEvent.ts new file mode 100644 index 0000000..dc25c84 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/achievements/AchievementsScoreEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AchievementsScoreParser } from '../../../parser'; + +export class AchievementsScoreEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AchievementsScoreParser); + } + + public getParser(): AchievementsScoreParser + { + return this.parser as AchievementsScoreParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/achievements/index.ts b/packages/communication/src/messages/incoming/inventory/achievements/index.ts new file mode 100644 index 0000000..1344aec --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/achievements/index.ts @@ -0,0 +1,3 @@ +export * from './AchievementEvent'; +export * from './AchievementsEvent'; +export * from './AchievementsScoreEvent'; diff --git a/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectActivatedEvent.ts b/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectActivatedEvent.ts new file mode 100644 index 0000000..74425f2 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectActivatedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AvatarEffectActivatedParser } from '../../../parser'; + +export class AvatarEffectActivatedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvatarEffectActivatedParser); + } + + public getParser(): AvatarEffectActivatedParser + { + return this.parser as AvatarEffectActivatedParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectAddedEvent.ts b/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectAddedEvent.ts new file mode 100644 index 0000000..c5a13cc --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectAddedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AvatarEffectAddedParser } from '../../../parser'; + +export class AvatarEffectAddedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvatarEffectAddedParser); + } + + public getParser(): AvatarEffectAddedParser + { + return this.parser as AvatarEffectAddedParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectExpiredEvent.ts b/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectExpiredEvent.ts new file mode 100644 index 0000000..db2956e --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectExpiredEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AvatarEffectExpiredParser } from '../../../parser'; + +export class AvatarEffectExpiredEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvatarEffectExpiredParser); + } + + public getParser(): AvatarEffectExpiredParser + { + return this.parser as AvatarEffectExpiredParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectSelectedEvent.ts b/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectSelectedEvent.ts new file mode 100644 index 0000000..98e6d61 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectSelectedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AvatarEffectSelectedParser } from '../../../parser'; + +export class AvatarEffectSelectedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvatarEffectSelectedParser); + } + + public getParser(): AvatarEffectSelectedParser + { + return this.parser as AvatarEffectSelectedParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectsEvent.ts b/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectsEvent.ts new file mode 100644 index 0000000..38f2c29 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/avatareffect/AvatarEffectsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AvatarEffectsParser } from '../../../parser'; + +export class AvatarEffectsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvatarEffectsParser); + } + + public getParser(): AvatarEffectsParser + { + return this.parser as AvatarEffectsParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/avatareffect/index.ts b/packages/communication/src/messages/incoming/inventory/avatareffect/index.ts new file mode 100644 index 0000000..4a407ad --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/avatareffect/index.ts @@ -0,0 +1,5 @@ +export * from './AvatarEffectActivatedEvent'; +export * from './AvatarEffectAddedEvent'; +export * from './AvatarEffectExpiredEvent'; +export * from './AvatarEffectSelectedEvent'; +export * from './AvatarEffectsEvent'; diff --git a/packages/communication/src/messages/incoming/inventory/badges/BadgePointLimitsEvent.ts b/packages/communication/src/messages/incoming/inventory/badges/BadgePointLimitsEvent.ts new file mode 100644 index 0000000..16859d5 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/badges/BadgePointLimitsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BadgePointLimitsParser } from '../../../parser'; + +export class BadgePointLimitsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BadgePointLimitsParser); + } + + public getParser(): BadgePointLimitsParser + { + return this.parser as BadgePointLimitsParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/badges/BadgeReceivedEvent.ts b/packages/communication/src/messages/incoming/inventory/badges/BadgeReceivedEvent.ts new file mode 100644 index 0000000..15d9d0c --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/badges/BadgeReceivedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BadgeReceivedParser } from '../../../parser'; + +export class BadgeReceivedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BadgeReceivedParser); + } + + public getParser(): BadgeReceivedParser + { + return this.parser as BadgeReceivedParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/badges/BadgesEvent.ts b/packages/communication/src/messages/incoming/inventory/badges/BadgesEvent.ts new file mode 100644 index 0000000..2062b84 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/badges/BadgesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BadgesParser } from '../../../parser'; + +export class BadgesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BadgesParser); + } + + public getParser(): BadgesParser + { + return this.parser as BadgesParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/badges/IsBadgeRequestFulfilledEvent.ts b/packages/communication/src/messages/incoming/inventory/badges/IsBadgeRequestFulfilledEvent.ts new file mode 100644 index 0000000..c5e1727 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/badges/IsBadgeRequestFulfilledEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { IsBadgeRequestFulfilledParser } from '../../../parser'; + +export class IsBadgeRequestFulfilledEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IsBadgeRequestFulfilledParser); + } + + public getParser(): IsBadgeRequestFulfilledParser + { + return this.parser as IsBadgeRequestFulfilledParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/badges/index.ts b/packages/communication/src/messages/incoming/inventory/badges/index.ts new file mode 100644 index 0000000..fe4c995 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/badges/index.ts @@ -0,0 +1,4 @@ +export * from './BadgePointLimitsEvent'; +export * from './BadgeReceivedEvent'; +export * from './BadgesEvent'; +export * from './IsBadgeRequestFulfilledEvent'; diff --git a/packages/communication/src/messages/incoming/inventory/clothes/FigureSetIdsMessageEvent.ts b/packages/communication/src/messages/incoming/inventory/clothes/FigureSetIdsMessageEvent.ts new file mode 100644 index 0000000..e29c89e --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/clothes/FigureSetIdsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FigureSetIdsMessageParser } from '../../../parser'; + +export class FigureSetIdsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FigureSetIdsMessageParser); + } + + public getParser(): FigureSetIdsMessageParser + { + return this.parser as FigureSetIdsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/clothes/_Str_16135.ts b/packages/communication/src/messages/incoming/inventory/clothes/_Str_16135.ts new file mode 100644 index 0000000..3de88ed --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/clothes/_Str_16135.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { _Str_8728 } from '../../../parser'; + +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; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/clothes/_Str_17532.ts b/packages/communication/src/messages/incoming/inventory/clothes/_Str_17532.ts new file mode 100644 index 0000000..24f64dd --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/clothes/_Str_17532.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { _Str_9021 } from '../../../parser'; + +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; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/clothes/index.ts b/packages/communication/src/messages/incoming/inventory/clothes/index.ts new file mode 100644 index 0000000..477fbf3 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/clothes/index.ts @@ -0,0 +1,3 @@ +export * from './FigureSetIdsMessageEvent'; +export * from './_Str_16135'; +export * from './_Str_17532'; diff --git a/packages/communication/src/messages/incoming/inventory/furni/FurnitureListAddOrUpdateEvent.ts b/packages/communication/src/messages/incoming/inventory/furni/FurnitureListAddOrUpdateEvent.ts new file mode 100644 index 0000000..bdb01b6 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/furni/FurnitureListAddOrUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureListAddOrUpdateParser } from '../../../parser'; + +export class FurnitureListAddOrUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureListAddOrUpdateParser); + } + + public getParser(): FurnitureListAddOrUpdateParser + { + return this.parser as FurnitureListAddOrUpdateParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/furni/FurnitureListEvent.ts b/packages/communication/src/messages/incoming/inventory/furni/FurnitureListEvent.ts new file mode 100644 index 0000000..8e44049 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/furni/FurnitureListEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureListParser } from '../../../parser'; + +export class FurnitureListEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureListParser); + } + + public getParser(): FurnitureListParser + { + return this.parser as FurnitureListParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/furni/FurnitureListInvalidateEvent.ts b/packages/communication/src/messages/incoming/inventory/furni/FurnitureListInvalidateEvent.ts new file mode 100644 index 0000000..f61d0ff --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/furni/FurnitureListInvalidateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureListInvalidateParser } from '../../../parser'; + +export class FurnitureListInvalidateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureListInvalidateParser); + } + + public getParser(): FurnitureListInvalidateParser + { + return this.parser as FurnitureListInvalidateParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/furni/FurnitureListRemovedEvent.ts b/packages/communication/src/messages/incoming/inventory/furni/FurnitureListRemovedEvent.ts new file mode 100644 index 0000000..ebd80f0 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/furni/FurnitureListRemovedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureListRemovedParser } from '../../../parser'; + +export class FurnitureListRemovedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureListRemovedParser); + } + + public getParser(): FurnitureListRemovedParser + { + return this.parser as FurnitureListRemovedParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/furni/FurniturePostItPlacedEvent.ts b/packages/communication/src/messages/incoming/inventory/furni/FurniturePostItPlacedEvent.ts new file mode 100644 index 0000000..a2e9303 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/furni/FurniturePostItPlacedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurniturePostItPlacedParser } from '../../../parser'; + +export class FurniturePostItPlacedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurniturePostItPlacedParser); + } + + public getParser(): FurniturePostItPlacedParser + { + return this.parser as FurniturePostItPlacedParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/furni/gifts/PresentOpenedMessageEvent.ts b/packages/communication/src/messages/incoming/inventory/furni/gifts/PresentOpenedMessageEvent.ts new file mode 100644 index 0000000..a62957d --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/furni/gifts/PresentOpenedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PresentOpenedMessageParser } from '../../../../parser'; + +export class PresentOpenedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PresentOpenedMessageParser); + } + + public getParser(): PresentOpenedMessageParser + { + return this.parser as PresentOpenedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/furni/gifts/index.ts b/packages/communication/src/messages/incoming/inventory/furni/gifts/index.ts new file mode 100644 index 0000000..349aca7 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/furni/gifts/index.ts @@ -0,0 +1 @@ +export * from './PresentOpenedMessageEvent'; diff --git a/packages/communication/src/messages/incoming/inventory/furni/index.ts b/packages/communication/src/messages/incoming/inventory/furni/index.ts new file mode 100644 index 0000000..79c3096 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/furni/index.ts @@ -0,0 +1,6 @@ +export * from './FurnitureListAddOrUpdateEvent'; +export * from './FurnitureListEvent'; +export * from './FurnitureListInvalidateEvent'; +export * from './FurnitureListRemovedEvent'; +export * from './FurniturePostItPlacedEvent'; +export * from './gifts'; diff --git a/packages/communication/src/messages/incoming/inventory/index.ts b/packages/communication/src/messages/incoming/inventory/index.ts new file mode 100644 index 0000000..4f6ae27 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/index.ts @@ -0,0 +1,8 @@ +export * from './achievements'; +export * from './avatareffect'; +export * from './badges'; +export * from './clothes'; +export * from './furni'; +export * from './furni/gifts'; +export * from './pets'; +export * from './trading'; diff --git a/packages/communication/src/messages/incoming/inventory/pets/ConfirmBreedingRequestEvent.ts b/packages/communication/src/messages/incoming/inventory/pets/ConfirmBreedingRequestEvent.ts new file mode 100644 index 0000000..5a07d28 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/pets/ConfirmBreedingRequestEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ConfirmBreedingRequestParser } from '../../../parser'; + +export class ConfirmBreedingRequestEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ConfirmBreedingRequestParser); + } + + public getParser(): ConfirmBreedingRequestParser + { + return this.parser as ConfirmBreedingRequestParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/pets/ConfirmBreedingResultEvent.ts b/packages/communication/src/messages/incoming/inventory/pets/ConfirmBreedingResultEvent.ts new file mode 100644 index 0000000..04b9a42 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/pets/ConfirmBreedingResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ConfirmBreedingResultParser } from '../../../parser'; + +export class ConfirmBreedingResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ConfirmBreedingResultParser); + } + + public getParser(): ConfirmBreedingResultParser + { + return this.parser as ConfirmBreedingResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/pets/GoToBreedingNestFailureEvent.ts b/packages/communication/src/messages/incoming/inventory/pets/GoToBreedingNestFailureEvent.ts new file mode 100644 index 0000000..e344549 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/pets/GoToBreedingNestFailureEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GoToBreedingNestFailureParser } from '../../../parser'; + +export class GoToBreedingNestFailureEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GoToBreedingNestFailureParser); + } + + public getParser(): GoToBreedingNestFailureParser + { + return this.parser as GoToBreedingNestFailureParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/pets/NestBreedingSuccessEvent.ts b/packages/communication/src/messages/incoming/inventory/pets/NestBreedingSuccessEvent.ts new file mode 100644 index 0000000..2202eb7 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/pets/NestBreedingSuccessEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NestBreedingSuccessParser } from '../../../parser'; + +export class NestBreedingSuccessEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NestBreedingSuccessParser); + } + + public getParser(): NestBreedingSuccessParser + { + return this.parser as NestBreedingSuccessParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/pets/PetAddedToInventoryEvent.ts b/packages/communication/src/messages/incoming/inventory/pets/PetAddedToInventoryEvent.ts new file mode 100644 index 0000000..da5e259 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/pets/PetAddedToInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetAddedToInventoryParser } from '../../../parser'; + +export class PetAddedToInventoryEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetAddedToInventoryParser); + } + + public getParser(): PetAddedToInventoryParser + { + return this.parser as PetAddedToInventoryParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/pets/PetInventoryEvent.ts b/packages/communication/src/messages/incoming/inventory/pets/PetInventoryEvent.ts new file mode 100644 index 0000000..e49449b --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/pets/PetInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetInventoryParser } from '../../../parser'; + +export class PetInventoryEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetInventoryParser); + } + + public getParser(): PetInventoryParser + { + return this.parser as PetInventoryParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/pets/PetReceivedMessageEvent.ts b/packages/communication/src/messages/incoming/inventory/pets/PetReceivedMessageEvent.ts new file mode 100644 index 0000000..072bc02 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/pets/PetReceivedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetReceivedMessageParser } from '../../../parser'; + +export class PetReceivedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetReceivedMessageParser); + } + + public getParser(): PetReceivedMessageParser + { + return this.parser as PetReceivedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/pets/PetRemovedFromInventoryEvent.ts b/packages/communication/src/messages/incoming/inventory/pets/PetRemovedFromInventoryEvent.ts new file mode 100644 index 0000000..d96bdff --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/pets/PetRemovedFromInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetRemovedFromInventoryParser } from '../../../parser'; + +export class PetRemovedFromInventory extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetRemovedFromInventoryParser); + } + + public getParser(): PetRemovedFromInventoryParser + { + return this.parser as PetRemovedFromInventoryParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/pets/index.ts b/packages/communication/src/messages/incoming/inventory/pets/index.ts new file mode 100644 index 0000000..f7c5d97 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/pets/index.ts @@ -0,0 +1,8 @@ +export * from './ConfirmBreedingRequestEvent'; +export * from './ConfirmBreedingResultEvent'; +export * from './GoToBreedingNestFailureEvent'; +export * from './NestBreedingSuccessEvent'; +export * from './PetAddedToInventoryEvent'; +export * from './PetInventoryEvent'; +export * from './PetReceivedMessageEvent'; +export * from './PetRemovedFromInventoryEvent'; diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingAcceptEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingAcceptEvent.ts new file mode 100644 index 0000000..d4f4631 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingAcceptEvent.ts @@ -0,0 +1,26 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TradingAcceptParser } from '../../../parser'; + +export class TradingAcceptEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingAcceptParser); + } + + public get userID(): number + { + return this.getParser().userID; + } + + public get userAccepts(): boolean + { + return this.getParser().userAccepts; + } + + public getParser(): TradingAcceptParser + { + return this.parser as TradingAcceptParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingCloseEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingCloseEvent.ts new file mode 100644 index 0000000..bb237b7 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingCloseEvent.ts @@ -0,0 +1,21 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TradingCloseParser } from '../../../parser'; + +export class TradingCloseEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingCloseParser); + } + + public get userID(): number + { + return this.getParser().userID; + } + + public getParser(): TradingCloseParser + { + return this.parser as TradingCloseParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingCompletedEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingCompletedEvent.ts new file mode 100644 index 0000000..09c9482 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingCompletedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TradingCompletedParser } from '../../../parser'; + +export class TradingCompletedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingCompletedParser); + } + + public getParser(): TradingCompletedParser + { + return this.parser as TradingCompletedParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingConfirmationEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingConfirmationEvent.ts new file mode 100644 index 0000000..0f1d78e --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingConfirmationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TradingConfirmationParser } from '../../../parser'; + +export class TradingConfirmationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingConfirmationParser); + } + + public getParser(): TradingConfirmationParser + { + return this.parser as TradingConfirmationParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingListItemEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingListItemEvent.ts new file mode 100644 index 0000000..a052c3c --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingListItemEvent.ts @@ -0,0 +1,56 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ItemDataStructure, TradingListItemParser } from '../../../parser'; + +export class TradingListItemEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingListItemParser); + } + + public get firstUserID(): number + { + return this.getParser().firstUserID; + } + + public get secondUserID(): number + { + return this.getParser().secondUserID; + } + + public get firstUserNumItems(): number + { + return this.getParser().firstUserNumItems; + } + + public get secondUserNumItems(): number + { + return this.getParser().secondUserNumItems; + } + + public get firstUserNumCredits(): number + { + return this.getParser().firstUserNumCredits; + } + + public get secondUserNumCredits(): number + { + return this.getParser().secondUserNumCredits; + } + + public get firstUserItemArray(): ItemDataStructure[] + { + return this.getParser().firstUserItemArray; + } + + public get secondUserItemArray(): ItemDataStructure[] + { + return this.getParser().secondUserItemArray; + } + + public getParser(): TradingListItemParser + { + return this.parser as TradingListItemParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingNoSuchItemEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingNoSuchItemEvent.ts new file mode 100644 index 0000000..9e70233 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingNoSuchItemEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TradingNoSuchItemParser } from '../../../parser'; + +export class TradingNoSuchItemEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingNoSuchItemParser); + } + + public getParser(): TradingNoSuchItemParser + { + return this.parser as TradingNoSuchItemParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingNotOpenEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingNotOpenEvent.ts new file mode 100644 index 0000000..2e53500 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingNotOpenEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TradingNotOpenParser } from '../../../parser'; + +export class TradingNotOpenEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingNotOpenParser); + } + + public getParser(): TradingNotOpenParser + { + return this.parser as TradingNotOpenParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingOpenEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingOpenEvent.ts new file mode 100644 index 0000000..2347456 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingOpenEvent.ts @@ -0,0 +1,36 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TradingOpenParser } from '../../../parser'; + +export class TradingOpenEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingOpenParser); + } + + public get userID(): number + { + return this.getParser().userID; + } + + public get userCanTrade(): boolean + { + return this.getParser().userCanTrade; + } + + public get otherUserID(): number + { + return this.getParser().otherUserID; + } + + public get otherUserCanTrade(): boolean + { + return this.getParser().otherUserCanTrade; + } + + public getParser(): TradingOpenParser + { + return this.parser as TradingOpenParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingOpenFailedEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingOpenFailedEvent.ts new file mode 100644 index 0000000..e5baa21 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingOpenFailedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TradingOpenFailedParser } from '../../../parser'; + +export class TradingOpenFailedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingOpenFailedParser); + } + + public getParser(): TradingOpenFailedParser + { + return this.parser as TradingOpenFailedParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingOtherNotAllowedEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingOtherNotAllowedEvent.ts new file mode 100644 index 0000000..f292b4a --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingOtherNotAllowedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TradingOtherNotAllowedParser } from '../../../parser'; + +export class TradingOtherNotAllowedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingOtherNotAllowedParser); + } + + public getParser(): TradingOtherNotAllowedParser + { + return this.parser as TradingOtherNotAllowedParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/TradingYouAreNotAllowedEvent.ts b/packages/communication/src/messages/incoming/inventory/trading/TradingYouAreNotAllowedEvent.ts new file mode 100644 index 0000000..b303630 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/TradingYouAreNotAllowedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TradingYouAreNotAllowedParser } from '../../../parser'; + +export class TradingYouAreNotAllowedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingYouAreNotAllowedParser); + } + + public getParser(): TradingYouAreNotAllowedParser + { + return this.parser as TradingYouAreNotAllowedParser; + } +} diff --git a/packages/communication/src/messages/incoming/inventory/trading/index.ts b/packages/communication/src/messages/incoming/inventory/trading/index.ts new file mode 100644 index 0000000..cddd363 --- /dev/null +++ b/packages/communication/src/messages/incoming/inventory/trading/index.ts @@ -0,0 +1,11 @@ +export * from './TradingAcceptEvent'; +export * from './TradingCloseEvent'; +export * from './TradingCompletedEvent'; +export * from './TradingConfirmationEvent'; +export * from './TradingListItemEvent'; +export * from './TradingNoSuchItemEvent'; +export * from './TradingNotOpenEvent'; +export * from './TradingOpenEvent'; +export * from './TradingOpenFailedEvent'; +export * from './TradingOtherNotAllowedEvent'; +export * from './TradingYouAreNotAllowedEvent'; diff --git a/packages/communication/src/messages/incoming/landingview/PromoArticlesMessageEvent.ts b/packages/communication/src/messages/incoming/landingview/PromoArticlesMessageEvent.ts new file mode 100644 index 0000000..687a3bc --- /dev/null +++ b/packages/communication/src/messages/incoming/landingview/PromoArticlesMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PromoArticlesMessageParser } from '../../parser'; + +export class PromoArticlesMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PromoArticlesMessageParser); + } + + public getParser(): PromoArticlesMessageParser + { + return this.parser as PromoArticlesMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/landingview/index.ts b/packages/communication/src/messages/incoming/landingview/index.ts new file mode 100644 index 0000000..d566aeb --- /dev/null +++ b/packages/communication/src/messages/incoming/landingview/index.ts @@ -0,0 +1,2 @@ +export * from './PromoArticlesMessageEvent'; +export * from './votes'; diff --git a/packages/communication/src/messages/incoming/landingview/votes/CommunityGoalVoteMessageEvent.ts b/packages/communication/src/messages/incoming/landingview/votes/CommunityGoalVoteMessageEvent.ts new file mode 100644 index 0000000..45db269 --- /dev/null +++ b/packages/communication/src/messages/incoming/landingview/votes/CommunityGoalVoteMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CommunityVoteReceivedParser } from '../../../parser'; + +export class CommunityGoalVoteMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CommunityVoteReceivedParser); + } + + public getParser(): CommunityVoteReceivedParser + { + return this.parser as CommunityVoteReceivedParser; + } +} diff --git a/packages/communication/src/messages/incoming/landingview/votes/index.ts b/packages/communication/src/messages/incoming/landingview/votes/index.ts new file mode 100644 index 0000000..adcbb0e --- /dev/null +++ b/packages/communication/src/messages/incoming/landingview/votes/index.ts @@ -0,0 +1 @@ +export * from './CommunityGoalVoteMessageEvent'; diff --git a/packages/communication/src/messages/incoming/marketplace/MarketplaceBuyOfferResultEvent.ts b/packages/communication/src/messages/incoming/marketplace/MarketplaceBuyOfferResultEvent.ts new file mode 100644 index 0000000..ece4d67 --- /dev/null +++ b/packages/communication/src/messages/incoming/marketplace/MarketplaceBuyOfferResultEvent.ts @@ -0,0 +1,17 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MarketplaceBuyOfferResultParser } from '../../parser'; + + +export class MarketplaceBuyOfferResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MarketplaceBuyOfferResultParser); + } + + public getParser(): MarketplaceBuyOfferResultParser + { + return this.parser as MarketplaceBuyOfferResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/marketplace/MarketplaceCanMakeOfferResult.ts b/packages/communication/src/messages/incoming/marketplace/MarketplaceCanMakeOfferResult.ts new file mode 100644 index 0000000..b44c520 --- /dev/null +++ b/packages/communication/src/messages/incoming/marketplace/MarketplaceCanMakeOfferResult.ts @@ -0,0 +1,17 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MarketplaceCanMakeOfferResultParser } from '../../parser'; + + +export class MarketplaceCanMakeOfferResult extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MarketplaceCanMakeOfferResultParser); + } + + public getParser(): MarketplaceCanMakeOfferResultParser + { + return this.parser as MarketplaceCanMakeOfferResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/marketplace/MarketplaceCancelOfferResultEvent.ts b/packages/communication/src/messages/incoming/marketplace/MarketplaceCancelOfferResultEvent.ts new file mode 100644 index 0000000..a01e071 --- /dev/null +++ b/packages/communication/src/messages/incoming/marketplace/MarketplaceCancelOfferResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MarketplaceCancelOfferResultParser } from '../../parser'; + +export class MarketplaceCancelOfferResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MarketplaceCancelOfferResultParser); + } + + public getParser(): MarketplaceCancelOfferResultParser + { + return this.parser as MarketplaceCancelOfferResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/marketplace/MarketplaceConfigurationEvent.ts b/packages/communication/src/messages/incoming/marketplace/MarketplaceConfigurationEvent.ts new file mode 100644 index 0000000..0efb244 --- /dev/null +++ b/packages/communication/src/messages/incoming/marketplace/MarketplaceConfigurationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MarketplaceConfigurationMessageParser } from '../../parser'; + +export class MarketplaceConfigurationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MarketplaceConfigurationMessageParser); + } + + public getParser(): MarketplaceConfigurationMessageParser + { + return this.parser as MarketplaceConfigurationMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/marketplace/MarketplaceItemStatsEvent.ts b/packages/communication/src/messages/incoming/marketplace/MarketplaceItemStatsEvent.ts new file mode 100644 index 0000000..3dfb9d0 --- /dev/null +++ b/packages/communication/src/messages/incoming/marketplace/MarketplaceItemStatsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MarketplaceItemStatsParser } from '../../parser'; + +export class MarketplaceItemStatsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MarketplaceItemStatsParser); + } + + public getParser(): MarketplaceItemStatsParser + { + return this.parser as MarketplaceItemStatsParser; + } +} diff --git a/packages/communication/src/messages/incoming/marketplace/MarketplaceMakeOfferResult.ts b/packages/communication/src/messages/incoming/marketplace/MarketplaceMakeOfferResult.ts new file mode 100644 index 0000000..db8ed99 --- /dev/null +++ b/packages/communication/src/messages/incoming/marketplace/MarketplaceMakeOfferResult.ts @@ -0,0 +1,17 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MarketplaceMakeOfferResultParser } from '../../parser'; + + +export class MarketplaceMakeOfferResult extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MarketplaceMakeOfferResultParser); + } + + public getParser(): MarketplaceMakeOfferResultParser + { + return this.parser as MarketplaceMakeOfferResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/marketplace/MarketplaceOffersEvent.ts b/packages/communication/src/messages/incoming/marketplace/MarketplaceOffersEvent.ts new file mode 100644 index 0000000..768cecc --- /dev/null +++ b/packages/communication/src/messages/incoming/marketplace/MarketplaceOffersEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MarketplaceOffersParser } from '../../parser'; + +export class MarketPlaceOffersEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MarketplaceOffersParser); + } + + public getParser(): MarketplaceOffersParser + { + return this.parser as MarketplaceOffersParser; + } +} diff --git a/packages/communication/src/messages/incoming/marketplace/MarketplaceOwnOffersEvent.ts b/packages/communication/src/messages/incoming/marketplace/MarketplaceOwnOffersEvent.ts new file mode 100644 index 0000000..a40dab2 --- /dev/null +++ b/packages/communication/src/messages/incoming/marketplace/MarketplaceOwnOffersEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MarketplaceOwnOffersParser } from '../../parser'; + +export class MarketplaceOwnOffersEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MarketplaceOwnOffersParser); + } + + public getParser(): MarketplaceOwnOffersParser + { + return this.parser as MarketplaceOwnOffersParser; + } +} diff --git a/packages/communication/src/messages/incoming/marketplace/index.ts b/packages/communication/src/messages/incoming/marketplace/index.ts new file mode 100644 index 0000000..7f4c2d5 --- /dev/null +++ b/packages/communication/src/messages/incoming/marketplace/index.ts @@ -0,0 +1,8 @@ +export * from './MarketplaceBuyOfferResultEvent'; +export * from './MarketplaceCancelOfferResultEvent'; +export * from './MarketplaceCanMakeOfferResult'; +export * from './MarketplaceConfigurationEvent'; +export * from './MarketplaceItemStatsEvent'; +export * from './MarketplaceMakeOfferResult'; +export * from './MarketplaceOffersEvent'; +export * from './MarketplaceOwnOffersEvent'; diff --git a/packages/communication/src/messages/incoming/moderation/CfhChatlogEvent.ts b/packages/communication/src/messages/incoming/moderation/CfhChatlogEvent.ts new file mode 100644 index 0000000..228db0b --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/CfhChatlogEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CfhChatlogMessageParser } from '../../parser'; + +export class CfhChatlogEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CfhChatlogMessageParser); + } + + public getParser(): CfhChatlogMessageParser + { + return this.parser as CfhChatlogMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/IssueDeletedMessageEvent.ts b/packages/communication/src/messages/incoming/moderation/IssueDeletedMessageEvent.ts new file mode 100644 index 0000000..e8bb447 --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/IssueDeletedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { IssueDeletedMessageParser } from '../../parser'; + +export class IssueDeletedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IssueDeletedMessageParser); + } + + public getParser(): IssueDeletedMessageParser + { + return this.parser as IssueDeletedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/IssueInfoMessageEvent.ts b/packages/communication/src/messages/incoming/moderation/IssueInfoMessageEvent.ts new file mode 100644 index 0000000..6d74f07 --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/IssueInfoMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { IssueInfoMessageParser } from '../../parser'; + +export class IssueInfoMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IssueInfoMessageParser); + } + + public getParser(): IssueInfoMessageParser + { + return this.parser as IssueInfoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/IssuePickFailedMessageEvent.ts b/packages/communication/src/messages/incoming/moderation/IssuePickFailedMessageEvent.ts new file mode 100644 index 0000000..6f9e627 --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/IssuePickFailedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { IssuePickFailedMessageParser } from '../../parser'; + +export class IssuePickFailedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IssuePickFailedMessageParser); + } + + public getParser(): IssuePickFailedMessageParser + { + return this.parser as IssuePickFailedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/ModeratorActionResultMessageEvent.ts b/packages/communication/src/messages/incoming/moderation/ModeratorActionResultMessageEvent.ts new file mode 100644 index 0000000..264ff97 --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/ModeratorActionResultMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ModeratorActionResultMessageParser } from '../../parser'; + +export class ModeratorActionResultMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModeratorActionResultMessageParser); + } + + public getParser(): ModeratorActionResultMessageParser + { + return this.parser as ModeratorActionResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/ModeratorCautionEvent.ts b/packages/communication/src/messages/incoming/moderation/ModeratorCautionEvent.ts new file mode 100644 index 0000000..d606577 --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/ModeratorCautionEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ModerationCautionParser } from '../../parser'; + +export class ModeratorCautionEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModerationCautionParser); + } + + public getParser(): ModerationCautionParser + { + return this.parser as ModerationCautionParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/ModeratorInitMessageEvent.ts b/packages/communication/src/messages/incoming/moderation/ModeratorInitMessageEvent.ts new file mode 100644 index 0000000..73891ee --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/ModeratorInitMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ModeratorInitMessageParser } from '../../parser'; + +export class ModeratorInitMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModeratorInitMessageParser); + } + + public getParser(): ModeratorInitMessageParser + { + return this.parser as ModeratorInitMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/ModeratorMessageEvent.ts b/packages/communication/src/messages/incoming/moderation/ModeratorMessageEvent.ts new file mode 100644 index 0000000..863ec05 --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/ModeratorMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ModeratorMessageParser } from '../../parser'; + +export class ModeratorMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModeratorMessageParser); + } + + public getParser(): ModeratorMessageParser + { + return this.parser as ModeratorMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/ModeratorRoomInfoEvent.ts b/packages/communication/src/messages/incoming/moderation/ModeratorRoomInfoEvent.ts new file mode 100644 index 0000000..e53bc73 --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/ModeratorRoomInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ModeratorRoomInfoMessageParser } from '../../parser'; + +export class ModeratorRoomInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModeratorRoomInfoMessageParser); + } + + public getParser(): ModeratorRoomInfoMessageParser + { + return this.parser as ModeratorRoomInfoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/ModeratorToolPreferencesEvent.ts b/packages/communication/src/messages/incoming/moderation/ModeratorToolPreferencesEvent.ts new file mode 100644 index 0000000..3ab1dd3 --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/ModeratorToolPreferencesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ModeratorToolPreferencesMessageParser } from '../../parser'; + +export class ModeratorToolPreferencesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModeratorToolPreferencesMessageParser); + } + + public getParser(): ModeratorToolPreferencesMessageParser + { + return this.parser as ModeratorToolPreferencesMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/ModeratorUserInfoEvent.ts b/packages/communication/src/messages/incoming/moderation/ModeratorUserInfoEvent.ts new file mode 100644 index 0000000..1a8cd8e --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/ModeratorUserInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ModeratorUserInfoMessageParser } from '../../parser'; + +export class ModeratorUserInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModeratorUserInfoMessageParser); + } + + public getParser(): ModeratorUserInfoMessageParser + { + return this.parser as ModeratorUserInfoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/RoomChatlogEvent.ts b/packages/communication/src/messages/incoming/moderation/RoomChatlogEvent.ts new file mode 100644 index 0000000..fd5ce65 --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/RoomChatlogEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomChatlogMessageParser } from '../../parser'; + +export class RoomChatlogEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomChatlogMessageParser); + } + + public getParser(): RoomChatlogMessageParser + { + return this.parser as RoomChatlogMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/RoomVisitsEvent.ts b/packages/communication/src/messages/incoming/moderation/RoomVisitsEvent.ts new file mode 100644 index 0000000..4cbf2cb --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/RoomVisitsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomVisitsMessageParser } from '../../parser'; + +export class RoomVisitsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomVisitsMessageParser); + } + + public getParser(): RoomVisitsMessageParser + { + return this.parser as RoomVisitsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/UserBannedMessageEvent.ts b/packages/communication/src/messages/incoming/moderation/UserBannedMessageEvent.ts new file mode 100644 index 0000000..54cbcda --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/UserBannedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserBannedMessageParser } from '../../parser'; + +export class UserBannedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserBannedMessageParser); + } + + public getParser(): UserBannedMessageParser + { + return this.parser as UserBannedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/UserChatlogEvent.ts b/packages/communication/src/messages/incoming/moderation/UserChatlogEvent.ts new file mode 100644 index 0000000..9314cff --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/UserChatlogEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserChatlogMessageParser } from '../../parser'; + +export class UserChatlogEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserChatlogMessageParser); + } + + public getParser(): UserChatlogMessageParser + { + return this.parser as UserChatlogMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/moderation/index.ts b/packages/communication/src/messages/incoming/moderation/index.ts new file mode 100644 index 0000000..2bbc0c0 --- /dev/null +++ b/packages/communication/src/messages/incoming/moderation/index.ts @@ -0,0 +1,15 @@ +export * from './CfhChatlogEvent'; +export * from './IssueDeletedMessageEvent'; +export * from './IssueInfoMessageEvent'; +export * from './IssuePickFailedMessageEvent'; +export * from './ModeratorActionResultMessageEvent'; +export * from './ModeratorCautionEvent'; +export * from './ModeratorInitMessageEvent'; +export * from './ModeratorMessageEvent'; +export * from './ModeratorRoomInfoEvent'; +export * from './ModeratorToolPreferencesEvent'; +export * from './ModeratorUserInfoEvent'; +export * from './RoomChatlogEvent'; +export * from './RoomVisitsEvent'; +export * from './UserBannedMessageEvent'; +export * from './UserChatlogEvent'; diff --git a/packages/communication/src/messages/incoming/mysterybox/CancelMysteryBoxWaitMessageEvent.ts b/packages/communication/src/messages/incoming/mysterybox/CancelMysteryBoxWaitMessageEvent.ts new file mode 100644 index 0000000..fd49f76 --- /dev/null +++ b/packages/communication/src/messages/incoming/mysterybox/CancelMysteryBoxWaitMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CancelMysteryBoxWaitMessageParser } from '../../parser/mysterybox'; + +export class CancelMysteryBoxWaitMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CancelMysteryBoxWaitMessageParser); + } + + public getParser(): CancelMysteryBoxWaitMessageParser + { + return this.parser as CancelMysteryBoxWaitMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/mysterybox/GotMysteryBoxPrizeMessageEvent.ts b/packages/communication/src/messages/incoming/mysterybox/GotMysteryBoxPrizeMessageEvent.ts new file mode 100644 index 0000000..00928d3 --- /dev/null +++ b/packages/communication/src/messages/incoming/mysterybox/GotMysteryBoxPrizeMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GotMysteryBoxPrizeMessageParser } from '../../parser/mysterybox'; + +export class GotMysteryBoxPrizeMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GotMysteryBoxPrizeMessageParser); + } + + public getParser(): GotMysteryBoxPrizeMessageParser + { + return this.parser as GotMysteryBoxPrizeMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/mysterybox/MysteryBoxKeysEvent.ts b/packages/communication/src/messages/incoming/mysterybox/MysteryBoxKeysEvent.ts new file mode 100644 index 0000000..bae9bd6 --- /dev/null +++ b/packages/communication/src/messages/incoming/mysterybox/MysteryBoxKeysEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MysteryBoxKeysParser } from '../../parser'; + +export class MysteryBoxKeysEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MysteryBoxKeysParser); + } + + public getParser(): MysteryBoxKeysParser + { + return this.parser as MysteryBoxKeysParser; + } +} diff --git a/packages/communication/src/messages/incoming/mysterybox/ShowMysteryBoxWaitMessageEvent.ts b/packages/communication/src/messages/incoming/mysterybox/ShowMysteryBoxWaitMessageEvent.ts new file mode 100644 index 0000000..6305863 --- /dev/null +++ b/packages/communication/src/messages/incoming/mysterybox/ShowMysteryBoxWaitMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ShowMysteryBoxWaitMessageParser } from '../../parser/mysterybox'; + +export class ShowMysteryBoxWaitMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ShowMysteryBoxWaitMessageParser); + } + + public getParser(): ShowMysteryBoxWaitMessageParser + { + return this.parser as ShowMysteryBoxWaitMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/mysterybox/index.ts b/packages/communication/src/messages/incoming/mysterybox/index.ts new file mode 100644 index 0000000..0d41333 --- /dev/null +++ b/packages/communication/src/messages/incoming/mysterybox/index.ts @@ -0,0 +1,4 @@ +export * from './CancelMysteryBoxWaitMessageEvent'; +export * from './GotMysteryBoxPrizeMessageEvent'; +export * from './MysteryBoxKeysEvent'; +export * from './ShowMysteryBoxWaitMessageEvent'; diff --git a/packages/communication/src/messages/incoming/navigator/CanCreateRoomEvent.ts b/packages/communication/src/messages/incoming/navigator/CanCreateRoomEvent.ts new file mode 100644 index 0000000..3836423 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/CanCreateRoomEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CanCreateRoomMessageParser } from '../../parser'; + +export class CanCreateRoomEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CanCreateRoomMessageParser); + } + + public getParser(): CanCreateRoomMessageParser + { + return this.parser as CanCreateRoomMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/CanCreateRoomEventEvent.ts b/packages/communication/src/messages/incoming/navigator/CanCreateRoomEventEvent.ts new file mode 100644 index 0000000..e1ac7e7 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/CanCreateRoomEventEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CanCreateRoomEventParser } from '../../parser'; + +export class CanCreateRoomEventEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CanCreateRoomEventParser); + } + + public getParser(): CanCreateRoomEventParser + { + return this.parser as CanCreateRoomEventParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/CategoriesWithVisitorCountEvent.ts b/packages/communication/src/messages/incoming/navigator/CategoriesWithVisitorCountEvent.ts new file mode 100644 index 0000000..651d255 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/CategoriesWithVisitorCountEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CategoriesWithVisitorCountParser } from '../../parser'; + +export class CategoriesWithVisitorCountEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CategoriesWithVisitorCountParser); + } + + public getParser(): CategoriesWithVisitorCountParser + { + return this.parser as CategoriesWithVisitorCountParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/CompetitionRoomsDataMessageEvent.ts b/packages/communication/src/messages/incoming/navigator/CompetitionRoomsDataMessageEvent.ts new file mode 100644 index 0000000..bd9a360 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/CompetitionRoomsDataMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CompetitionRoomsDataMessageParser } from '../../parser'; + +export class CompetitionRoomsDataMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CompetitionRoomsDataMessageParser); + } + + public getParser(): CompetitionRoomsDataMessageParser + { + return this.parser as CompetitionRoomsDataMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/ConvertedRoomIdEvent.ts b/packages/communication/src/messages/incoming/navigator/ConvertedRoomIdEvent.ts new file mode 100644 index 0000000..eb37e70 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/ConvertedRoomIdEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ConvertedRoomIdMessageParser } from '../../parser'; + +export class ConvertedRoomIdEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ConvertedRoomIdMessageParser); + } + + public getParser(): ConvertedRoomIdMessageParser + { + return this.parser as ConvertedRoomIdMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/DoorbellMessageEvent.ts b/packages/communication/src/messages/incoming/navigator/DoorbellMessageEvent.ts new file mode 100644 index 0000000..ce495a1 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/DoorbellMessageEvent.ts @@ -0,0 +1,21 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { DoorbellMessageParser } from '../../parser'; + +export class DoorbellMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, DoorbellMessageParser); + } + + public getParser(): DoorbellMessageParser + { + return this.parser as DoorbellMessageParser; + } + + public get userName(): string + { + return this.getParser().userName; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/FavouriteChangedEvent.ts b/packages/communication/src/messages/incoming/navigator/FavouriteChangedEvent.ts new file mode 100644 index 0000000..e9652cb --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/FavouriteChangedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FavouriteChangedMessageParser } from '../../parser'; + +export class FavouriteChangedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FavouriteChangedMessageParser); + } + + public getParser(): FavouriteChangedMessageParser + { + return this.parser as FavouriteChangedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/FavouritesEvent.ts b/packages/communication/src/messages/incoming/navigator/FavouritesEvent.ts new file mode 100644 index 0000000..46622f5 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/FavouritesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FavouritesMessageParser } from '../../parser'; + +export class FavouritesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FavouritesMessageParser); + } + + public getParser(): FavouritesMessageParser + { + return this.parser as FavouritesMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/FlatAccessDeniedMessageEvent.ts b/packages/communication/src/messages/incoming/navigator/FlatAccessDeniedMessageEvent.ts new file mode 100644 index 0000000..205bfb5 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/FlatAccessDeniedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FlatAccessDeniedMessageParser } from '../../parser'; + +export class FlatAccessDeniedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FlatAccessDeniedMessageParser); + } + + public getParser(): FlatAccessDeniedMessageParser + { + return this.parser as FlatAccessDeniedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/FlatCreatedEvent.ts b/packages/communication/src/messages/incoming/navigator/FlatCreatedEvent.ts new file mode 100644 index 0000000..a6e00a9 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/FlatCreatedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FlatCreatedMessageParser } from '../../parser'; + +export class FlatCreatedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FlatCreatedMessageParser); + } + + public getParser(): FlatCreatedMessageParser + { + return this.parser as FlatCreatedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/GetGuestRoomResultEvent.ts b/packages/communication/src/messages/incoming/navigator/GetGuestRoomResultEvent.ts new file mode 100644 index 0000000..3f601ea --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/GetGuestRoomResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GetGuestRoomResultMessageParser } from '../../parser'; + +export class GetGuestRoomResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GetGuestRoomResultMessageParser); + } + + public getParser(): GetGuestRoomResultMessageParser + { + return this.parser as GetGuestRoomResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/GuestRoomSearchResultEvent.ts b/packages/communication/src/messages/incoming/navigator/GuestRoomSearchResultEvent.ts new file mode 100644 index 0000000..95ca50a --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/GuestRoomSearchResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuestRoomSearchResultMessageParser } from '../../parser'; + +export class GuestRoomSearchResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuestRoomSearchResultMessageParser); + } + + public getParser(): GuestRoomSearchResultMessageParser + { + return this.parser as GuestRoomSearchResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/NavigatorCollapsedEvent.ts b/packages/communication/src/messages/incoming/navigator/NavigatorCollapsedEvent.ts new file mode 100644 index 0000000..fb6e0f7 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/NavigatorCollapsedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NavigatorCollapsedParser } from '../../parser'; + +export class NavigatorCollapsedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorCollapsedParser); + } + + public getParser(): NavigatorCollapsedParser + { + return this.parser as NavigatorCollapsedParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/NavigatorHomeRoomEvent.ts b/packages/communication/src/messages/incoming/navigator/NavigatorHomeRoomEvent.ts new file mode 100644 index 0000000..3e1c021 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/NavigatorHomeRoomEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NavigatorHomeRoomParser } from '../../parser'; + +export class NavigatorHomeRoomEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorHomeRoomParser); + } + + public getParser(): NavigatorHomeRoomParser + { + return this.parser as NavigatorHomeRoomParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/NavigatorLiftedEvent.ts b/packages/communication/src/messages/incoming/navigator/NavigatorLiftedEvent.ts new file mode 100644 index 0000000..8dbbdf1 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/NavigatorLiftedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NavigatorLiftedParser } from '../../parser'; + +export class NavigatorLiftedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorLiftedParser); + } + + public getParser(): NavigatorLiftedParser + { + return this.parser as NavigatorLiftedParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/NavigatorMetadataEvent.ts b/packages/communication/src/messages/incoming/navigator/NavigatorMetadataEvent.ts new file mode 100644 index 0000000..ed6eb51 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/NavigatorMetadataEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NavigatorMetadataParser } from '../../parser'; + +export class NavigatorMetadataEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorMetadataParser); + } + + public getParser(): NavigatorMetadataParser + { + return this.parser as NavigatorMetadataParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/NavigatorOpenRoomCreatorEvent.ts b/packages/communication/src/messages/incoming/navigator/NavigatorOpenRoomCreatorEvent.ts new file mode 100644 index 0000000..70eb7ea --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/NavigatorOpenRoomCreatorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NavigatorOpenRoomCreatorParser } from '../../parser'; + +export class NavigatorOpenRoomCreatorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorOpenRoomCreatorParser); + } + + public getParser(): NavigatorOpenRoomCreatorParser + { + return this.parser as NavigatorOpenRoomCreatorParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/NavigatorSearchEvent.ts b/packages/communication/src/messages/incoming/navigator/NavigatorSearchEvent.ts new file mode 100644 index 0000000..bf2dffe --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/NavigatorSearchEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NavigatorSearchParser } from '../../parser'; + +export class NavigatorSearchEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorSearchParser); + } + + public getParser(): NavigatorSearchParser + { + return this.parser as NavigatorSearchParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/NavigatorSearchesEvent.ts b/packages/communication/src/messages/incoming/navigator/NavigatorSearchesEvent.ts new file mode 100644 index 0000000..df9ac9e --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/NavigatorSearchesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NavigatorSearchesParser } from '../../parser'; + +export class NavigatorSearchesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorSearchesParser); + } + + public getParser(): NavigatorSearchesParser + { + return this.parser as NavigatorSearchesParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/NavigatorSettingsEvent.ts b/packages/communication/src/messages/incoming/navigator/NavigatorSettingsEvent.ts new file mode 100644 index 0000000..9546220 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/NavigatorSettingsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NavigatorSettingsParser } from '../../parser'; + +export class NavigatorSettingsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorSettingsParser); + } + + public getParser(): NavigatorSettingsParser + { + return this.parser as NavigatorSettingsParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/PopularRoomTagsResultEvent.ts b/packages/communication/src/messages/incoming/navigator/PopularRoomTagsResultEvent.ts new file mode 100644 index 0000000..738570c --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/PopularRoomTagsResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PopularRoomTagsResultMessageParser } from '../../parser'; + +export class PopularRoomTagsResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PopularRoomTagsResultMessageParser); + } + + public getParser(): PopularRoomTagsResultMessageParser + { + return this.parser as PopularRoomTagsResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/RoomEventCancelEvent.ts b/packages/communication/src/messages/incoming/navigator/RoomEventCancelEvent.ts new file mode 100644 index 0000000..938ffcf --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/RoomEventCancelEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomEventCancelMessageParser } from '../../parser'; + +export class RoomEventCancelEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomEventCancelMessageParser); + } + + public getParser(): RoomEventCancelMessageParser + { + return this.parser as RoomEventCancelMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/RoomEventEvent.ts b/packages/communication/src/messages/incoming/navigator/RoomEventEvent.ts new file mode 100644 index 0000000..51b2764 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/RoomEventEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomEventMessageParser } from '../../parser'; + +export class RoomEventEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomEventMessageParser); + } + + public getParser(): RoomEventMessageParser + { + return this.parser as RoomEventMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/RoomFilterSettingsMessageEvent.ts b/packages/communication/src/messages/incoming/navigator/RoomFilterSettingsMessageEvent.ts new file mode 100644 index 0000000..c2a22f9 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/RoomFilterSettingsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomFilterSettingsMessageParser } from '../../parser'; + +export class RoomFilterSettingsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomFilterSettingsMessageParser); + } + + public getParser(): RoomFilterSettingsMessageParser + { + return this.parser as RoomFilterSettingsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/RoomSettingsUpdatedEvent.ts b/packages/communication/src/messages/incoming/navigator/RoomSettingsUpdatedEvent.ts new file mode 100644 index 0000000..f3ac9df --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/RoomSettingsUpdatedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomSettingsUpdatedParser } from '../../parser'; + +export class RoomSettingsUpdatedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsUpdatedParser); + } + + public getParser(): RoomSettingsUpdatedParser + { + return this.parser as RoomSettingsUpdatedParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/RoomThumbnailUpdateResultEvent.ts b/packages/communication/src/messages/incoming/navigator/RoomThumbnailUpdateResultEvent.ts new file mode 100644 index 0000000..eacb19a --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/RoomThumbnailUpdateResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomThumbnailUpdateResultMessageParser } from '../../parser'; + +export class RoomThumbnailUpdateResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomThumbnailUpdateResultMessageParser); + } + + public getParser(): RoomThumbnailUpdateResultMessageParser + { + return this.parser as RoomThumbnailUpdateResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/UserEventCatsEvent.ts b/packages/communication/src/messages/incoming/navigator/UserEventCatsEvent.ts new file mode 100644 index 0000000..a4677e2 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/UserEventCatsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserEventCatsMessageParser } from '../../parser'; + +export class UserEventCatsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserEventCatsMessageParser); + } + + public getParser(): UserEventCatsMessageParser + { + return this.parser as UserEventCatsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/UserFlatCatsEvent.ts b/packages/communication/src/messages/incoming/navigator/UserFlatCatsEvent.ts new file mode 100644 index 0000000..1d8e7b9 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/UserFlatCatsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserFlatCatsMessageParser } from '../../parser'; + +export class UserFlatCatsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserFlatCatsMessageParser); + } + + public getParser(): UserFlatCatsMessageParser + { + return this.parser as UserFlatCatsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/navigator/index.ts b/packages/communication/src/messages/incoming/navigator/index.ts new file mode 100644 index 0000000..deac832 --- /dev/null +++ b/packages/communication/src/messages/incoming/navigator/index.ts @@ -0,0 +1,28 @@ +export * from './CanCreateRoomEvent'; +export * from './CanCreateRoomEventEvent'; +export * from './CategoriesWithVisitorCountEvent'; +export * from './CompetitionRoomsDataMessageEvent'; +export * from './ConvertedRoomIdEvent'; +export * from './DoorbellMessageEvent'; +export * from './FavouriteChangedEvent'; +export * from './FavouritesEvent'; +export * from './FlatAccessDeniedMessageEvent'; +export * from './FlatCreatedEvent'; +export * from './GetGuestRoomResultEvent'; +export * from './GuestRoomSearchResultEvent'; +export * from './NavigatorCollapsedEvent'; +export * from './NavigatorHomeRoomEvent'; +export * from './NavigatorLiftedEvent'; +export * from './NavigatorMetadataEvent'; +export * from './NavigatorOpenRoomCreatorEvent'; +export * from './NavigatorSearchesEvent'; +export * from './NavigatorSearchEvent'; +export * from './NavigatorSettingsEvent'; +export * from './PopularRoomTagsResultEvent'; +export * from './RoomEventCancelEvent'; +export * from './RoomEventEvent'; +export * from './RoomFilterSettingsMessageEvent'; +export * from './RoomSettingsUpdatedEvent'; +export * from './RoomThumbnailUpdateResultEvent'; +export * from './UserEventCatsEvent'; +export * from './UserFlatCatsEvent'; diff --git a/packages/communication/src/messages/incoming/notifications/AchievementNotificationMessageEvent.ts b/packages/communication/src/messages/incoming/notifications/AchievementNotificationMessageEvent.ts new file mode 100644 index 0000000..520a99f --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/AchievementNotificationMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AchievementNotificationMessageParser } from '../../parser'; + +export class AchievementNotificationMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AchievementNotificationMessageParser); + } + + public getParser(): AchievementNotificationMessageParser + { + return this.parser as AchievementNotificationMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/ActivityPointNotificationMessageEvent.ts b/packages/communication/src/messages/incoming/notifications/ActivityPointNotificationMessageEvent.ts new file mode 100644 index 0000000..20bf570 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/ActivityPointNotificationMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ActivityPointNotificationParser } from '../../parser'; + +export class ActivityPointNotificationMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ActivityPointNotificationParser); + } + + public getParser(): ActivityPointNotificationParser + { + return this.parser as ActivityPointNotificationParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/BotErrorEvent.ts b/packages/communication/src/messages/incoming/notifications/BotErrorEvent.ts new file mode 100644 index 0000000..8eaa0a1 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/BotErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BotErrorEventParser } from '../../parser'; + +export class BotErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotErrorEventParser); + } + + public getParser(): BotErrorEventParser + { + return this.parser as BotErrorEventParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/ClubGiftNotificationEvent.ts b/packages/communication/src/messages/incoming/notifications/ClubGiftNotificationEvent.ts new file mode 100644 index 0000000..d8e1795 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/ClubGiftNotificationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ClubGiftNotificationParser } from '../../parser'; + +export class ClubGiftNotificationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ClubGiftNotificationParser); + } + + public getParser(): ClubGiftNotificationParser + { + return this.parser as ClubGiftNotificationParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/ConnectionErrorEvent.ts b/packages/communication/src/messages/incoming/notifications/ConnectionErrorEvent.ts new file mode 100644 index 0000000..1b12eab --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/ConnectionErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ConnectionErrorMessageParser } from '../../parser/notifications/ConnectionErrorMessageParser'; + +export class ConnectionErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ConnectionErrorMessageParser); + } + + public getParser(): ConnectionErrorMessageParser + { + return this.parser as ConnectionErrorMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/ElementPointerMessageEvent.ts b/packages/communication/src/messages/incoming/notifications/ElementPointerMessageEvent.ts new file mode 100644 index 0000000..12b941e --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/ElementPointerMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ElementPointerMessageParser } from '../../parser'; + +export class ElementPointerMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ElementPointerMessageParser); + } + + public getParser(): ElementPointerMessageParser + { + return this.parser as ElementPointerMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/HabboBroadcastMessageEvent.ts b/packages/communication/src/messages/incoming/notifications/HabboBroadcastMessageEvent.ts new file mode 100644 index 0000000..58e1db0 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/HabboBroadcastMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HabboBroadcastMessageParser } from '../../parser'; + +export class HabboBroadcastMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HabboBroadcastMessageParser); + } + + public getParser(): HabboBroadcastMessageParser + { + return this.parser as HabboBroadcastMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/HotelWillShutdownEvent.ts b/packages/communication/src/messages/incoming/notifications/HotelWillShutdownEvent.ts new file mode 100644 index 0000000..b726633 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/HotelWillShutdownEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HotelWillShutdownParser } from '../../parser'; + +export class HotelWillShutdownEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HotelWillShutdownParser); + } + + public getParser(): HotelWillShutdownParser + { + return this.parser as HotelWillShutdownParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/InfoFeedEnableMessageEvent.ts b/packages/communication/src/messages/incoming/notifications/InfoFeedEnableMessageEvent.ts new file mode 100644 index 0000000..5c7e54e --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/InfoFeedEnableMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { InfoFeedEnableMessageParser } from '../../parser'; + +export class InfoFeedEnableMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, InfoFeedEnableMessageParser); + } + + public getParser(): InfoFeedEnableMessageParser + { + return this.parser as InfoFeedEnableMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/MOTDNotificationEvent.ts b/packages/communication/src/messages/incoming/notifications/MOTDNotificationEvent.ts new file mode 100644 index 0000000..07ae143 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/MOTDNotificationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MOTDNotificationParser } from '../../parser'; + +export class MOTDNotificationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MOTDNotificationParser); + } + + public getParser(): MOTDNotificationParser + { + return this.parser as MOTDNotificationParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/NotificationDialogMessageEvent.ts b/packages/communication/src/messages/incoming/notifications/NotificationDialogMessageEvent.ts new file mode 100644 index 0000000..b6b7fd7 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/NotificationDialogMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NotificationDialogMessageParser } from '../../parser'; + +export class NotificationDialogMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NotificationDialogMessageParser); + } + + public getParser(): NotificationDialogMessageParser + { + return this.parser as NotificationDialogMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/OfferRewardDeliveredMessageEvent.ts b/packages/communication/src/messages/incoming/notifications/OfferRewardDeliveredMessageEvent.ts new file mode 100644 index 0000000..7262060 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/OfferRewardDeliveredMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { OfferRewardDeliveredMessageParser } from '../../parser'; + +export class OfferRewardDeliveredMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, OfferRewardDeliveredMessageParser); + } + + public getParser(): OfferRewardDeliveredMessageParser + { + return this.parser as OfferRewardDeliveredMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/PetLevelNotificationEvent.ts b/packages/communication/src/messages/incoming/notifications/PetLevelNotificationEvent.ts new file mode 100644 index 0000000..3bb1d11 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/PetLevelNotificationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetLevelNotificationParser } from '../../parser'; + +export class PetLevelNotificationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetLevelNotificationParser); + } + + public getParser(): PetLevelNotificationParser + { + return this.parser as PetLevelNotificationParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/PetPlacingErrorEvent.ts b/packages/communication/src/messages/incoming/notifications/PetPlacingErrorEvent.ts new file mode 100644 index 0000000..88aa0fb --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/PetPlacingErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetPlacingErrorEventParser } from '../../parser'; + +export class PetPlacingErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetPlacingErrorEventParser); + } + + public getParser(): PetPlacingErrorEventParser + { + return this.parser as PetPlacingErrorEventParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/RestoreClientMessageEvent.ts b/packages/communication/src/messages/incoming/notifications/RestoreClientMessageEvent.ts new file mode 100644 index 0000000..48767d1 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/RestoreClientMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RestoreClientMessageParser } from '../../parser'; + +export class RestoreClientMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RestoreClientMessageParser); + } + + public getParser(): RestoreClientMessageParser + { + return this.parser as RestoreClientMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/SimpleAlertMessageEvent.ts b/packages/communication/src/messages/incoming/notifications/SimpleAlertMessageEvent.ts new file mode 100644 index 0000000..11373d9 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/SimpleAlertMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { SimpleAlertMessageParser } from '../../parser'; + +export class SimpleAlertMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, SimpleAlertMessageParser); + } + + public getParser(): SimpleAlertMessageParser + { + return this.parser as SimpleAlertMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/UnseenItemsEvent.ts b/packages/communication/src/messages/incoming/notifications/UnseenItemsEvent.ts new file mode 100644 index 0000000..9807fb1 --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/UnseenItemsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UnseenItemsParser } from '../../parser'; + +export class UnseenItemsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UnseenItemsParser); + } + + public getParser(): UnseenItemsParser + { + return this.parser as UnseenItemsParser; + } +} diff --git a/packages/communication/src/messages/incoming/notifications/index.ts b/packages/communication/src/messages/incoming/notifications/index.ts new file mode 100644 index 0000000..943253e --- /dev/null +++ b/packages/communication/src/messages/incoming/notifications/index.ts @@ -0,0 +1,17 @@ +export * from './AchievementNotificationMessageEvent'; +export * from './ActivityPointNotificationMessageEvent'; +export * from './BotErrorEvent'; +export * from './ClubGiftNotificationEvent'; +export * from './ConnectionErrorEvent'; +export * from './ElementPointerMessageEvent'; +export * from './HabboBroadcastMessageEvent'; +export * from './HotelWillShutdownEvent'; +export * from './InfoFeedEnableMessageEvent'; +export * from './MOTDNotificationEvent'; +export * from './NotificationDialogMessageEvent'; +export * from './OfferRewardDeliveredMessageEvent'; +export * from './PetLevelNotificationEvent'; +export * from './PetPlacingErrorEvent'; +export * from './RestoreClientMessageEvent'; +export * from './SimpleAlertMessageEvent'; +export * from './UnseenItemsEvent'; diff --git a/packages/communication/src/messages/incoming/nux/NewUserExperienceGift.ts b/packages/communication/src/messages/incoming/nux/NewUserExperienceGift.ts new file mode 100644 index 0000000..6d1c7d9 --- /dev/null +++ b/packages/communication/src/messages/incoming/nux/NewUserExperienceGift.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { ProductOffer } from './ProductOffer'; + +export class NewUserExperienceGift +{ + private _thumbnailUrl: string; + private _productOfferList: ProductOffer[]; + + constructor(wrapper: IMessageDataWrapper) + { + this._thumbnailUrl = wrapper.readString(); + if(this._thumbnailUrl == '') + { + this._thumbnailUrl = null; + } + + this._productOfferList = []; + const count:number = wrapper.readInt(); + let index = 0; + + while(index < count) + { + this._productOfferList.push(new ProductOffer(wrapper)); + index++; + } + } + + public get productOfferList(): ProductOffer[] + { + return this._productOfferList; + } + + public get thumbnailUrl(): string + { + return this._thumbnailUrl; + } +} diff --git a/packages/communication/src/messages/incoming/nux/NewUserExperienceGiftOfferMessageEvent.ts b/packages/communication/src/messages/incoming/nux/NewUserExperienceGiftOfferMessageEvent.ts new file mode 100644 index 0000000..91b5672 --- /dev/null +++ b/packages/communication/src/messages/incoming/nux/NewUserExperienceGiftOfferMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NewUserExperienceGiftOfferMessageParser } from '../../parser/nux'; + +export class NewUserExperienceGiftOfferMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NewUserExperienceGiftOfferMessageParser); + } + + public getParser(): NewUserExperienceGiftOfferMessageParser + { + return this.parser as NewUserExperienceGiftOfferMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/nux/NewUserExperienceGiftOptions.ts b/packages/communication/src/messages/incoming/nux/NewUserExperienceGiftOptions.ts new file mode 100644 index 0000000..d15d7ce --- /dev/null +++ b/packages/communication/src/messages/incoming/nux/NewUserExperienceGiftOptions.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { NewUserExperienceGift } from './NewUserExperienceGift'; + +export class NewUserExperienceGiftOptions +{ + private _dayIndex: number; + private _stepIndex: number; + private _options: NewUserExperienceGift[]; + + constructor(wrapper: IMessageDataWrapper) + { + this._dayIndex = wrapper.readInt(); + this._stepIndex = wrapper.readInt(); + this._options = []; + + const count:number = wrapper.readInt(); + let index = 0; + + while(index < count) + { + this._options.push(new NewUserExperienceGift(wrapper)); + index++; + } + } + + public get dayIndex(): number + { + return this._dayIndex; + } + + public get stepIndex(): number + { + return this._stepIndex; + } + + public get options(): NewUserExperienceGift[] + { + return this._options; + } +} diff --git a/packages/communication/src/messages/incoming/nux/NewUserExperienceNotCompleteEvent.ts b/packages/communication/src/messages/incoming/nux/NewUserExperienceNotCompleteEvent.ts new file mode 100644 index 0000000..2205caf --- /dev/null +++ b/packages/communication/src/messages/incoming/nux/NewUserExperienceNotCompleteEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NewUserExperienceNotCompleteParser } from '../../parser/nux'; + +export class NewUserExperienceNotCompleteEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NewUserExperienceNotCompleteParser); + } + + public getParser(): NewUserExperienceNotCompleteParser + { + return this.parser as NewUserExperienceNotCompleteParser; + } +} diff --git a/packages/communication/src/messages/incoming/nux/ProductOffer.ts b/packages/communication/src/messages/incoming/nux/ProductOffer.ts new file mode 100644 index 0000000..ae1ce97 --- /dev/null +++ b/packages/communication/src/messages/incoming/nux/ProductOffer.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class ProductOffer +{ + private _itemName: string; + private _extraInfo: string; + + constructor(wrapper: IMessageDataWrapper) + { + this._itemName = wrapper.readString(); + this._extraInfo = wrapper.readString(); + + if(this._extraInfo == '') + { + this._extraInfo = null; + } + } + + public get itemName(): string + { + return this._itemName; + } + + public get extraInfo(): string + { + return this._extraInfo; + } +} diff --git a/packages/communication/src/messages/incoming/nux/index.ts b/packages/communication/src/messages/incoming/nux/index.ts new file mode 100644 index 0000000..731f00d --- /dev/null +++ b/packages/communication/src/messages/incoming/nux/index.ts @@ -0,0 +1,5 @@ +export * from './NewUserExperienceGift'; +export * from './NewUserExperienceGiftOfferMessageEvent'; +export * from './NewUserExperienceGiftOptions'; +export * from './NewUserExperienceNotCompleteEvent'; +export * from './ProductOffer'; diff --git a/packages/communication/src/messages/incoming/perk/PerkAllowancesMessageEvent.ts b/packages/communication/src/messages/incoming/perk/PerkAllowancesMessageEvent.ts new file mode 100644 index 0000000..a4d257f --- /dev/null +++ b/packages/communication/src/messages/incoming/perk/PerkAllowancesMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PerkAllowancesMessageParser } from './../../parser'; + +export class PerkAllowancesMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PerkAllowancesMessageParser); + } + + public getParser(): PerkAllowancesMessageParser + { + return this.parser as PerkAllowancesMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/perk/index.ts b/packages/communication/src/messages/incoming/perk/index.ts new file mode 100644 index 0000000..b19fe4b --- /dev/null +++ b/packages/communication/src/messages/incoming/perk/index.ts @@ -0,0 +1 @@ +export * from './PerkAllowancesMessageEvent'; diff --git a/packages/communication/src/messages/incoming/pet/OpenPetPackageRequestedMessageEvent.ts b/packages/communication/src/messages/incoming/pet/OpenPetPackageRequestedMessageEvent.ts new file mode 100644 index 0000000..e1650c7 --- /dev/null +++ b/packages/communication/src/messages/incoming/pet/OpenPetPackageRequestedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { OpenPetPackageRequestedMessageParser } from './../../parser'; + +export class OpenPetPackageRequestedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, OpenPetPackageRequestedMessageParser); + } + + public getParser(): OpenPetPackageRequestedMessageParser + { + return this.parser as OpenPetPackageRequestedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/pet/OpenPetPackageResultMessageEvent.ts b/packages/communication/src/messages/incoming/pet/OpenPetPackageResultMessageEvent.ts new file mode 100644 index 0000000..aa6b5d8 --- /dev/null +++ b/packages/communication/src/messages/incoming/pet/OpenPetPackageResultMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { OpenPetPackageResultMessageParser } from './../../parser'; + +export class OpenPetPackageResultMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, OpenPetPackageResultMessageParser); + } + + public getParser(): OpenPetPackageResultMessageParser + { + return this.parser as OpenPetPackageResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/pet/PetLevelUpdateMessageEvent.ts b/packages/communication/src/messages/incoming/pet/PetLevelUpdateMessageEvent.ts new file mode 100644 index 0000000..ca2a8cb --- /dev/null +++ b/packages/communication/src/messages/incoming/pet/PetLevelUpdateMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetLevelUpdateMessageParser } from '../../parser'; + +export class PetLevelUpdateMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetLevelUpdateMessageParser); + } + + public getParser(): PetLevelUpdateMessageParser + { + return this.parser as PetLevelUpdateMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/pet/PetScratchFailedMessageEvent.ts b/packages/communication/src/messages/incoming/pet/PetScratchFailedMessageEvent.ts new file mode 100644 index 0000000..0571742 --- /dev/null +++ b/packages/communication/src/messages/incoming/pet/PetScratchFailedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetScratchFailedMessageParser } from './../../parser'; + +export class PetScratchFailedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetScratchFailedMessageParser); + } + + public getParser(): PetScratchFailedMessageParser + { + return this.parser as PetScratchFailedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/pet/PetTrainingPanelMessageEvent.ts b/packages/communication/src/messages/incoming/pet/PetTrainingPanelMessageEvent.ts new file mode 100644 index 0000000..0825b29 --- /dev/null +++ b/packages/communication/src/messages/incoming/pet/PetTrainingPanelMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetTrainingMessageParser } from './../../parser'; + +export class PetTrainingPanelMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetTrainingMessageParser); + } + + public getParser(): PetTrainingMessageParser + { + return this.parser as PetTrainingMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/pet/breeding/PetBreedingMessageEvent.ts b/packages/communication/src/messages/incoming/pet/breeding/PetBreedingMessageEvent.ts new file mode 100644 index 0000000..0f8cb1f --- /dev/null +++ b/packages/communication/src/messages/incoming/pet/breeding/PetBreedingMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetBreedingMessageParser } from './../../../parser'; + +export class PetBreedingMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetBreedingMessageParser); + } + + public getParser(): PetBreedingMessageParser + { + return this.parser as PetBreedingMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/pet/breeding/index.ts b/packages/communication/src/messages/incoming/pet/breeding/index.ts new file mode 100644 index 0000000..c18ef67 --- /dev/null +++ b/packages/communication/src/messages/incoming/pet/breeding/index.ts @@ -0,0 +1 @@ +export * from './PetBreedingMessageEvent'; diff --git a/packages/communication/src/messages/incoming/pet/index.ts b/packages/communication/src/messages/incoming/pet/index.ts new file mode 100644 index 0000000..d5fb00b --- /dev/null +++ b/packages/communication/src/messages/incoming/pet/index.ts @@ -0,0 +1,6 @@ +export * from './breeding'; +export * from './OpenPetPackageRequestedMessageEvent'; +export * from './OpenPetPackageResultMessageEvent'; +export * from './PetLevelUpdateMessageEvent'; +export * from './PetScratchFailedMessageEvent'; +export * from './PetTrainingPanelMessageEvent'; diff --git a/packages/communication/src/messages/incoming/poll/PollContentsEvent.ts b/packages/communication/src/messages/incoming/poll/PollContentsEvent.ts new file mode 100644 index 0000000..1c241a2 --- /dev/null +++ b/packages/communication/src/messages/incoming/poll/PollContentsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PollContentsParser } from '../../parser'; + +export class PollContentsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PollContentsParser); + } + + public getParser(): PollContentsParser + { + return this.parser as PollContentsParser; + } +} diff --git a/packages/communication/src/messages/incoming/poll/PollErrorEvent.ts b/packages/communication/src/messages/incoming/poll/PollErrorEvent.ts new file mode 100644 index 0000000..9a4b478 --- /dev/null +++ b/packages/communication/src/messages/incoming/poll/PollErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PollErrorParser } from '../../parser'; + +export class PollErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PollErrorParser); + } + + public getParser(): PollErrorParser + { + return this.parser as PollErrorParser; + } +} diff --git a/packages/communication/src/messages/incoming/poll/PollOfferEvent.ts b/packages/communication/src/messages/incoming/poll/PollOfferEvent.ts new file mode 100644 index 0000000..b72ea66 --- /dev/null +++ b/packages/communication/src/messages/incoming/poll/PollOfferEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PollOfferParser } from '../../parser'; + +export class PollOfferEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PollOfferParser); + } + + public getParser(): PollOfferParser + { + return this.parser as PollOfferParser; + } +} diff --git a/packages/communication/src/messages/incoming/poll/QuestionAnsweredEvent.ts b/packages/communication/src/messages/incoming/poll/QuestionAnsweredEvent.ts new file mode 100644 index 0000000..7dd889f --- /dev/null +++ b/packages/communication/src/messages/incoming/poll/QuestionAnsweredEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { QuestionAnsweredParser } from '../../parser'; + +export class QuestionAnsweredEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, QuestionAnsweredParser); + } + + public getParser(): QuestionAnsweredParser + { + return this.parser as QuestionAnsweredParser; + } +} diff --git a/packages/communication/src/messages/incoming/poll/QuestionEvent.ts b/packages/communication/src/messages/incoming/poll/QuestionEvent.ts new file mode 100644 index 0000000..6a9b153 --- /dev/null +++ b/packages/communication/src/messages/incoming/poll/QuestionEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { QuestionParser } from '../../parser'; + +export class QuestionEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, QuestionParser); + } + + public getParser(): QuestionParser + { + return this.parser as QuestionParser; + } +} diff --git a/packages/communication/src/messages/incoming/poll/QuestionFinishedEvent.ts b/packages/communication/src/messages/incoming/poll/QuestionFinishedEvent.ts new file mode 100644 index 0000000..21b0226 --- /dev/null +++ b/packages/communication/src/messages/incoming/poll/QuestionFinishedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { QuestionFinishedParser } from '../../parser'; + +export class QuestionFinishedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, QuestionFinishedParser); + } + + public getParser(): QuestionFinishedParser + { + return this.parser as QuestionFinishedParser; + } +} diff --git a/packages/communication/src/messages/incoming/poll/RoomPollResultEvent.ts b/packages/communication/src/messages/incoming/poll/RoomPollResultEvent.ts new file mode 100644 index 0000000..dbafbf6 --- /dev/null +++ b/packages/communication/src/messages/incoming/poll/RoomPollResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomPollResultParser } from '../../parser'; + +export class RoomPollResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomPollResultParser); + } + + public getParser(): RoomPollResultParser + { + return this.parser as RoomPollResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/poll/StartRoomPollEvent.ts b/packages/communication/src/messages/incoming/poll/StartRoomPollEvent.ts new file mode 100644 index 0000000..c7d5cfc --- /dev/null +++ b/packages/communication/src/messages/incoming/poll/StartRoomPollEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomPollDataParser } from '../../parser'; + +export class StartRoomPollEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomPollDataParser); + } + + public getParser(): RoomPollDataParser + { + return this.parser as RoomPollDataParser; + } +} diff --git a/packages/communication/src/messages/incoming/poll/index.ts b/packages/communication/src/messages/incoming/poll/index.ts new file mode 100644 index 0000000..a90c6f5 --- /dev/null +++ b/packages/communication/src/messages/incoming/poll/index.ts @@ -0,0 +1,8 @@ +export * from './PollContentsEvent'; +export * from './PollErrorEvent'; +export * from './PollOfferEvent'; +export * from './QuestionAnsweredEvent'; +export * from './QuestionEvent'; +export * from './QuestionFinishedEvent'; +export * from './RoomPollResultEvent'; +export * from './StartRoomPollEvent'; diff --git a/packages/communication/src/messages/incoming/quest/CommunityGoalEarnedPrizesMessageEvent.ts b/packages/communication/src/messages/incoming/quest/CommunityGoalEarnedPrizesMessageEvent.ts new file mode 100644 index 0000000..7bf00ee --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/CommunityGoalEarnedPrizesMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CommunityGoalEarnedPrizesMessageParser } from '../../parser'; + +export class CommunityGoalEarnedPrizesMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CommunityGoalEarnedPrizesMessageParser); + } + + public getParser(): CommunityGoalEarnedPrizesMessageParser + { + return this.parser as CommunityGoalEarnedPrizesMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/CommunityGoalHallOfFameMessageEvent.ts b/packages/communication/src/messages/incoming/quest/CommunityGoalHallOfFameMessageEvent.ts new file mode 100644 index 0000000..bb4c09e --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/CommunityGoalHallOfFameMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CommunityGoalHallOfFameMessageParser } from '../../parser'; + +export class CommunityGoalHallOfFameMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CommunityGoalHallOfFameMessageParser); + } + + public getParser(): CommunityGoalHallOfFameMessageParser + { + return this.parser as CommunityGoalHallOfFameMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/CommunityGoalProgressMessageEvent.ts b/packages/communication/src/messages/incoming/quest/CommunityGoalProgressMessageEvent.ts new file mode 100644 index 0000000..4f3ebd1 --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/CommunityGoalProgressMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CommunityGoalProgressMessageParser } from '../../parser'; + +export class CommunityGoalProgressMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CommunityGoalProgressMessageParser); + } + + public getParser(): CommunityGoalProgressMessageParser + { + return this.parser as CommunityGoalProgressMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/ConcurrentUsersGoalProgressMessageEvent.ts b/packages/communication/src/messages/incoming/quest/ConcurrentUsersGoalProgressMessageEvent.ts new file mode 100644 index 0000000..1684a75 --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/ConcurrentUsersGoalProgressMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ConcurrentUsersGoalProgressMessageParser } from '../../parser'; + +export class ConcurrentUsersGoalProgressMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ConcurrentUsersGoalProgressMessageParser); + } + + public getParser(): ConcurrentUsersGoalProgressMessageParser + { + return this.parser as ConcurrentUsersGoalProgressMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/EpicPopupMessageEvent.ts b/packages/communication/src/messages/incoming/quest/EpicPopupMessageEvent.ts new file mode 100644 index 0000000..6812fdc --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/EpicPopupMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { EpicPopupMessageParser } from '../../parser'; + +export class EpicPopupMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, EpicPopupMessageParser); + } + + public getParser(): EpicPopupMessageParser + { + return this.parser as EpicPopupMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/QuestCancelledMessageEvent.ts b/packages/communication/src/messages/incoming/quest/QuestCancelledMessageEvent.ts new file mode 100644 index 0000000..1c00e67 --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/QuestCancelledMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { QuestCancelledMessageParser } from '../../parser'; + +export class QuestCancelledMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, QuestCancelledMessageParser); + } + + public getParser(): QuestCancelledMessageParser + { + return this.parser as QuestCancelledMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/QuestCompletedMessageEvent.ts b/packages/communication/src/messages/incoming/quest/QuestCompletedMessageEvent.ts new file mode 100644 index 0000000..c864e81 --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/QuestCompletedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { QuestCompletedMessageParser } from '../../parser'; + +export class QuestCompletedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, QuestCompletedMessageParser); + } + + public getParser(): QuestCompletedMessageParser + { + return this.parser as QuestCompletedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/QuestDailyMessageEvent.ts b/packages/communication/src/messages/incoming/quest/QuestDailyMessageEvent.ts new file mode 100644 index 0000000..97299a5 --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/QuestDailyMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { QuestDailyMessageParser } from '../../parser'; + +export class QuestDailyMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, QuestDailyMessageParser); + } + + public getParser(): QuestDailyMessageParser + { + return this.parser as QuestDailyMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/QuestMessageEvent.ts b/packages/communication/src/messages/incoming/quest/QuestMessageEvent.ts new file mode 100644 index 0000000..a592186 --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/QuestMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { QuestMessageParser } from '../../parser'; + +export class QuestMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, QuestMessageParser); + } + + public getParser(): QuestMessageParser + { + return this.parser as QuestMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/QuestsMessageEvent.ts b/packages/communication/src/messages/incoming/quest/QuestsMessageEvent.ts new file mode 100644 index 0000000..cbdadef --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/QuestsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { QuestsMessageParser } from '../../parser'; + +export class QuestsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, QuestsMessageParser); + } + + public getParser(): QuestsMessageParser + { + return this.parser as QuestsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/SeasonalQuestsMessageEvent.ts b/packages/communication/src/messages/incoming/quest/SeasonalQuestsMessageEvent.ts new file mode 100644 index 0000000..f2417b5 --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/SeasonalQuestsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { SeasonalQuestsParser } from '../../parser'; + +export class SeasonalQuestsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, SeasonalQuestsParser); + } + + public getParser(): SeasonalQuestsParser + { + return this.parser as SeasonalQuestsParser; + } +} diff --git a/packages/communication/src/messages/incoming/quest/index.ts b/packages/communication/src/messages/incoming/quest/index.ts new file mode 100644 index 0000000..f2b8707 --- /dev/null +++ b/packages/communication/src/messages/incoming/quest/index.ts @@ -0,0 +1,11 @@ +export * from './CommunityGoalEarnedPrizesMessageEvent'; +export * from './CommunityGoalHallOfFameMessageEvent'; +export * from './CommunityGoalProgressMessageEvent'; +export * from './ConcurrentUsersGoalProgressMessageEvent'; +export * from './EpicPopupMessageEvent'; +export * from './QuestCancelledMessageEvent'; +export * from './QuestCompletedMessageEvent'; +export * from './QuestDailyMessageEvent'; +export * from './QuestMessageEvent'; +export * from './QuestsMessageEvent'; +export * from './SeasonalQuestsMessageEvent'; diff --git a/packages/communication/src/messages/incoming/recycler/RecyclerFinishedMessageEvent.ts b/packages/communication/src/messages/incoming/recycler/RecyclerFinishedMessageEvent.ts new file mode 100644 index 0000000..eb5f1e9 --- /dev/null +++ b/packages/communication/src/messages/incoming/recycler/RecyclerFinishedMessageEvent.ts @@ -0,0 +1,19 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RecyclerFinishedMessageParser } from '../../parser'; + +export class RecyclerFinishedMessageEvent extends MessageEvent implements IMessageEvent +{ + public static readonly FINISHED_OK: number = 1; + public static readonly FINISHED_FAIL: number = 2; + + constructor(callBack: Function) + { + super(callBack, RecyclerFinishedMessageParser); + } + + public getParser(): RecyclerFinishedMessageParser + { + return this.parser as RecyclerFinishedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/recycler/RecyclerStatusMessageEvent.ts b/packages/communication/src/messages/incoming/recycler/RecyclerStatusMessageEvent.ts new file mode 100644 index 0000000..69f3c94 --- /dev/null +++ b/packages/communication/src/messages/incoming/recycler/RecyclerStatusMessageEvent.ts @@ -0,0 +1,20 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RecyclerStatusMessageParser } from '../../parser'; + +export class RecyclerStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + public static readonly SYSTEM_STATUS_ENABLED: number = 1; + public static readonly SYSTEM_STATUS_DISABLED: number = 2; + public static readonly SYSTEM_STATUS_TIMEOUT: number = 3; + + constructor(callBack: Function) + { + super(callBack, RecyclerStatusMessageParser); + } + + public getParser(): RecyclerStatusMessageParser + { + return this.parser as RecyclerStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/recycler/index.ts b/packages/communication/src/messages/incoming/recycler/index.ts new file mode 100644 index 0000000..b6f40ee --- /dev/null +++ b/packages/communication/src/messages/incoming/recycler/index.ts @@ -0,0 +1,2 @@ +export * from './RecyclerFinishedMessageEvent'; +export * from './RecyclerStatusMessageEvent'; diff --git a/packages/communication/src/messages/incoming/room/access/RoomEnterErrorEvent.ts b/packages/communication/src/messages/incoming/room/access/RoomEnterErrorEvent.ts new file mode 100644 index 0000000..8728f86 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/access/RoomEnterErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CantConnectMessageParser } from '../../../parser'; + +export class RoomEnterErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CantConnectMessageParser); + } + + public getParser(): CantConnectMessageParser + { + return this.parser as CantConnectMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/access/RoomEnterEvent.ts b/packages/communication/src/messages/incoming/room/access/RoomEnterEvent.ts new file mode 100644 index 0000000..f4d23b0 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/access/RoomEnterEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomEnterParser } from '../../../parser'; + +export class RoomEnterEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomEnterParser); + } + + public getParser(): RoomEnterParser + { + return this.parser as RoomEnterParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/access/RoomForwardEvent.ts b/packages/communication/src/messages/incoming/room/access/RoomForwardEvent.ts new file mode 100644 index 0000000..d36e606 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/access/RoomForwardEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomFowardParser as RoomForwardParser } from '../../../parser'; + +export class RoomForwardEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomForwardParser); + } + + public getParser(): RoomForwardParser + { + return this.parser as RoomForwardParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/access/doorbell/RoomDoorbellAcceptedEvent.ts b/packages/communication/src/messages/incoming/room/access/doorbell/RoomDoorbellAcceptedEvent.ts new file mode 100644 index 0000000..c504dc8 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/access/doorbell/RoomDoorbellAcceptedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomDoorbellAcceptedParser } from '../../../../parser'; + +export class RoomDoorbellAcceptedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomDoorbellAcceptedParser); + } + + public getParser(): RoomDoorbellAcceptedParser + { + return this.parser as RoomDoorbellAcceptedParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/access/doorbell/index.ts b/packages/communication/src/messages/incoming/room/access/doorbell/index.ts new file mode 100644 index 0000000..ce67bee --- /dev/null +++ b/packages/communication/src/messages/incoming/room/access/doorbell/index.ts @@ -0,0 +1 @@ +export * from './RoomDoorbellAcceptedEvent'; diff --git a/packages/communication/src/messages/incoming/room/access/index.ts b/packages/communication/src/messages/incoming/room/access/index.ts new file mode 100644 index 0000000..0e1f2d7 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/access/index.ts @@ -0,0 +1,5 @@ +export * from './doorbell'; +export * from './rights'; +export * from './RoomEnterErrorEvent'; +export * from './RoomEnterEvent'; +export * from './RoomForwardEvent'; diff --git a/packages/communication/src/messages/incoming/room/access/rights/RoomRightsClearEvent.ts b/packages/communication/src/messages/incoming/room/access/rights/RoomRightsClearEvent.ts new file mode 100644 index 0000000..f35a282 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/access/rights/RoomRightsClearEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomRightsClearParser } from '../../../../parser'; + +export class RoomRightsClearEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomRightsClearParser); + } + + public getParser(): RoomRightsClearParser + { + return this.parser as RoomRightsClearParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/access/rights/RoomRightsEvent.ts b/packages/communication/src/messages/incoming/room/access/rights/RoomRightsEvent.ts new file mode 100644 index 0000000..053909e --- /dev/null +++ b/packages/communication/src/messages/incoming/room/access/rights/RoomRightsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomRightsParser } from '../../../../parser'; + +export class RoomRightsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomRightsParser); + } + + public getParser(): RoomRightsParser + { + return this.parser as RoomRightsParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/access/rights/RoomRightsOwnerEvent.ts b/packages/communication/src/messages/incoming/room/access/rights/RoomRightsOwnerEvent.ts new file mode 100644 index 0000000..c0bad6e --- /dev/null +++ b/packages/communication/src/messages/incoming/room/access/rights/RoomRightsOwnerEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomRightsOwnerParser } from '../../../../parser'; + +export class RoomRightsOwnerEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomRightsOwnerParser); + } + + public getParser(): RoomRightsOwnerParser + { + return this.parser as RoomRightsOwnerParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/access/rights/index.ts b/packages/communication/src/messages/incoming/room/access/rights/index.ts new file mode 100644 index 0000000..9569969 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/access/rights/index.ts @@ -0,0 +1,3 @@ +export * from './RoomRightsClearEvent'; +export * from './RoomRightsEvent'; +export * from './RoomRightsOwnerEvent'; diff --git a/packages/communication/src/messages/incoming/room/bots/BotCommandConfigurationEvent.ts b/packages/communication/src/messages/incoming/room/bots/BotCommandConfigurationEvent.ts new file mode 100644 index 0000000..e72008b --- /dev/null +++ b/packages/communication/src/messages/incoming/room/bots/BotCommandConfigurationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BotCommandConfigurationParser } from '../../../parser'; + +export class BotCommandConfigurationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotCommandConfigurationParser); + } + + public getParser(): BotCommandConfigurationParser + { + return this.parser as BotCommandConfigurationParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/bots/BotForceOpenContextMenuEvent.ts b/packages/communication/src/messages/incoming/room/bots/BotForceOpenContextMenuEvent.ts new file mode 100644 index 0000000..beb5166 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/bots/BotForceOpenContextMenuEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BotForceOpenContextMenuParser } from '../../../parser'; + +export class BotForceOpenContextMenuEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotForceOpenContextMenuParser); + } + + public getParser(): BotForceOpenContextMenuParser + { + return this.parser as BotForceOpenContextMenuParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/bots/BotSkillListUpdateEvent.ts b/packages/communication/src/messages/incoming/room/bots/BotSkillListUpdateEvent.ts new file mode 100644 index 0000000..4be59a7 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/bots/BotSkillListUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BotSkillListUpdateParser } from '../../../parser'; + +export class BotSkillListUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotSkillListUpdateParser); + } + + public getParser(): BotSkillListUpdateParser + { + return this.parser as BotSkillListUpdateParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/bots/index.ts b/packages/communication/src/messages/incoming/room/bots/index.ts new file mode 100644 index 0000000..cae047b --- /dev/null +++ b/packages/communication/src/messages/incoming/room/bots/index.ts @@ -0,0 +1,3 @@ +export * from './BotCommandConfigurationEvent'; +export * from './BotForceOpenContextMenuEvent'; +export * from './BotSkillListUpdateEvent'; diff --git a/packages/communication/src/messages/incoming/room/data/RoomChatSettingsEvent.ts b/packages/communication/src/messages/incoming/room/data/RoomChatSettingsEvent.ts new file mode 100644 index 0000000..0bddf54 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/data/RoomChatSettingsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomChatSettingsParser } from '../../../parser'; + +export class RoomChatSettingsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomChatSettingsParser); + } + + public getParser(): RoomChatSettingsParser + { + return this.parser as RoomChatSettingsParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/data/RoomEntryInfoMessageEvent.ts b/packages/communication/src/messages/incoming/room/data/RoomEntryInfoMessageEvent.ts new file mode 100644 index 0000000..52bb798 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/data/RoomEntryInfoMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomEntryInfoMessageParser } from '../../../parser'; + +export class RoomEntryInfoMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomEntryInfoMessageParser); + } + + public getParser(): RoomEntryInfoMessageParser + { + return this.parser as RoomEntryInfoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/data/RoomScoreEvent.ts b/packages/communication/src/messages/incoming/room/data/RoomScoreEvent.ts new file mode 100644 index 0000000..1b61c3e --- /dev/null +++ b/packages/communication/src/messages/incoming/room/data/RoomScoreEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomScoreParser } from '../../../parser'; + +export class RoomScoreEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomScoreParser); + } + + public getParser(): RoomScoreParser + { + return this.parser as RoomScoreParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/data/index.ts b/packages/communication/src/messages/incoming/room/data/index.ts new file mode 100644 index 0000000..e0187f0 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/data/index.ts @@ -0,0 +1,3 @@ +export * from './RoomChatSettingsEvent'; +export * from './RoomEntryInfoMessageEvent'; +export * from './RoomScoreEvent'; diff --git a/packages/communication/src/messages/incoming/room/engine/FavoriteMembershipUpdateMessageEvent.ts b/packages/communication/src/messages/incoming/room/engine/FavoriteMembershipUpdateMessageEvent.ts new file mode 100644 index 0000000..22d0673 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/engine/FavoriteMembershipUpdateMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FavoriteMembershipUpdateMessageParser } from '../../../parser'; + +export class FavoriteMembershipUpdateMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FavoriteMembershipUpdateMessageParser); + } + + public getParser(): FavoriteMembershipUpdateMessageParser + { + return this.parser as FavoriteMembershipUpdateMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/engine/ObjectsDataUpdateEvent.ts b/packages/communication/src/messages/incoming/room/engine/ObjectsDataUpdateEvent.ts new file mode 100644 index 0000000..b437f67 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/engine/ObjectsDataUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ObjectsDataUpdateParser } from '../../../parser'; + +export class ObjectsDataUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ObjectsDataUpdateParser); + } + + public getParser(): ObjectsDataUpdateParser + { + return this.parser as ObjectsDataUpdateParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/engine/ObjectsRollingEvent.ts b/packages/communication/src/messages/incoming/room/engine/ObjectsRollingEvent.ts new file mode 100644 index 0000000..0933888 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/engine/ObjectsRollingEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ObjectsRollingParser } from '../../../parser'; + +export class ObjectsRollingEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ObjectsRollingParser); + } + + public getParser(): ObjectsRollingParser + { + return this.parser as ObjectsRollingParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/engine/index.ts b/packages/communication/src/messages/incoming/room/engine/index.ts new file mode 100644 index 0000000..24ceed5 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/engine/index.ts @@ -0,0 +1,3 @@ +export * from './FavoriteMembershipUpdateMessageEvent'; +export * from './ObjectsDataUpdateEvent'; +export * from './ObjectsRollingEvent'; diff --git a/packages/communication/src/messages/incoming/room/furniture/CustomUserNotificationMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/CustomUserNotificationMessageEvent.ts new file mode 100644 index 0000000..5d9985a --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/CustomUserNotificationMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { CustomUserNotificationMessageParser } from '../../../parser'; + +export class CustomUserNotificationMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CustomUserNotificationMessageParser); + } + + public getParser(): CustomUserNotificationMessageParser + { + return this.parser as CustomUserNotificationMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/DiceValueMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/DiceValueMessageEvent.ts new file mode 100644 index 0000000..f51f6ea --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/DiceValueMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { DiceValueMessageParser } from '../../../parser'; + +export class DiceValueMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, DiceValueMessageParser); + } + + public getParser(): DiceValueMessageParser + { + return this.parser as DiceValueMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/FurniRentOrBuyoutOfferMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/FurniRentOrBuyoutOfferMessageEvent.ts new file mode 100644 index 0000000..8bd9108 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/FurniRentOrBuyoutOfferMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurniRentOrBuyoutOfferMessageParser } from '../../../parser'; + +export class FurniRentOrBuyoutOfferMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurniRentOrBuyoutOfferMessageParser); + } + + public getParser(): FurniRentOrBuyoutOfferMessageParser + { + return this.parser as FurniRentOrBuyoutOfferMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/FurnitureAliasesEvent.ts b/packages/communication/src/messages/incoming/room/furniture/FurnitureAliasesEvent.ts new file mode 100644 index 0000000..889f2d1 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/FurnitureAliasesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureAliasesParser } from '../../../parser'; + +export class FurnitureAliasesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureAliasesParser); + } + + public getParser(): FurnitureAliasesParser + { + return this.parser as FurnitureAliasesParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/FurnitureDataEvent.ts b/packages/communication/src/messages/incoming/room/furniture/FurnitureDataEvent.ts new file mode 100644 index 0000000..2d79a96 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/FurnitureDataEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureDataParser } from '../../../parser'; + +export class FurnitureDataEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureDataParser); + } + + public getParser(): FurnitureDataParser + { + return this.parser as FurnitureDataParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/FurnitureStackHeightEvent.ts b/packages/communication/src/messages/incoming/room/furniture/FurnitureStackHeightEvent.ts new file mode 100644 index 0000000..a3567b5 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/FurnitureStackHeightEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureStackHeightParser } from '../../../parser'; + +export class FurnitureStackHeightEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureStackHeightParser); + } + + public getParser(): FurnitureStackHeightParser + { + return this.parser as FurnitureStackHeightParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/GroupFurniContextMenuInfoMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/GroupFurniContextMenuInfoMessageEvent.ts new file mode 100644 index 0000000..39ae2e4 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/GroupFurniContextMenuInfoMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GroupFurniContextMenuInfoMessageParser } from '../../../parser'; + +export class GroupFurniContextMenuInfoMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupFurniContextMenuInfoMessageParser); + } + + public getParser(): GroupFurniContextMenuInfoMessageParser + { + return this.parser as GroupFurniContextMenuInfoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/ItemDataUpdateMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/ItemDataUpdateMessageEvent.ts new file mode 100644 index 0000000..93b5b53 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/ItemDataUpdateMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ItemDataUpdateMessageParser } from '../../../parser'; + +export class ItemDataUpdateMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ItemDataUpdateMessageParser); + } + + public getParser(): ItemDataUpdateMessageParser + { + return this.parser as ItemDataUpdateMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/LoveLockFurniFinishedEvent.ts b/packages/communication/src/messages/incoming/room/furniture/LoveLockFurniFinishedEvent.ts new file mode 100644 index 0000000..f11a0a4 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/LoveLockFurniFinishedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { LoveLockFurniFinishedParser } from '../../../parser'; + +export class LoveLockFurniFinishedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LoveLockFurniFinishedParser); + } + + public getParser(): LoveLockFurniFinishedParser + { + return this.parser as LoveLockFurniFinishedParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/LoveLockFurniFriendConfirmedEvent.ts b/packages/communication/src/messages/incoming/room/furniture/LoveLockFurniFriendConfirmedEvent.ts new file mode 100644 index 0000000..a957f9d --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/LoveLockFurniFriendConfirmedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { LoveLockFurniFriendConfirmedParser } from '../../../parser'; + +export class LoveLockFurniFriendConfirmedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LoveLockFurniFriendConfirmedParser); + } + + public getParser(): LoveLockFurniFriendConfirmedParser + { + return this.parser as LoveLockFurniFriendConfirmedParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/LoveLockFurniStartEvent.ts b/packages/communication/src/messages/incoming/room/furniture/LoveLockFurniStartEvent.ts new file mode 100644 index 0000000..d096e0a --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/LoveLockFurniStartEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { LoveLockFurniStartParser } from '../../../parser'; + +export class LoveLockFurniStartEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LoveLockFurniStartParser); + } + + public getParser(): LoveLockFurniStartParser + { + return this.parser as LoveLockFurniStartParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/OneWayDoorStatusMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/OneWayDoorStatusMessageEvent.ts new file mode 100644 index 0000000..47c94aa --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/OneWayDoorStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { OneWayDoorStatusMessageParser } from '../../../parser'; + +export class OneWayDoorStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, OneWayDoorStatusMessageParser); + } + + public getParser(): OneWayDoorStatusMessageParser + { + return this.parser as OneWayDoorStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/RentableSpaceRentFailedMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/RentableSpaceRentFailedMessageEvent.ts new file mode 100644 index 0000000..7d89a75 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/RentableSpaceRentFailedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RentableSpaceRentFailedMessageParser } from '../../../parser'; + +export class RentableSpaceRentFailedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RentableSpaceRentFailedMessageParser); + } + + public getParser(): RentableSpaceRentFailedMessageParser + { + return this.parser as RentableSpaceRentFailedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/RentableSpaceRentOkMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/RentableSpaceRentOkMessageEvent.ts new file mode 100644 index 0000000..4f4411b --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/RentableSpaceRentOkMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RentableSpaceRentOkMessageParser } from '../../../parser'; + +export class RentableSpaceRentOkMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RentableSpaceRentOkMessageParser); + } + + public getParser(): RentableSpaceRentOkMessageParser + { + return this.parser as RentableSpaceRentOkMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/RentableSpaceStatusMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/RentableSpaceStatusMessageEvent.ts new file mode 100644 index 0000000..144901f --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/RentableSpaceStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RentableSpaceStatusMessageParser } from '../../../parser'; + +export class RentableSpaceStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RentableSpaceStatusMessageParser); + } + + public getParser(): RentableSpaceStatusMessageParser + { + return this.parser as RentableSpaceStatusMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/RequestSpamWallPostItMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/RequestSpamWallPostItMessageEvent.ts new file mode 100644 index 0000000..a56e186 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/RequestSpamWallPostItMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RequestSpamWallPostItMessageParser } from '../../../parser'; + +export class RequestSpamWallPostItMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RequestSpamWallPostItMessageParser); + } + + public getParser(): RequestSpamWallPostItMessageParser + { + return this.parser as RequestSpamWallPostItMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/RoomDimmerPresetsMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/RoomDimmerPresetsMessageEvent.ts new file mode 100644 index 0000000..f2bc75c --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/RoomDimmerPresetsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomDimmerPresetsMessageParser } from '../../../parser'; + +export class RoomDimmerPresetsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomDimmerPresetsMessageParser); + } + + public getParser(): RoomDimmerPresetsMessageParser + { + return this.parser as RoomDimmerPresetsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/RoomMessageNotificationMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/RoomMessageNotificationMessageEvent.ts new file mode 100644 index 0000000..38ec773 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/RoomMessageNotificationMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomMessageNotificationMessageParser } from '../../../parser'; + +export class RoomMessageNotificationMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomMessageNotificationMessageParser); + } + + public getParser(): RoomMessageNotificationMessageParser + { + return this.parser as RoomMessageNotificationMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/WelcomeGiftStatusEvent.ts b/packages/communication/src/messages/incoming/room/furniture/WelcomeGiftStatusEvent.ts new file mode 100644 index 0000000..f5d2f84 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/WelcomeGiftStatusEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WelcomeGiftStatusParser } from '../../../parser'; + +export class WelcomeGiftStatusEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WelcomeGiftStatusParser); + } + + public getParser(): WelcomeGiftStatusParser + { + return this.parser as WelcomeGiftStatusParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorAddEvent.ts b/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorAddEvent.ts new file mode 100644 index 0000000..7110566 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorAddEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureFloorAddParser } from '../../../../parser'; + +export class FurnitureFloorAddEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureFloorAddParser); + } + + public getParser(): FurnitureFloorAddParser + { + return this.parser as FurnitureFloorAddParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorEvent.ts b/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorEvent.ts new file mode 100644 index 0000000..aa306ad --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureFloorParser } from '../../../../parser'; + +export class FurnitureFloorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureFloorParser); + } + + public getParser(): FurnitureFloorParser + { + return this.parser as FurnitureFloorParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorRemoveEvent.ts b/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorRemoveEvent.ts new file mode 100644 index 0000000..2e52e7d --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorRemoveEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureFloorRemoveParser } from '../../../../parser'; + +export class FurnitureFloorRemoveEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureFloorRemoveParser); + } + + public getParser(): FurnitureFloorRemoveParser + { + return this.parser as FurnitureFloorRemoveParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorUpdateEvent.ts b/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorUpdateEvent.ts new file mode 100644 index 0000000..649a919 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/floor/FurnitureFloorUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureFloorUpdateParser } from '../../../../parser'; + +export class FurnitureFloorUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureFloorUpdateParser); + } + + public getParser(): FurnitureFloorUpdateParser + { + return this.parser as FurnitureFloorUpdateParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/floor/index.ts b/packages/communication/src/messages/incoming/room/furniture/floor/index.ts new file mode 100644 index 0000000..4b0cb67 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/floor/index.ts @@ -0,0 +1,4 @@ +export * from './FurnitureFloorAddEvent'; +export * from './FurnitureFloorEvent'; +export * from './FurnitureFloorRemoveEvent'; +export * from './FurnitureFloorUpdateEvent'; diff --git a/packages/communication/src/messages/incoming/room/furniture/index.ts b/packages/communication/src/messages/incoming/room/furniture/index.ts new file mode 100644 index 0000000..3926d97 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/index.ts @@ -0,0 +1,22 @@ +export * from './CustomUserNotificationMessageEvent'; +export * from './DiceValueMessageEvent'; +export * from './floor'; +export * from './FurniRentOrBuyoutOfferMessageEvent'; +export * from './FurnitureAliasesEvent'; +export * from './FurnitureDataEvent'; +export * from './FurnitureStackHeightEvent'; +export * from './GroupFurniContextMenuInfoMessageEvent'; +export * from './ItemDataUpdateMessageEvent'; +export * from './LoveLockFurniFinishedEvent'; +export * from './LoveLockFurniFriendConfirmedEvent'; +export * from './LoveLockFurniStartEvent'; +export * from './OneWayDoorStatusMessageEvent'; +export * from './RentableSpaceRentFailedMessageEvent'; +export * from './RentableSpaceRentOkMessageEvent'; +export * from './RentableSpaceStatusMessageEvent'; +export * from './RequestSpamWallPostItMessageEvent'; +export * from './RoomDimmerPresetsMessageEvent'; +export * from './RoomMessageNotificationMessageEvent'; +export * from './wall'; +export * from './WelcomeGiftStatusEvent'; +export * from './youtube'; diff --git a/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallAddEvent.ts b/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallAddEvent.ts new file mode 100644 index 0000000..65ed984 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallAddEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureWallAddParser } from '../../../../parser'; + +export class FurnitureWallAddEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureWallAddParser); + } + + public getParser(): FurnitureWallAddParser + { + return this.parser as FurnitureWallAddParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallEvent.ts b/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallEvent.ts new file mode 100644 index 0000000..9fa41de --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureWallParser } from '../../../../parser'; + +export class FurnitureWallEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureWallParser); + } + + public getParser(): FurnitureWallParser + { + return this.parser as FurnitureWallParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallRemoveEvent.ts b/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallRemoveEvent.ts new file mode 100644 index 0000000..629bea0 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallRemoveEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureWallRemoveParser } from '../../../../parser'; + +export class FurnitureWallRemoveEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureWallRemoveParser); + } + + public getParser(): FurnitureWallRemoveParser + { + return this.parser as FurnitureWallRemoveParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallUpdateEvent.ts b/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallUpdateEvent.ts new file mode 100644 index 0000000..9de2f54 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/wall/FurnitureWallUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FurnitureWallUpdateParser } from '../../../../parser'; + +export class FurnitureWallUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureWallUpdateParser); + } + + public getParser(): FurnitureWallUpdateParser + { + return this.parser as FurnitureWallUpdateParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/wall/index.ts b/packages/communication/src/messages/incoming/room/furniture/wall/index.ts new file mode 100644 index 0000000..3065491 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/wall/index.ts @@ -0,0 +1,4 @@ +export * from './FurnitureWallAddEvent'; +export * from './FurnitureWallEvent'; +export * from './FurnitureWallRemoveEvent'; +export * from './FurnitureWallUpdateEvent'; diff --git a/packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeControlVideoMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeControlVideoMessageEvent.ts new file mode 100644 index 0000000..07bd036 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeControlVideoMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { YoutubeControlVideoMessageParser } from '../../../../parser'; + +export class YoutubeControlVideoMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, YoutubeControlVideoMessageParser); + } + + public getParser(): YoutubeControlVideoMessageParser + { + return this.parser as YoutubeControlVideoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeDisplayPlaylistsEvent.ts b/packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeDisplayPlaylistsEvent.ts new file mode 100644 index 0000000..e0cc322 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeDisplayPlaylistsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { YoutubeDisplayPlaylistsMessageParser } from '../../../../parser'; + +export class YoutubeDisplayPlaylistsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, YoutubeDisplayPlaylistsMessageParser); + } + + public getParser(): YoutubeDisplayPlaylistsMessageParser + { + return this.parser as YoutubeDisplayPlaylistsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeDisplayVideoMessageEvent.ts b/packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeDisplayVideoMessageEvent.ts new file mode 100644 index 0000000..c5d0808 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/youtube/YoutubeDisplayVideoMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { YoutubeDisplayVideoMessageParser } from '../../../../parser'; + +export class YoutubeDisplayVideoMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, YoutubeDisplayVideoMessageParser); + } + + public getParser(): YoutubeDisplayVideoMessageParser + { + return this.parser as YoutubeDisplayVideoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/furniture/youtube/index.ts b/packages/communication/src/messages/incoming/room/furniture/youtube/index.ts new file mode 100644 index 0000000..4bb22a3 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/furniture/youtube/index.ts @@ -0,0 +1,3 @@ +export * from './YoutubeControlVideoMessageEvent'; +export * from './YoutubeDisplayPlaylistsEvent'; +export * from './YoutubeDisplayVideoMessageEvent'; diff --git a/packages/communication/src/messages/incoming/room/index.ts b/packages/communication/src/messages/incoming/room/index.ts new file mode 100644 index 0000000..81b327b --- /dev/null +++ b/packages/communication/src/messages/incoming/room/index.ts @@ -0,0 +1,15 @@ +export * from './access'; +export * from './access/doorbell'; +export * from './access/rights'; +export * from './bots'; +export * from './data'; +export * from './engine'; +export * from './furniture'; +export * from './furniture/floor'; +export * from './furniture/wall'; +export * from './furniture/youtube'; +export * from './mapping'; +export * from './pet'; +export * from './session'; +export * from './unit'; +export * from './unit/chat'; diff --git a/packages/communication/src/messages/incoming/room/mapping/FloorHeightMapEvent.ts b/packages/communication/src/messages/incoming/room/mapping/FloorHeightMapEvent.ts new file mode 100644 index 0000000..49f3e01 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/mapping/FloorHeightMapEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FloorHeightMapMessageParser } from '../../../parser'; + +export class FloorHeightMapEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FloorHeightMapMessageParser); + } + + public getParser(): FloorHeightMapMessageParser + { + return this.parser as FloorHeightMapMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/mapping/RoomEntryTileMessageEvent.ts b/packages/communication/src/messages/incoming/room/mapping/RoomEntryTileMessageEvent.ts new file mode 100644 index 0000000..b398781 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/mapping/RoomEntryTileMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomEntryTileMessageParser } from '../../../parser'; + +export class RoomEntryTileMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomEntryTileMessageParser); + } + + public getParser(): RoomEntryTileMessageParser + { + return this.parser as RoomEntryTileMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/mapping/RoomHeightMapEvent.ts b/packages/communication/src/messages/incoming/room/mapping/RoomHeightMapEvent.ts new file mode 100644 index 0000000..022ff6e --- /dev/null +++ b/packages/communication/src/messages/incoming/room/mapping/RoomHeightMapEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomHeightMapParser } from '../../../parser'; + +export class RoomHeightMapEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomHeightMapParser); + } + + public getParser(): RoomHeightMapParser + { + return this.parser as RoomHeightMapParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/mapping/RoomHeightMapUpdateEvent.ts b/packages/communication/src/messages/incoming/room/mapping/RoomHeightMapUpdateEvent.ts new file mode 100644 index 0000000..89892ae --- /dev/null +++ b/packages/communication/src/messages/incoming/room/mapping/RoomHeightMapUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomHeightMapUpdateParser } from '../../../parser'; + +export class RoomHeightMapUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomHeightMapUpdateParser); + } + + public getParser(): RoomHeightMapUpdateParser + { + return this.parser as RoomHeightMapUpdateParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/mapping/RoomOccupiedTilesMessageEvent.ts b/packages/communication/src/messages/incoming/room/mapping/RoomOccupiedTilesMessageEvent.ts new file mode 100644 index 0000000..d58d1e9 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/mapping/RoomOccupiedTilesMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomOccupiedTilesMessageParser } from '../../../parser'; + +export class RoomOccupiedTilesMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomOccupiedTilesMessageParser); + } + + public getParser(): RoomOccupiedTilesMessageParser + { + return this.parser as RoomOccupiedTilesMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/mapping/RoomPaintEvent.ts b/packages/communication/src/messages/incoming/room/mapping/RoomPaintEvent.ts new file mode 100644 index 0000000..c6a81e6 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/mapping/RoomPaintEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomPaintParser } from '../../../parser'; + +export class RoomPaintEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomPaintParser); + } + + public getParser(): RoomPaintParser + { + return this.parser as RoomPaintParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/mapping/RoomReadyMessageEvent.ts b/packages/communication/src/messages/incoming/room/mapping/RoomReadyMessageEvent.ts new file mode 100644 index 0000000..9866d91 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/mapping/RoomReadyMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomReadyMessageParser } from '../../../parser'; + +export class RoomReadyMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomReadyMessageParser); + } + + public getParser(): RoomReadyMessageParser + { + return this.parser as RoomReadyMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/mapping/RoomVisualizationSettingsEvent.ts b/packages/communication/src/messages/incoming/room/mapping/RoomVisualizationSettingsEvent.ts new file mode 100644 index 0000000..2c43b55 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/mapping/RoomVisualizationSettingsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomVisualizationSettingsParser } from '../../../parser'; + +export class RoomVisualizationSettingsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomVisualizationSettingsParser); + } + + public getParser(): RoomVisualizationSettingsParser + { + return this.parser as RoomVisualizationSettingsParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/mapping/index.ts b/packages/communication/src/messages/incoming/room/mapping/index.ts new file mode 100644 index 0000000..1ada5b8 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/mapping/index.ts @@ -0,0 +1,8 @@ +export * from './FloorHeightMapEvent'; +export * from './RoomEntryTileMessageEvent'; +export * from './RoomHeightMapEvent'; +export * from './RoomHeightMapUpdateEvent'; +export * from './RoomOccupiedTilesMessageEvent'; +export * from './RoomPaintEvent'; +export * from './RoomReadyMessageEvent'; +export * from './RoomVisualizationSettingsEvent'; diff --git a/packages/communication/src/messages/incoming/room/pet/PetBreedingResultEvent.ts b/packages/communication/src/messages/incoming/room/pet/PetBreedingResultEvent.ts new file mode 100644 index 0000000..15427aa --- /dev/null +++ b/packages/communication/src/messages/incoming/room/pet/PetBreedingResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetBreedingResultParser } from '../../../parser'; + +export class PetBreedingResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetBreedingResultParser); + } + + public getParser(): PetBreedingResultParser + { + return this.parser as PetBreedingResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/pet/PetExperienceEvent.ts b/packages/communication/src/messages/incoming/room/pet/PetExperienceEvent.ts new file mode 100644 index 0000000..e62fb70 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/pet/PetExperienceEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetExperienceParser } from '../../../parser'; + +export class PetExperienceEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetExperienceParser); + } + + public getParser(): PetExperienceParser + { + return this.parser as PetExperienceParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/pet/PetFigureUpdateEvent.ts b/packages/communication/src/messages/incoming/room/pet/PetFigureUpdateEvent.ts new file mode 100644 index 0000000..de538ae --- /dev/null +++ b/packages/communication/src/messages/incoming/room/pet/PetFigureUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetFigureUpdateParser } from '../../../parser'; + +export class PetFigureUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetFigureUpdateParser); + } + + public getParser(): PetFigureUpdateParser + { + return this.parser as PetFigureUpdateParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/pet/PetInfoEvent.ts b/packages/communication/src/messages/incoming/room/pet/PetInfoEvent.ts new file mode 100644 index 0000000..3e42bcf --- /dev/null +++ b/packages/communication/src/messages/incoming/room/pet/PetInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetInfoParser } from '../../../parser'; + +export class PetInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetInfoParser); + } + + public getParser(): PetInfoParser + { + return this.parser as PetInfoParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/pet/PetStatusUpdateEvent.ts b/packages/communication/src/messages/incoming/room/pet/PetStatusUpdateEvent.ts new file mode 100644 index 0000000..587b126 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/pet/PetStatusUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetStatusUpdateParser } from '../../../parser'; + +export class PetStatusUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetStatusUpdateParser); + } + + public getParser(): PetStatusUpdateParser + { + return this.parser as PetStatusUpdateParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/pet/index.ts b/packages/communication/src/messages/incoming/room/pet/index.ts new file mode 100644 index 0000000..e43bd92 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/pet/index.ts @@ -0,0 +1,5 @@ +export * from './PetBreedingResultEvent'; +export * from './PetExperienceEvent'; +export * from './PetFigureUpdateEvent'; +export * from './PetInfoEvent'; +export * from './PetStatusUpdateEvent'; diff --git a/packages/communication/src/messages/incoming/room/session/YouArePlayingGameEvent.ts b/packages/communication/src/messages/incoming/room/session/YouArePlayingGameEvent.ts new file mode 100644 index 0000000..a895b58 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/session/YouArePlayingGameEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { YouArePlayingGameParser } from '../../../parser'; + +export class YouArePlayingGameEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, YouArePlayingGameParser); + } + + public getParser(): YouArePlayingGameParser + { + return this.parser as YouArePlayingGameParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/session/YouAreSpectatorMessageEvent.ts b/packages/communication/src/messages/incoming/room/session/YouAreSpectatorMessageEvent.ts new file mode 100644 index 0000000..70a0067 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/session/YouAreSpectatorMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { YouAreSpectatorMessageParser } from '../../../parser'; + +export class YouAreSpectatorMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, YouAreSpectatorMessageParser); + } + + public getParser(): YouAreSpectatorMessageParser + { + return this.parser as YouAreSpectatorMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/session/index.ts b/packages/communication/src/messages/incoming/room/session/index.ts new file mode 100644 index 0000000..0ac722b --- /dev/null +++ b/packages/communication/src/messages/incoming/room/session/index.ts @@ -0,0 +1,2 @@ +export * from './YouArePlayingGameEvent'; +export * from './YouAreSpectatorMessageEvent'; diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitDanceEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitDanceEvent.ts new file mode 100644 index 0000000..3c2bc06 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitDanceEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitDanceParser } from '../../../parser'; + +export class RoomUnitDanceEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitDanceParser); + } + + public getParser(): RoomUnitDanceParser + { + return this.parser as RoomUnitDanceParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitEffectEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitEffectEvent.ts new file mode 100644 index 0000000..933d21a --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitEffectEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitEffectParser } from '../../../parser'; + +export class RoomUnitEffectEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitEffectParser); + } + + public getParser(): RoomUnitEffectParser + { + return this.parser as RoomUnitEffectParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitEvent.ts new file mode 100644 index 0000000..37a5e09 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitParser } from '../../../parser'; + +export class RoomUnitEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitParser); + } + + public getParser(): RoomUnitParser + { + return this.parser as RoomUnitParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitExpressionEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitExpressionEvent.ts new file mode 100644 index 0000000..f42becf --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitExpressionEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitExpressionParser } from '../../../parser'; + +export class RoomUnitExpressionEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitExpressionParser); + } + + public getParser(): RoomUnitExpressionParser + { + return this.parser as RoomUnitExpressionParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitHandItemEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitHandItemEvent.ts new file mode 100644 index 0000000..dd7a431 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitHandItemEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitHandItemParser } from '../../../parser'; + +export class RoomUnitHandItemEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitHandItemParser); + } + + public getParser(): RoomUnitHandItemParser + { + return this.parser as RoomUnitHandItemParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitHandItemReceivedEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitHandItemReceivedEvent.ts new file mode 100644 index 0000000..05548cd --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitHandItemReceivedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitHandItemReceivedParser } from '../../../parser'; + +export class RoomUnitHandItemReceivedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitHandItemReceivedParser); + } + + public getParser(): RoomUnitHandItemReceivedParser + { + return this.parser as RoomUnitHandItemReceivedParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitIdleEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitIdleEvent.ts new file mode 100644 index 0000000..263e64f --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitIdleEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitIdleParser } from '../../../parser'; + +export class RoomUnitIdleEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitIdleParser); + } + + public getParser(): RoomUnitIdleParser + { + return this.parser as RoomUnitIdleParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitInfoEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitInfoEvent.ts new file mode 100644 index 0000000..f4f91aa --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitInfoParser } from '../../../parser'; + +export class RoomUnitInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitInfoParser); + } + + public getParser(): RoomUnitInfoParser + { + return this.parser as RoomUnitInfoParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitNumberEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitNumberEvent.ts new file mode 100644 index 0000000..cd2f0e8 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitNumberEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitNumberParser } from '../../../parser'; + +export class RoomUnitNumberEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitNumberParser); + } + + public getParser(): RoomUnitNumberParser + { + return this.parser as RoomUnitNumberParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitRemoveEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitRemoveEvent.ts new file mode 100644 index 0000000..1c55487 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitRemoveEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitRemoveParser } from '../../../parser'; + +export class RoomUnitRemoveEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitRemoveParser); + } + + public getParser(): RoomUnitRemoveParser + { + return this.parser as RoomUnitRemoveParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/RoomUnitStatusEvent.ts b/packages/communication/src/messages/incoming/room/unit/RoomUnitStatusEvent.ts new file mode 100644 index 0000000..290b337 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/RoomUnitStatusEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitStatusParser } from '../../../parser'; + +export class RoomUnitStatusEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitStatusParser); + } + + public getParser(): RoomUnitStatusParser + { + return this.parser as RoomUnitStatusParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/chat/FloodControlEvent.ts b/packages/communication/src/messages/incoming/room/unit/chat/FloodControlEvent.ts new file mode 100644 index 0000000..2e739e0 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/chat/FloodControlEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FloodControlParser } from '../../../../parser'; + +export class FloodControlEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FloodControlParser); + } + + public getParser(): FloodControlParser + { + return this.parser as FloodControlParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/chat/RemainingMuteEvent.ts b/packages/communication/src/messages/incoming/room/unit/chat/RemainingMuteEvent.ts new file mode 100644 index 0000000..36b194d --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/chat/RemainingMuteEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RemainingMuteParser } from '../../../../parser'; + +export class RemainingMuteEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RemainingMuteParser); + } + + public getParser(): RemainingMuteParser + { + return this.parser as RemainingMuteParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatEvent.ts b/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatEvent.ts new file mode 100644 index 0000000..2f0a49c --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitChatParser } from '../../../../parser'; + +export class RoomUnitChatEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitChatParser); + } + + public getParser(): RoomUnitChatParser + { + return this.parser as RoomUnitChatParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatShoutEvent.ts b/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatShoutEvent.ts new file mode 100644 index 0000000..728de37 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatShoutEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitChatParser } from '../../../../parser'; + +export class RoomUnitChatShoutEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitChatParser); + } + + public getParser(): RoomUnitChatParser + { + return this.parser as RoomUnitChatParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent.ts b/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent.ts new file mode 100644 index 0000000..7706052 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitChatParser } from '../../../../parser'; + +export class RoomUnitChatWhisperEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitChatParser); + } + + public getParser(): RoomUnitChatParser + { + return this.parser as RoomUnitChatParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitTypingEvent.ts b/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitTypingEvent.ts new file mode 100644 index 0000000..c13c250 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/chat/RoomUnitTypingEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomUnitTypingParser } from '../../../../parser'; + +export class RoomUnitTypingEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitTypingParser); + } + + public getParser(): RoomUnitTypingParser + { + return this.parser as RoomUnitTypingParser; + } +} diff --git a/packages/communication/src/messages/incoming/room/unit/chat/index.ts b/packages/communication/src/messages/incoming/room/unit/chat/index.ts new file mode 100644 index 0000000..6ba41a2 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/chat/index.ts @@ -0,0 +1,6 @@ +export * from './FloodControlEvent'; +export * from './RemainingMuteEvent'; +export * from './RoomUnitChatEvent'; +export * from './RoomUnitChatShoutEvent'; +export * from './RoomUnitChatWhisperEvent'; +export * from './RoomUnitTypingEvent'; diff --git a/packages/communication/src/messages/incoming/room/unit/index.ts b/packages/communication/src/messages/incoming/room/unit/index.ts new file mode 100644 index 0000000..2592685 --- /dev/null +++ b/packages/communication/src/messages/incoming/room/unit/index.ts @@ -0,0 +1,12 @@ +export * from './chat'; +export * from './RoomUnitDanceEvent'; +export * from './RoomUnitEffectEvent'; +export * from './RoomUnitEvent'; +export * from './RoomUnitExpressionEvent'; +export * from './RoomUnitHandItemEvent'; +export * from './RoomUnitHandItemReceivedEvent'; +export * from './RoomUnitIdleEvent'; +export * from './RoomUnitInfoEvent'; +export * from './RoomUnitNumberEvent'; +export * from './RoomUnitRemoveEvent'; +export * from './RoomUnitStatusEvent'; diff --git a/packages/communication/src/messages/incoming/roomevents/WiredFurniActionEvent.ts b/packages/communication/src/messages/incoming/roomevents/WiredFurniActionEvent.ts new file mode 100644 index 0000000..4ee1c0b --- /dev/null +++ b/packages/communication/src/messages/incoming/roomevents/WiredFurniActionEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WiredFurniActionParser } from '../../parser'; + +export class WiredFurniActionEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredFurniActionParser); + } + + public getParser(): WiredFurniActionParser + { + return this.parser as WiredFurniActionParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomevents/WiredFurniConditionEvent.ts b/packages/communication/src/messages/incoming/roomevents/WiredFurniConditionEvent.ts new file mode 100644 index 0000000..096c447 --- /dev/null +++ b/packages/communication/src/messages/incoming/roomevents/WiredFurniConditionEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WiredFurniConditionParser } from '../../parser'; + +export class WiredFurniConditionEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredFurniConditionParser); + } + + public getParser(): WiredFurniConditionParser + { + return this.parser as WiredFurniConditionParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomevents/WiredFurniTriggerEvent.ts b/packages/communication/src/messages/incoming/roomevents/WiredFurniTriggerEvent.ts new file mode 100644 index 0000000..d6afb96 --- /dev/null +++ b/packages/communication/src/messages/incoming/roomevents/WiredFurniTriggerEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WiredFurniTriggerParser } from '../../parser'; + +export class WiredFurniTriggerEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredFurniTriggerParser); + } + + public getParser(): WiredFurniTriggerParser + { + return this.parser as WiredFurniTriggerParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomevents/WiredOpenEvent.ts b/packages/communication/src/messages/incoming/roomevents/WiredOpenEvent.ts new file mode 100644 index 0000000..3496953 --- /dev/null +++ b/packages/communication/src/messages/incoming/roomevents/WiredOpenEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WiredOpenParser } from '../../parser'; + +export class WiredOpenEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredOpenParser); + } + + public getParser(): WiredOpenParser + { + return this.parser as WiredOpenParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomevents/WiredRewardResultMessageEvent.ts b/packages/communication/src/messages/incoming/roomevents/WiredRewardResultMessageEvent.ts new file mode 100644 index 0000000..59252da --- /dev/null +++ b/packages/communication/src/messages/incoming/roomevents/WiredRewardResultMessageEvent.ts @@ -0,0 +1,19 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WiredRewardResultMessageParser } from '../../parser'; + +export class WiredRewardResultMessageEvent extends MessageEvent implements IMessageEvent +{ + public static PRODUCT_DONATED_CODE: number = 6; + public static BADGE_DONATED_CODE: number = 7; + + constructor(callBack: Function) + { + super(callBack, WiredRewardResultMessageParser); + } + + public getParser(): WiredRewardResultMessageParser + { + return this.parser as WiredRewardResultMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomevents/WiredSaveSuccessEvent.ts b/packages/communication/src/messages/incoming/roomevents/WiredSaveSuccessEvent.ts new file mode 100644 index 0000000..3b6250a --- /dev/null +++ b/packages/communication/src/messages/incoming/roomevents/WiredSaveSuccessEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WiredSaveSuccessParser } from '../../parser'; + +export class WiredSaveSuccessEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredSaveSuccessParser); + } + + public getParser(): WiredSaveSuccessParser + { + return this.parser as WiredSaveSuccessParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomevents/WiredValidationErrorEvent.ts b/packages/communication/src/messages/incoming/roomevents/WiredValidationErrorEvent.ts new file mode 100644 index 0000000..a29963a --- /dev/null +++ b/packages/communication/src/messages/incoming/roomevents/WiredValidationErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WiredValidationErrorParser } from '../../parser'; + +export class WiredValidationErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredValidationErrorParser); + } + + public getParser(): WiredValidationErrorParser + { + return this.parser as WiredValidationErrorParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomevents/index.ts b/packages/communication/src/messages/incoming/roomevents/index.ts new file mode 100644 index 0000000..0775d57 --- /dev/null +++ b/packages/communication/src/messages/incoming/roomevents/index.ts @@ -0,0 +1,7 @@ +export * from './WiredFurniActionEvent'; +export * from './WiredFurniConditionEvent'; +export * from './WiredFurniTriggerEvent'; +export * from './WiredOpenEvent'; +export * from './WiredRewardResultMessageEvent'; +export * from './WiredSaveSuccessEvent'; +export * from './WiredValidationErrorEvent'; diff --git a/packages/communication/src/messages/incoming/roomsettings/BannedUsersFromRoomEvent.ts b/packages/communication/src/messages/incoming/roomsettings/BannedUsersFromRoomEvent.ts new file mode 100644 index 0000000..8e95804 --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/BannedUsersFromRoomEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { BannedUsersFromRoomParser } from '../../parser'; + +export class BannedUsersFromRoomEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BannedUsersFromRoomParser); + } + + public getParser(): BannedUsersFromRoomParser + { + return this.parser as BannedUsersFromRoomParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/FlatControllerAddedEvent.ts b/packages/communication/src/messages/incoming/roomsettings/FlatControllerAddedEvent.ts new file mode 100644 index 0000000..4d1fe0b --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/FlatControllerAddedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FlatControllerAddedParser } from '../../parser'; + +export class FlatControllerAddedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FlatControllerAddedParser); + } + + public getParser(): FlatControllerAddedParser + { + return this.parser as FlatControllerAddedParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/FlatControllerRemovedEvent.ts b/packages/communication/src/messages/incoming/roomsettings/FlatControllerRemovedEvent.ts new file mode 100644 index 0000000..4f1bdbc --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/FlatControllerRemovedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FlatControllerRemovedParser } from '../../parser'; + +export class FlatControllerRemovedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FlatControllerRemovedParser); + } + + public getParser(): FlatControllerRemovedParser + { + return this.parser as FlatControllerRemovedParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/FlatControllersEvent.ts b/packages/communication/src/messages/incoming/roomsettings/FlatControllersEvent.ts new file mode 100644 index 0000000..98da732 --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/FlatControllersEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { FlatControllersParser } from '../../parser'; + +export class FlatControllersEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FlatControllersParser); + } + + public getParser(): FlatControllersParser + { + return this.parser as FlatControllersParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/MuteAllInRoomEvent.ts b/packages/communication/src/messages/incoming/roomsettings/MuteAllInRoomEvent.ts new file mode 100644 index 0000000..9eaccf9 --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/MuteAllInRoomEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { MuteAllInRoomParser } from '../../parser'; + +export class MuteAllInRoomEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MuteAllInRoomParser); + } + + public getParser(): MuteAllInRoomParser + { + return this.parser as MuteAllInRoomParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/NoSuchFlatEvent.ts b/packages/communication/src/messages/incoming/roomsettings/NoSuchFlatEvent.ts new file mode 100644 index 0000000..745ac4d --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/NoSuchFlatEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NoSuchFlatParser } from '../../parser'; + +export class NoSuchFlatEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NoSuchFlatParser); + } + + public getParser(): NoSuchFlatParser + { + return this.parser as NoSuchFlatParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/RoomSettingsDataEvent.ts b/packages/communication/src/messages/incoming/roomsettings/RoomSettingsDataEvent.ts new file mode 100644 index 0000000..69274ef --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/RoomSettingsDataEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomSettingsDataParser } from '../../parser'; + +export class RoomSettingsDataEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsDataParser); + } + + public getParser(): RoomSettingsDataParser + { + return this.parser as RoomSettingsDataParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/RoomSettingsErrorEvent.ts b/packages/communication/src/messages/incoming/roomsettings/RoomSettingsErrorEvent.ts new file mode 100644 index 0000000..d245ce5 --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/RoomSettingsErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomSettingsErrorParser } from '../../parser'; + +export class RoomSettingsErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsErrorParser); + } + + public getParser(): RoomSettingsErrorParser + { + return this.parser as RoomSettingsErrorParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/RoomSettingsSaveErrorEvent.ts b/packages/communication/src/messages/incoming/roomsettings/RoomSettingsSaveErrorEvent.ts new file mode 100644 index 0000000..459c672 --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/RoomSettingsSaveErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomSettingsSaveErrorParser } from '../../parser'; + +export class RoomSettingsSaveErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsSaveErrorParser); + } + + public getParser(): RoomSettingsSaveErrorParser + { + return this.parser as RoomSettingsSaveErrorParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/RoomSettingsSavedEvent.ts b/packages/communication/src/messages/incoming/roomsettings/RoomSettingsSavedEvent.ts new file mode 100644 index 0000000..842de1e --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/RoomSettingsSavedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RoomSettingsSavedParser } from '../../parser'; + +export class RoomSettingsSavedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsSavedParser); + } + + public getParser(): RoomSettingsSavedParser + { + return this.parser as RoomSettingsSavedParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/ShowEnforceRoomCategoryDialogEvent.ts b/packages/communication/src/messages/incoming/roomsettings/ShowEnforceRoomCategoryDialogEvent.ts new file mode 100644 index 0000000..c4fbb4f --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/ShowEnforceRoomCategoryDialogEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ShowEnforceRoomCategoryDialogParser } from '../../parser'; + +export class ShowEnforceRoomCategoryDialogEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ShowEnforceRoomCategoryDialogParser); + } + + public getParser(): ShowEnforceRoomCategoryDialogParser + { + return this.parser as ShowEnforceRoomCategoryDialogParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/UserUnbannedFromRoomEvent.ts b/packages/communication/src/messages/incoming/roomsettings/UserUnbannedFromRoomEvent.ts new file mode 100644 index 0000000..69be3f1 --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/UserUnbannedFromRoomEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserUnbannedFromRoomParser } from '../../parser'; + +export class UserUnbannedFromRoomEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserUnbannedFromRoomParser); + } + + public getParser(): UserUnbannedFromRoomParser + { + return this.parser as UserUnbannedFromRoomParser; + } +} diff --git a/packages/communication/src/messages/incoming/roomsettings/index.ts b/packages/communication/src/messages/incoming/roomsettings/index.ts new file mode 100644 index 0000000..63327aa --- /dev/null +++ b/packages/communication/src/messages/incoming/roomsettings/index.ts @@ -0,0 +1,12 @@ +export * from './BannedUsersFromRoomEvent'; +export * from './FlatControllerAddedEvent'; +export * from './FlatControllerRemovedEvent'; +export * from './FlatControllersEvent'; +export * from './MuteAllInRoomEvent'; +export * from './NoSuchFlatEvent'; +export * from './RoomSettingsDataEvent'; +export * from './RoomSettingsErrorEvent'; +export * from './RoomSettingsSavedEvent'; +export * from './RoomSettingsSaveErrorEvent'; +export * from './ShowEnforceRoomCategoryDialogEvent'; +export * from './UserUnbannedFromRoomEvent'; diff --git a/packages/communication/src/messages/incoming/security/AuthenticatedEvent.ts b/packages/communication/src/messages/incoming/security/AuthenticatedEvent.ts new file mode 100644 index 0000000..1924bf8 --- /dev/null +++ b/packages/communication/src/messages/incoming/security/AuthenticatedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AuthenticatedParser } from '../../parser'; + +export class AuthenticatedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AuthenticatedParser); + } + + public getParser(): AuthenticatedParser + { + return this.parser as AuthenticatedParser; + } +} diff --git a/packages/communication/src/messages/incoming/security/index.ts b/packages/communication/src/messages/incoming/security/index.ts new file mode 100644 index 0000000..01a887c --- /dev/null +++ b/packages/communication/src/messages/incoming/security/index.ts @@ -0,0 +1 @@ +export * from './AuthenticatedEvent'; diff --git a/packages/communication/src/messages/incoming/sound/JukeboxPlayListFullMessageEvent.ts b/packages/communication/src/messages/incoming/sound/JukeboxPlayListFullMessageEvent.ts new file mode 100644 index 0000000..7af71ef --- /dev/null +++ b/packages/communication/src/messages/incoming/sound/JukeboxPlayListFullMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { JukeboxPlayListFullMessageParser } from '../../parser'; + +export class JukeboxPlayListFullMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, JukeboxPlayListFullMessageParser); + } + + public getParser(): JukeboxPlayListFullMessageParser + { + return this.parser as JukeboxPlayListFullMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/sound/JukeboxSongDisksMessageEvent.ts b/packages/communication/src/messages/incoming/sound/JukeboxSongDisksMessageEvent.ts new file mode 100644 index 0000000..aff0703 --- /dev/null +++ b/packages/communication/src/messages/incoming/sound/JukeboxSongDisksMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { JukeboxSongDisksMessageParser } from '../../parser'; + +export class JukeboxSongDisksMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, JukeboxSongDisksMessageParser); + } + + public getParser(): JukeboxSongDisksMessageParser + { + return this.parser as JukeboxSongDisksMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/sound/NowPlayingMessageEvent.ts b/packages/communication/src/messages/incoming/sound/NowPlayingMessageEvent.ts new file mode 100644 index 0000000..4dd5a2d --- /dev/null +++ b/packages/communication/src/messages/incoming/sound/NowPlayingMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { NowPlayingMessageParser } from '../../parser'; + +export class NowPlayingMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NowPlayingMessageParser); + } + + public getParser(): NowPlayingMessageParser + { + return this.parser as NowPlayingMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/sound/OfficialSongIdMessageEvent.ts b/packages/communication/src/messages/incoming/sound/OfficialSongIdMessageEvent.ts new file mode 100644 index 0000000..d57bd3b --- /dev/null +++ b/packages/communication/src/messages/incoming/sound/OfficialSongIdMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { OfficialSongIdMessageParser } from '../../parser'; + +export class OfficialSongIdMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, OfficialSongIdMessageParser); + } + + public getParser(): OfficialSongIdMessageParser + { + return this.parser as OfficialSongIdMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/sound/PlayListMessageEvent.ts b/packages/communication/src/messages/incoming/sound/PlayListMessageEvent.ts new file mode 100644 index 0000000..762d006 --- /dev/null +++ b/packages/communication/src/messages/incoming/sound/PlayListMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PlayListMessageParser } from '../../parser'; + +export class PlayListMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PlayListMessageParser); + } + + public getParser(): PlayListMessageParser + { + return this.parser as PlayListMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/sound/PlayListSongAddedMessageEvent.ts b/packages/communication/src/messages/incoming/sound/PlayListSongAddedMessageEvent.ts new file mode 100644 index 0000000..5d5f516 --- /dev/null +++ b/packages/communication/src/messages/incoming/sound/PlayListSongAddedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PlayListSongAddedMessageParser } from '../../parser'; + +export class PlayListSongAddedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PlayListSongAddedMessageParser); + } + + public getParser(): PlayListSongAddedMessageParser + { + return this.parser as PlayListSongAddedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/sound/TraxSongInfoMessageEvent.ts b/packages/communication/src/messages/incoming/sound/TraxSongInfoMessageEvent.ts new file mode 100644 index 0000000..7bf5d17 --- /dev/null +++ b/packages/communication/src/messages/incoming/sound/TraxSongInfoMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TraxSongInfoMessageParser } from '../../parser'; + +export class TraxSongInfoMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TraxSongInfoMessageParser); + } + + public getParser(): TraxSongInfoMessageParser + { + return this.parser as TraxSongInfoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/sound/UserSongDisksInventoryMessageEvent.ts b/packages/communication/src/messages/incoming/sound/UserSongDisksInventoryMessageEvent.ts new file mode 100644 index 0000000..8e09055 --- /dev/null +++ b/packages/communication/src/messages/incoming/sound/UserSongDisksInventoryMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserSongDisksInventoryMessageParser } from '../../parser'; + +export class UserSongDisksInventoryMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserSongDisksInventoryMessageParser); + } + + public getParser(): UserSongDisksInventoryMessageParser + { + return this.parser as UserSongDisksInventoryMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/sound/index.ts b/packages/communication/src/messages/incoming/sound/index.ts new file mode 100644 index 0000000..24744f7 --- /dev/null +++ b/packages/communication/src/messages/incoming/sound/index.ts @@ -0,0 +1,8 @@ +export * from './JukeboxPlayListFullMessageEvent'; +export * from './JukeboxSongDisksMessageEvent'; +export * from './NowPlayingMessageEvent'; +export * from './OfficialSongIdMessageEvent'; +export * from './PlayListMessageEvent'; +export * from './PlayListSongAddedMessageEvent'; +export * from './TraxSongInfoMessageEvent'; +export * from './UserSongDisksInventoryMessageEvent'; diff --git a/packages/communication/src/messages/incoming/talent/TalentLevelUpEvent.ts b/packages/communication/src/messages/incoming/talent/TalentLevelUpEvent.ts new file mode 100644 index 0000000..07684b1 --- /dev/null +++ b/packages/communication/src/messages/incoming/talent/TalentLevelUpEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TalentLevelUpMessageParser } from '../../parser'; + +export class TalentLevelUpEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TalentLevelUpMessageParser); + } + + public getParser(): TalentLevelUpMessageParser + { + return this.parser as TalentLevelUpMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/talent/TalentTrackLevelMessageEvent.ts b/packages/communication/src/messages/incoming/talent/TalentTrackLevelMessageEvent.ts new file mode 100644 index 0000000..dbe59b4 --- /dev/null +++ b/packages/communication/src/messages/incoming/talent/TalentTrackLevelMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TalentTrackLevelMessageParser } from '../../parser'; + +export class TalentTrackLevelMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TalentTrackLevelMessageParser); + } + + public getParser(): TalentTrackLevelMessageParser + { + return this.parser as TalentTrackLevelMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/talent/TalentTrackMessageEvent.ts b/packages/communication/src/messages/incoming/talent/TalentTrackMessageEvent.ts new file mode 100644 index 0000000..05192bc --- /dev/null +++ b/packages/communication/src/messages/incoming/talent/TalentTrackMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { TalentTrackParser } from '../../parser'; + +export class TalentTrackMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TalentTrackParser); + } + + public getParser(): TalentTrackParser + { + return this.parser as TalentTrackParser; + } +} diff --git a/packages/communication/src/messages/incoming/talent/index.ts b/packages/communication/src/messages/incoming/talent/index.ts new file mode 100644 index 0000000..a05161d --- /dev/null +++ b/packages/communication/src/messages/incoming/talent/index.ts @@ -0,0 +1,3 @@ +export * from './TalentLevelUpEvent'; +export * from './TalentTrackLevelMessageEvent'; +export * from './TalentTrackMessageEvent'; diff --git a/packages/communication/src/messages/incoming/user/AccountSafetyLockStatusChangeMessageEvent.ts b/packages/communication/src/messages/incoming/user/AccountSafetyLockStatusChangeMessageEvent.ts new file mode 100644 index 0000000..e62be5d --- /dev/null +++ b/packages/communication/src/messages/incoming/user/AccountSafetyLockStatusChangeMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { AccountSafetyLockStatusChangeParser } from '../../parser/user/AccountSafetyLockStatusChangeParser'; + +export class AccountSafetyLockStatusChangeMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AccountSafetyLockStatusChangeParser); + } + + public getParser(): AccountSafetyLockStatusChangeParser + { + return this.parser as AccountSafetyLockStatusChangeParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/ApproveNameMessageEvent.ts b/packages/communication/src/messages/incoming/user/ApproveNameMessageEvent.ts new file mode 100644 index 0000000..17b4339 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/ApproveNameMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ApproveNameResultParser } from '../../parser'; + +export class ApproveNameMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ApproveNameResultParser); + } + + public getParser(): ApproveNameResultParser + { + return this.parser as ApproveNameResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/ChangeEmailResultEvent.ts b/packages/communication/src/messages/incoming/user/ChangeEmailResultEvent.ts new file mode 100644 index 0000000..1e5f589 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/ChangeEmailResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ChangeEmailResultParser } from '../../parser'; + +export class ChangeEmailResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ChangeEmailResultParser); + } + + public getParser(): ChangeEmailResultParser + { + return this.parser as ChangeEmailResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/EmailStatusResultEvent.ts b/packages/communication/src/messages/incoming/user/EmailStatusResultEvent.ts new file mode 100644 index 0000000..0b12f24 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/EmailStatusResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { EmailStatusParser } from '../../parser'; + +export class EmailStatusResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, EmailStatusParser); + } + + public getParser(): EmailStatusParser + { + return this.parser as EmailStatusParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/ExtendedProfileChangedMessageEvent.ts b/packages/communication/src/messages/incoming/user/ExtendedProfileChangedMessageEvent.ts new file mode 100644 index 0000000..cf0dc5f --- /dev/null +++ b/packages/communication/src/messages/incoming/user/ExtendedProfileChangedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ExtendedProfileChangedMessageParser } from '../../parser'; + +export class ExtendedProfileChangedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ExtendedProfileChangedMessageParser); + } + + public getParser(): ExtendedProfileChangedMessageParser + { + return this.parser as ExtendedProfileChangedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/GroupDetailsChangedMessageEvent.ts b/packages/communication/src/messages/incoming/user/GroupDetailsChangedMessageEvent.ts new file mode 100644 index 0000000..461c9c3 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/GroupDetailsChangedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GroupDetailsChangedMessageParser } from '../../parser'; + +export class GroupDetailsChangedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupDetailsChangedMessageParser); + } + + public getParser(): GroupDetailsChangedMessageParser + { + return this.parser as GroupDetailsChangedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/GroupMembershipRequestedMessageEvent.ts b/packages/communication/src/messages/incoming/user/GroupMembershipRequestedMessageEvent.ts new file mode 100644 index 0000000..649648a --- /dev/null +++ b/packages/communication/src/messages/incoming/user/GroupMembershipRequestedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GroupMembershipRequestedMessageParser } from '../../parser'; + +export class GroupMembershipRequestedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupMembershipRequestedMessageParser); + } + + public getParser(): GroupMembershipRequestedMessageParser + { + return this.parser as GroupMembershipRequestedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/GuildEditFailedMessageEvent.ts b/packages/communication/src/messages/incoming/user/GuildEditFailedMessageEvent.ts new file mode 100644 index 0000000..bdefae8 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/GuildEditFailedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuildEditFailedMessageParser } from '../../parser'; + +export class GuildEditFailedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuildEditFailedMessageParser); + } + + public getParser(): GuildEditFailedMessageParser + { + return this.parser as GuildEditFailedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/GuildMemberMgmtFailedMessageEvent.ts b/packages/communication/src/messages/incoming/user/GuildMemberMgmtFailedMessageEvent.ts new file mode 100644 index 0000000..d4f67a1 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/GuildMemberMgmtFailedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuildMemberMgmtFailedMessageParser } from '../../parser'; + +export class GuildMemberMgmtFailedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuildMemberMgmtFailedMessageParser); + } + + public getParser(): GuildMemberMgmtFailedMessageParser + { + return this.parser as GuildMemberMgmtFailedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/GuildMembershipsMessageEvent.ts b/packages/communication/src/messages/incoming/user/GuildMembershipsMessageEvent.ts new file mode 100644 index 0000000..7a9d4be --- /dev/null +++ b/packages/communication/src/messages/incoming/user/GuildMembershipsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { GuildMembershipsMessageParser } from '../../parser'; + +export class GuildMembershipsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GuildMembershipsMessageParser); + } + + public getParser(): GuildMembershipsMessageParser + { + return this.parser as GuildMembershipsMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/HabboGroupBadgesMessageEvent.ts b/packages/communication/src/messages/incoming/user/HabboGroupBadgesMessageEvent.ts new file mode 100644 index 0000000..4138952 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/HabboGroupBadgesMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HabboGroupBadgesMessageParser } from '../../parser'; + +export class HabboGroupBadgesMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HabboGroupBadgesMessageParser); + } + + public getParser(): HabboGroupBadgesMessageParser + { + return this.parser as HabboGroupBadgesMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/HabboGroupJoinFailedMessageEvent.ts b/packages/communication/src/messages/incoming/user/HabboGroupJoinFailedMessageEvent.ts new file mode 100644 index 0000000..f2e0846 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/HabboGroupJoinFailedMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { HabboGroupJoinFailedMessageParser } from '../../parser'; + +export class HabboGroupJoinFailedMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HabboGroupJoinFailedMessageParser); + } + + public getParser(): HabboGroupJoinFailedMessageParser + { + return this.parser as HabboGroupJoinFailedMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/IgnoreResultEvent.ts b/packages/communication/src/messages/incoming/user/IgnoreResultEvent.ts new file mode 100644 index 0000000..521cc3d --- /dev/null +++ b/packages/communication/src/messages/incoming/user/IgnoreResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { IgnoreResultParser } from '../../parser'; + +export class IgnoreResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IgnoreResultParser); + } + + public getParser(): IgnoreResultParser + { + return this.parser as IgnoreResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/IgnoredUsersEvent.ts b/packages/communication/src/messages/incoming/user/IgnoredUsersEvent.ts new file mode 100644 index 0000000..9dd6f6a --- /dev/null +++ b/packages/communication/src/messages/incoming/user/IgnoredUsersEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { IgnoredUsersParser } from '../../parser'; + +export class IgnoredUsersEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IgnoredUsersParser); + } + + public getParser(): IgnoredUsersParser + { + return this.parser as IgnoredUsersParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/InClientLinkEvent.ts b/packages/communication/src/messages/incoming/user/InClientLinkEvent.ts new file mode 100644 index 0000000..4e8798a --- /dev/null +++ b/packages/communication/src/messages/incoming/user/InClientLinkEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { InClientLinkParser } from '../../parser'; + +export class InClientLinkEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, InClientLinkParser); + } + + public getParser(): InClientLinkParser + { + return this.parser as InClientLinkParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/MemberData.ts b/packages/communication/src/messages/incoming/user/MemberData.ts new file mode 100644 index 0000000..ac60c0e --- /dev/null +++ b/packages/communication/src/messages/incoming/user/MemberData.ts @@ -0,0 +1,70 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class MemberData +{ + private static readonly TYPE_OWNER: number = 0; + private static readonly TYPE_ADMIN: number = 1; + private static readonly TYPE_PENDING: number = 2; + private static readonly TYPE_MEMBER: number = 3; + private static readonly TYPE_BLOCKED: number = 4; + + private _type: number; + private _userId: number; + private _userName: string; + private _figure: string; + private _memberSince: string; + + constructor(wrapper: IMessageDataWrapper) + { + this._type = wrapper.readInt(); + this._userId = wrapper.readInt(); + this._userName = wrapper.readString(); + this._figure = wrapper.readString(); + this._memberSince = wrapper.readString(); + } + + public get userId(): number + { + return this._userId; + } + + public get userName(): string + { + return this._userName; + } + + public get admin(): boolean + { + return this._type == MemberData.TYPE_ADMIN; + } + + public get owner(): boolean + { + return this._type == MemberData.TYPE_OWNER; + } + + public get pending(): boolean + { + return this._type == MemberData.TYPE_PENDING; + } + + public get member(): boolean + { + return this._type != MemberData.TYPE_MEMBER; + } + + public get blocked(): boolean + { + return this._type == MemberData.TYPE_BLOCKED; + } + + public get figure(): string + { + return this._figure; + } + + public get memberSince(): string + { + return this._memberSince; + } +} diff --git a/packages/communication/src/messages/incoming/user/PetRespectNoficationEvent.ts b/packages/communication/src/messages/incoming/user/PetRespectNoficationEvent.ts new file mode 100644 index 0000000..5e44b95 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/PetRespectNoficationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetRespectNotificationParser } from '../../parser'; + +export class PetRespectNoficationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetRespectNotificationParser); + } + + public getParser(): PetRespectNotificationParser + { + return this.parser as PetRespectNotificationParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/PetSupplementedNotificationEvent.ts b/packages/communication/src/messages/incoming/user/PetSupplementedNotificationEvent.ts new file mode 100644 index 0000000..9e9ff72 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/PetSupplementedNotificationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { PetSupplementedNotificationParser } from '../../parser'; + +export class PetSupplementedNotificationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetSupplementedNotificationParser); + } + + public getParser(): PetSupplementedNotificationParser + { + return this.parser as PetSupplementedNotificationParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/RespectReceivedEvent.ts b/packages/communication/src/messages/incoming/user/RespectReceivedEvent.ts new file mode 100644 index 0000000..3326ae6 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/RespectReceivedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RespectReceivedParser } from '../../parser'; + +export class RespectReceivedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RespectReceivedParser); + } + + public getParser(): RespectReceivedParser + { + return this.parser as RespectReceivedParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/ScrSendKickbackInfoMessageEvent.ts b/packages/communication/src/messages/incoming/user/ScrSendKickbackInfoMessageEvent.ts new file mode 100644 index 0000000..faabaf5 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/ScrSendKickbackInfoMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { ScrSendKickbackInfoMessageParser } from '../../parser'; + +export class ScrSendKickbackInfoMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ScrSendKickbackInfoMessageParser); + } + + public getParser(): ScrSendKickbackInfoMessageParser + { + return this.parser as ScrSendKickbackInfoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/WelcomeGiftChangeEmailResultEvent.ts b/packages/communication/src/messages/incoming/user/WelcomeGiftChangeEmailResultEvent.ts new file mode 100644 index 0000000..a2a56ff --- /dev/null +++ b/packages/communication/src/messages/incoming/user/WelcomeGiftChangeEmailResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { WelcomeGiftChangeEmailResultParser } from '../../parser'; + +export class WelcomeGiftChangeEmailResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WelcomeGiftChangeEmailResultParser); + } + + public getParser(): WelcomeGiftChangeEmailResultParser + { + return this.parser as WelcomeGiftChangeEmailResultParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/access/UserPermissionsEvent.ts b/packages/communication/src/messages/incoming/user/access/UserPermissionsEvent.ts new file mode 100644 index 0000000..e5943c4 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/access/UserPermissionsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserPermissionsParser } from '../../../parser'; + +export class UserPermissionsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserPermissionsParser); + } + + public getParser(): UserPermissionsParser + { + return this.parser as UserPermissionsParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/access/index.ts b/packages/communication/src/messages/incoming/user/access/index.ts new file mode 100644 index 0000000..51901c3 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/access/index.ts @@ -0,0 +1 @@ +export * from './UserPermissionsEvent'; diff --git a/packages/communication/src/messages/incoming/user/data/RelationshipStatusInfoEvent.ts b/packages/communication/src/messages/incoming/user/data/RelationshipStatusInfoEvent.ts new file mode 100644 index 0000000..c9caba4 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/data/RelationshipStatusInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { RelationshipStatusInfoMessageParser } from '../../../parser'; + +export class RelationshipStatusInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RelationshipStatusInfoMessageParser); + } + + public getParser(): RelationshipStatusInfoMessageParser + { + return this.parser as RelationshipStatusInfoMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/data/UserCurrentBadgesEvent.ts b/packages/communication/src/messages/incoming/user/data/UserCurrentBadgesEvent.ts new file mode 100644 index 0000000..600b808 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/data/UserCurrentBadgesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserCurrentBadgesParser } from '../../../parser'; + +export class UserCurrentBadgesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserCurrentBadgesParser); + } + + public getParser(): UserCurrentBadgesParser + { + return this.parser as UserCurrentBadgesParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/data/UserInfoEvent.ts b/packages/communication/src/messages/incoming/user/data/UserInfoEvent.ts new file mode 100644 index 0000000..3231671 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/data/UserInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserInfoParser } from '../../../parser'; + +export class UserInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserInfoParser); + } + + public getParser(): UserInfoParser + { + return this.parser as UserInfoParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/data/UserNameChangeMessageEvent.ts b/packages/communication/src/messages/incoming/user/data/UserNameChangeMessageEvent.ts new file mode 100644 index 0000000..f0cd532 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/data/UserNameChangeMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserNameChangeMessageParser } from '../../../parser'; + +export class UserNameChangeMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserNameChangeMessageParser); + } + + public getParser(): UserNameChangeMessageParser + { + return this.parser as UserNameChangeMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/data/UserProfileEvent.ts b/packages/communication/src/messages/incoming/user/data/UserProfileEvent.ts new file mode 100644 index 0000000..cc05661 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/data/UserProfileEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserProfileParser } from '../../../parser'; + +export class UserProfileEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserProfileParser); + } + + public getParser(): UserProfileParser + { + return this.parser as UserProfileParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/data/UserSettingsEvent.ts b/packages/communication/src/messages/incoming/user/data/UserSettingsEvent.ts new file mode 100644 index 0000000..e95508d --- /dev/null +++ b/packages/communication/src/messages/incoming/user/data/UserSettingsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserSettingsParser } from '../../../parser'; + +export class UserSettingsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserSettingsParser); + } + + public getParser(): UserSettingsParser + { + return this.parser as UserSettingsParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/data/UserTagsMessageEvent.ts b/packages/communication/src/messages/incoming/user/data/UserTagsMessageEvent.ts new file mode 100644 index 0000000..a556251 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/data/UserTagsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserTagsParser } from '../../../parser'; + +export class UserTagsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserTagsParser); + } + + public getParser(): UserTagsParser + { + return this.parser as UserTagsParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/data/index.ts b/packages/communication/src/messages/incoming/user/data/index.ts new file mode 100644 index 0000000..5994aa9 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/data/index.ts @@ -0,0 +1,7 @@ +export * from './RelationshipStatusInfoEvent'; +export * from './UserCurrentBadgesEvent'; +export * from './UserInfoEvent'; +export * from './UserNameChangeMessageEvent'; +export * from './UserProfileEvent'; +export * from './UserSettingsEvent'; +export * from './UserTagsMessageEvent'; diff --git a/packages/communication/src/messages/incoming/user/index.ts b/packages/communication/src/messages/incoming/user/index.ts new file mode 100644 index 0000000..f6f8642 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/index.ts @@ -0,0 +1,27 @@ +export * from './access'; +export * from './AccountSafetyLockStatusChangeMessageEvent'; +export * from './ApproveNameMessageEvent'; +export * from './ChangeEmailResultEvent'; +export * from './data'; +export * from './EmailStatusResultEvent'; +export * from './ExtendedProfileChangedMessageEvent'; +export * from './GroupDetailsChangedMessageEvent'; +export * from './GroupMembershipRequestedMessageEvent'; +export * from './GuildEditFailedMessageEvent'; +export * from './GuildMemberMgmtFailedMessageEvent'; +export * from './GuildMembershipsMessageEvent'; +export * from './HabboGroupBadgesMessageEvent'; +export * from './HabboGroupJoinFailedMessageEvent'; +export * from './IgnoredUsersEvent'; +export * from './IgnoreResultEvent'; +export * from './InClientLinkEvent'; +export * from './inventory'; +export * from './inventory/currency'; +export * from './inventory/subscription'; +export * from './MemberData'; +export * from './PetRespectNoficationEvent'; +export * from './PetSupplementedNotificationEvent'; +export * from './RespectReceivedEvent'; +export * from './ScrSendKickbackInfoMessageEvent'; +export * from './wardrobe'; +export * from './WelcomeGiftChangeEmailResultEvent'; diff --git a/packages/communication/src/messages/incoming/user/inventory/currency/UserCreditsEvent.ts b/packages/communication/src/messages/incoming/user/inventory/currency/UserCreditsEvent.ts new file mode 100644 index 0000000..4b3aa0d --- /dev/null +++ b/packages/communication/src/messages/incoming/user/inventory/currency/UserCreditsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserCreditsParser } from '../../../../parser'; + +export class UserCreditsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserCreditsParser); + } + + public getParser(): UserCreditsParser + { + return this.parser as UserCreditsParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/inventory/currency/UserCurrencyEvent.ts b/packages/communication/src/messages/incoming/user/inventory/currency/UserCurrencyEvent.ts new file mode 100644 index 0000000..402cbe6 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/inventory/currency/UserCurrencyEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserCurrencyParser } from '../../../../parser'; + +export class UserCurrencyEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserCurrencyParser); + } + + public getParser(): UserCurrencyParser + { + return this.parser as UserCurrencyParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/inventory/currency/index.ts b/packages/communication/src/messages/incoming/user/inventory/currency/index.ts new file mode 100644 index 0000000..f178ba7 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/inventory/currency/index.ts @@ -0,0 +1,2 @@ +export * from './UserCreditsEvent'; +export * from './UserCurrencyEvent'; diff --git a/packages/communication/src/messages/incoming/user/inventory/index.ts b/packages/communication/src/messages/incoming/user/inventory/index.ts new file mode 100644 index 0000000..e25bf08 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/inventory/index.ts @@ -0,0 +1,2 @@ +export * from './currency'; +export * from './subscription'; diff --git a/packages/communication/src/messages/incoming/user/inventory/subscription/UserSubscriptionEvent.ts b/packages/communication/src/messages/incoming/user/inventory/subscription/UserSubscriptionEvent.ts new file mode 100644 index 0000000..ae780cc --- /dev/null +++ b/packages/communication/src/messages/incoming/user/inventory/subscription/UserSubscriptionEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserSubscriptionParser } from '../../../../parser'; + +export class UserSubscriptionEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserSubscriptionParser); + } + + public getParser(): UserSubscriptionParser + { + return this.parser as UserSubscriptionParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/inventory/subscription/index.ts b/packages/communication/src/messages/incoming/user/inventory/subscription/index.ts new file mode 100644 index 0000000..3d8e4a1 --- /dev/null +++ b/packages/communication/src/messages/incoming/user/inventory/subscription/index.ts @@ -0,0 +1 @@ +export * from './UserSubscriptionEvent'; diff --git a/packages/communication/src/messages/incoming/user/wardrobe/UserWardrobePageEvent.ts b/packages/communication/src/messages/incoming/user/wardrobe/UserWardrobePageEvent.ts new file mode 100644 index 0000000..41b371b --- /dev/null +++ b/packages/communication/src/messages/incoming/user/wardrobe/UserWardrobePageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserWardrobePageParser } from '../../../parser'; + +export class UserWardrobePageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserWardrobePageParser); + } + + public getParser(): UserWardrobePageParser + { + return this.parser as UserWardrobePageParser; + } +} diff --git a/packages/communication/src/messages/incoming/user/wardrobe/index.ts b/packages/communication/src/messages/incoming/user/wardrobe/index.ts new file mode 100644 index 0000000..179e41c --- /dev/null +++ b/packages/communication/src/messages/incoming/user/wardrobe/index.ts @@ -0,0 +1 @@ +export * from './UserWardrobePageEvent'; diff --git a/packages/communication/src/messages/incoming/userclassification/UserClassificationMessageEvent.ts b/packages/communication/src/messages/incoming/userclassification/UserClassificationMessageEvent.ts new file mode 100644 index 0000000..41bc6db --- /dev/null +++ b/packages/communication/src/messages/incoming/userclassification/UserClassificationMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '@nitrots/api'; +import { MessageEvent } from '@nitrots/events'; +import { UserClassificationMessageParser } from '../../parser'; + +export class UserClassificationMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserClassificationMessageParser); + } + + public getParser(): UserClassificationMessageParser + { + return this.parser as UserClassificationMessageParser; + } +} diff --git a/packages/communication/src/messages/incoming/userclassification/index.ts b/packages/communication/src/messages/incoming/userclassification/index.ts new file mode 100644 index 0000000..f56a235 --- /dev/null +++ b/packages/communication/src/messages/incoming/userclassification/index.ts @@ -0,0 +1 @@ +export * from './UserClassificationMessageEvent'; diff --git a/packages/communication/src/messages/index.ts b/packages/communication/src/messages/index.ts new file mode 100644 index 0000000..7b88840 --- /dev/null +++ b/packages/communication/src/messages/index.ts @@ -0,0 +1,4 @@ +export * from './MessageClassManager'; +export * from './incoming'; +export * from './outgoing'; +export * from './parser'; diff --git a/packages/communication/src/messages/outgoing/OutgoingHeader.ts b/packages/communication/src/messages/outgoing/OutgoingHeader.ts new file mode 100644 index 0000000..4917a51 --- /dev/null +++ b/packages/communication/src/messages/outgoing/OutgoingHeader.ts @@ -0,0 +1,471 @@ +export class OutgoingHeader +{ + public static ACHIEVEMENT_LIST = 219; + public static AUTHENTICATION = -1; + public static BOT_CONFIGURATION = 1986; + public static BOT_PICKUP = 3323; + public static BOT_PLACE = 1592; + public static BOT_SKILL_SAVE = 2624; + public static GET_CLUB_OFFERS = 3285; + public static GET_CLUB_GIFT_INFO = 487; + public static GET_CATALOG_INDEX = 1195; + public static GET_CATALOG_PAGE = 412; + public static CATALOG_PURCHASE = 3492; + public static CATALOG_PURCHASE_GIFT = 1411; + public static GET_PRODUCT_OFFER = 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 GET_CURRENT_TIMING_CODE = 2912; + public static DESKTOP_NEWS = 1827; + public static DESKTOP_VIEW = 105; + public static GET_BUNDLE_DISCOUNT_RULESET = 223; + public static EVENT_TRACKER = 3457; + public static FIND_NEW_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_POSTIT_SAVE_STICKY_POLE = 3283; + 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 ACCEPTGAMEINVITE = 3802; + public static GAMEUNLOADEDMESSAGE = 3207; + public static GETGAMEACHIEVEMENTSMESSAGE = 2399; + public static GETGAMESTATUSMESSAGE = 3171; + public static GETUSERGAMEACHIEVEMENTSMESSAGE = 389; + public static JOINQUEUEMESSAGE = 1458; + public static LEAVEQUEUEMESSAGE = 2384; + public static RESETRESOLUTIONACHIEVEMENTMESSAGE = 3144; + public static GETWEEKLYGAMEREWARDWINNERS = 1054; + public static GAME2GETACCOUNTGAMESTATUSMESSAGE = 11; + public static GAME2CHECKGAMEDIRECTORYSTATUSMESSAGE = 3259; + public static GAME2EXITGAMEMESSAGE = 1445; + public static GAME2GAMECHATMESSAGE = 2502; + public static GAME2LOADSTAGEREADYMESSAGE = 2415; + public static GAME2PLAYAGAINMESSAGE = 3196; + public static GAME2REQUESTFULLSTATUSUPDATEMESSAGE = 1598; + public static GAME2GETWEEKLYFRIENDSLEADERBOARD = 1232; + public static GAME2GETWEEKLYLEADERBOARD = 2565; + public static GET_GIFT_WRAPPING_CONFIG = 418; + public static GROUP_ADMIN_ADD = 2894; + public static GROUP_ADMIN_REMOVE = 722; + public static GROUP_CREATE_OPTIONS = 798; + public static GROUP_FAVORITE = 3549; + public static GET_FORUM_STATS = 3149; + public static GET_FORUM_THREADS = 873; + public static GET_FORUMS_LIST = 436; + public static GET_FORUM_MESSAGES = 232; + public static GET_FORUM_THREAD = 3900; + public static GET_UNREAD_FORUMS_COUNT = 2908; + public static FORUM_MODERATE_MESSAGE = 286; + public static FORUM_MODERATE_THREAD = 1397; + public static FORUM_POST_MESSAGE = 3529; + public static UPDATE_FORUM_READ_MARKER = 1855; + public static UPDATE_FORUM_SETTINGS = 2214; + public static FORUM_UPDATE_THREAD = 3045; + 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 GROUP_BADGES = 21; + public static GROUP_UNBLOCK_MEMBER = 2864; + public static GET_BADGE_POINTS_LIMITS = 1371; + public static REQUESTABADGE = 3077; + public static GETISBADGEREQUESTFULFILLED = 1364; + 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 SET_OBJECT_DATA = 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 ACCEPT_FRIEND = 137; + public static MESSENGER_CHAT = 3567; + public static DECLINE_FRIEND = 2890; + public static FOLLOW_FRIEND = 3997; + public static MESSENGER_FRIENDS = 1523; + public static MESSENGER_INIT = 2781; + public static MESSENGER_RELATIONSHIPS = 2138; + public static SET_RELATIONSHIP_STATUS = 3768; + public static REMOVE_FRIEND = 1689; + public static REQUEST_FRIEND = 3157; + public static GET_FRIEND_REQUESTS = 2448; + public static SEND_ROOM_INVITE = 1276; + public static HABBO_SEARCH = 1210; + public static FRIEND_LIST_UPDATE = 1419; + public static MOD_TOOL_USER_INFO = 3295; + public static GET_USER_FLAT_CATS = 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 GET_USER_EVENT_CATS = 1782; + public static NAVIGATOR_SETTINGS_SAVE = 3159; + public static NAVIGATOR_CATEGORY_LIST_MODE = 1202; + public static NAVIGATOR_DELETE_SAVED_SEARCH = 1954; + 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 PET_OPEN_PACKAGE = 3698; + public static PET_SELECTED = 549; + public static PETS_BREED = 1638; + public static PET_CANCEL_BREEDING = 2713; + public static PET_CONFIRM_BREEDING = 3382; + public static GET_PET_TRAINING_PANEL = 2161; + public static RECYCLER_PRIZES = 398; + public static RECYCLER_STATUS = 1342; + public static RECYCLER_ITEMS = 2771; + public static RELEASE_VERSION = 4000; + public static CALL_FOR_HELP = 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 CAN_CREATE_ROOM = 2128; + public static CANCEL_ROOM_EVENT = 2725; + public static EDIT_ROOM_EVENT = 3991; + public static COMPETITION_ROOM_SEARCH = 433; + public static FORWARD_TO_RANDOM_PROMOTED_ROOM = 10; + public static FORWARD_TO_SOME_ROOM = 1703; + public static GET_CATEGORIES_WITH_USER_COUNT = 3782; + public static GET_GUEST_ROOM = 2230; + public static GET_OFFICIAL_ROOMS = 1229; + public static GET_POPULAR_ROOM_TAGS = 826; + public static GUILD_BASE_SEARCH = 2930; + public static MY_FAVOURITE_ROOMS_SEARCH = 2578; + public static MY_FREQUENT_ROOM_HISTORY_SEARCH = 1002; + public static MY_FRIENDS_ROOM_SEARCH = 2266; + public static MY_GUILD_BASES_SEARCH = 39; + public static MY_RECOMMENDED_ROOMS = 2537; + public static MY_ROOM_HISTORY_SEARCH = 2264; + public static MY_ROOM_RIGHTS_SEARCH = 272; + public static MY_ROOMS_SEARCH = 2277; + public static POPULAR_ROOMS_SEARCH = 2758; + public static ROOM_AD_EVENT_TAB_CLICKED = 2412; + public static ROOM_AD_EVENT_TAB_VIEWED = 2668; + public static ROOM_AD_SEARCH = 2809; + public static ROOM_TEXT_SEARCH = 3943; + public static ROOMS_WHERE_MY_FRIENDS_ARE = 1786; + public static ROOMS_WITH_HIGHEST_SCORE_SEARCH = 2939; + public static SET_ROOM_SESSION_TAGS = 3305; + public static UPDATE_ROOM_THUMBNAIL = 2468; + public static ROOM_KICK = 1320; + public static ROOM_LIKE = 3582; + public static ROOM_MODEL = 2300; + public static GET_OCCUPIED_TILES = 1687; + public static GET_ROOM_ENTRY_TILE = 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_SETTINGS_UPDATE_ROOM_CATEGORY_AND_TRADE = 1265; + public static ROOM_STAFF_PICK = 1918; + public static ROOM_FILTER_WORDS = 1911; + public static ROOM_FILTER_WORDS_MODIFY = 3001; + public static MYSTERYBOXWAITINGCANCELEDMESSAGE = 2012; + public static MYSTERYBOX_OPEN_TROPHY = 3074; + 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 REQUESTFURNIINVENTORYWHENNOTINROOM = 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_PETS = 3095; + public static USER_PROFILE = 3265; + public static USER_PROFILE_BY_NAME = 2249; + public static USER_RESPECT = 2694; + public static GET_SOUND_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 GET_WARDROBE = 2742; + public static SAVE_WARDROBE_OUTFIT = 800; + public static USER_TAGS = 17; + public static PEER_USERS_CLASSIFICATION = 1160; + public static USER_CLASSIFICATION = 2285; + public static VISIT_USER = 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 SET_ITEM_DATA = 3666; + public static CATALOG_REDEEM_VOUCHER = 339; + public static ROOM_TONER_APPLY = 2880; + public static FRIEND_FURNI_CONFIRM_LOCK = 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 MODTOOL_PREFERENCES = 31; + public static CLOSE_ISSUE_DEFAULT_ACTION = 2717; + public static CLOSE_ISSUES = 2067; + public static DEFAULT_SANCTION = 1681; + public static GET_CFH_CHATLOG = 211; + public static MODTOOL_SANCTION = 1392; + public static PICK_ISSUES = 15; + public static RELEASE_ISSUES = 1572; + public static CONVERT_GLOBAL_ROOM_ID = 314; + public static REQUEST_SELL_ITEM = 848; + public static REQUEST_MARKETPLACE_ITEM_STATS = 3288; + public static MARKETPLACE_SELL_ITEM = 3447; + public static MARKETPLACE_REQUEST_OWN_ITEMS = 2105; + public static MARKETPLACE_TAKE_BACK_ITEM = 434; + public static MARKETPLACE_REDEEM_CREDITS = 2650; + public static MARKETPLACE_REQUEST_OFFERS = 2407; + public static MARKETPLACE_BUY_OFFER = 1603; + public static MARKETPLACE_BUY_TOKENS = 1866; + public static CATALOG_REQUESET_PET_BREEDS = 1756; + public static APPROVE_NAME = 2109; + public static UNIT_GIVE_HANDITEM_PET = 2768; + public static PET_MOUNT = 1036; + public static PET_SUPPLEMENT = 749; + public static FURNITURE_GROUP_INFO = 2651; + public static ACHIEVEMENT_RESOLUTION_OPEN = 359; + public static USE_PET_PRODUCT = 1328; + public static REMOVE_PET_SADDLE = 186; + public static TOGGLE_PET_RIDING = 1472; + public static TOGGLE_PET_BREEDING = 3379; + public static UNSEEN_RESET_CATEGORY = 3493; + public static UNSEEN_RESET_ITEMS = 2343; + public static COMMUNITY_GOAL_VOTE_COMPOSER = 3536; + public static GET_PROMO_ARTICLES = 1827; + public static ACCEPT_QUEST = 3604; + public static ACTIVATE_QUEST = 793; + public static CANCEL_QUEST = 3133; + public static FRIEND_REQUEST_QUEST_COMPLETE = 1148; + public static GET_COMMUNITY_GOAL_EARNED_PRIZES = 2688; + public static GET_COMMUNITY_GOAL_HALL_OF_FAME = 2167; + public static GET_COMMUNITY_GOAL_PROGRESS = 1145; + public static GET_CONCURRENT_USERS_GOAL_PROGRESS = 1343; + public static GET_CONCURRENT_USERS_REWARD = 3872; + public static GET_DAILY_QUEST = 2486; + public static GET_QUESTS = 3333; + public static GET_SEASONAL_QUESTS_ONLY = 1190; + public static OPEN_QUEST_TRACKER = 2750; + public static REDEEM_COMMUNITY_GOAL_PRIZE = 90; + public static REJECT_QUEST = 2397; + public static START_CAMPAIGN = 1697; + public static GET_BONUS_RARE_INFO = 957; + public static CRAFT = 3591; + public static CRAFT_SECRET = 1251; + public static GET_CRAFTABLE_PRODUCTS = 633; + public static GET_CRAFTING_RECIPE = 1173; + public static GET_CRAFTING_RECIPES_AVAILABLE = 3086; + public static PHOTO_COMPETITION = 3959; + public static PUBLISH_PHOTO = 2068; + public static PURCHASE_PHOTO = 2408; + public static RENDER_ROOM = 3226; + public static RENDER_ROOM_THUMBNAIL = 1982; + public static REQUEST_CAMERA_CONFIGURATION = 796; + public static ADD_JUKEBOX_DISK = 753; + public static GET_JUKEBOX_PLAYLIST = 1435; + public static GET_NOW_PLAYING = 1325; + public static GET_OFFICIAL_SONG_ID = 3189; + public static GET_SONG_INFO = 3082; + public static GET_SOUND_MACHINE_PLAYLIST = 3498; + public static GET_USER_SONG_DISKS = 2304; + public static REMOVE_JUKEBOX_DISK = 3050; + public static INTERSTITIAL_SHOWN = 1109; + public static GET_INTERSTITIAL = 2519; + public static CHANGE_USERNAME = 2977; + public static CHECK_USERNAME = 3950; + public static OPEN_CAMPAIGN_CALENDAR_DOOR_STAFF= 3889; + public static OPEN_CAMPAIGN_CALENDAR_DOOR = 2257; + public static BUILDERS_CLUB_PLACE_ROOM_ITEM = 1051; + public static BUILDERS_CLUB_PLACE_WALL_ITEM = 462; + public static BUILDERS_CLUB_QUERY_FURNI_COUNT = 2529; + public static GET_CATALOG_PAGE_EXPIRATION = 742; + public static GET_CATALOG_PAGE_WITH_EARLIEST_EXP = 3135; + public static GET_DIRECT_CLUB_BUY_AVAILABLE = 801; + public static GET_HABBO_BASIC_MEMBERSHIP_EXTEND_OFFER = 603; + public static GET_HABBO_CLUB_EXTEND_OFFER = 2462; + public static GET_IS_OFFER_GIFTABLE = 1347; + public static GET_LIMITED_OFFER_APPEARING_NEXT = 410; + public static GET_NEXT_TARGETED_OFFER = 596; + public static GET_ROOM_AD_PURCHASE_INFO = 1075; + public static GET_SEASONAL_CALENDAR_DAILY_OFFER = 3257; + public static GET_TARGETED_OFFER = 2487; + public static MARK_CATALOG_NEW_ADDITIONS_PAGE_OPENED = 2150; + public static PURCHASE_BASIC_MEMBERSHIP_EXTENSION = 2735; + public static PURCHASE_ROOM_AD = 777; + public static PURCHASE_TARGETED_OFFER = 1826; + public static PURCHASE_VIP_MEMBERSHIP_EXTENSION = 3407; + public static ROOM_AD_PURCHASE_INITIATED = 2283; + public static SET_TARGETTED_OFFER_STATE = 2041; + public static SHOP_TARGETED_OFFER_VIEWED = 3483; + public static HELPER_TALENT_TRACK = 196; + public static TALENT_TRACK_GET_LEVEL = 2127; + public static FORWARD_TO_A_COMPETITION_ROOM = 172; + public static FORWARD_TO_A_SUBMITTABLE_ROOM = 1450; + public static FORWARD_TO_RANDOM_COMPETITION_ROOM = 865; + public static GET_IS_USER_PART_OF_COMPETITION = 2077; + public static GET_SECONDS_UNTIL = 271; + public static ROOM_COMPETITION_INIT = 1334; + public static SUBMIT_ROOM_TO_COMPETITION = 2595; + public static VOTE_FOR_ROOM = 143; + public static GET_GIFT = 2436; + public static RESET_PHONE_NUMBER_STATE = 2741; + public static SET_PHONE_NUMBER_VERIFICATION_STATUS = 1379; + public static TRY_PHONE_NUMBER = 790; + public static VERIFY_CODE = 2721; + public static CONTROL_YOUTUBE_DISPLAY_PLAYBACK = 3005; + public static GET_YOUTUBE_DISPLAY_STATUS = 336; + public static SET_YOUTUBE_DISPLAY_PLAYLIST = 2069; + public static GO_TO_FLAT = 685; + public static CHANGE_QUEUE = 3093; + public static CALL_FOR_HELP_FROM_FORUM_MESSAGE = 1412; + public static CALL_FOR_HELP_FROM_FORUM_THREAD = 534; + public static CALL_FOR_HELP_FROM_IM = 2950; + public static CALL_FOR_HELP_FROM_PHOTO = 2492; + public static CALL_FOR_HELP_FROM_SELFIE = 2755; + public static CHAT_REVIEW_GUIDE_DECIDES = 3365; + public static CHAT_REVIEW_GUIDE_DETACHED = 2501; + public static CHAT_REVIEW_GUIDE_VOTE = 3961; + public static CHAT_REVIEW_SESSION_CREATE = 3060; + public static DELETE_PENDING_CALLS_FOR_HELP = 3605; + public static GET_CFH_STATUS = 2746; + public static GET_FAQ_CATEGORY = 3445; + public static GET_FAQ_TEXT = 1849; + public static GET_GUIDE_REPORTING_STATUS = 3786; + public static GET_PENDING_CALLS_FOR_HELP = 3267; + public static GET_QUIZ_QUESTIONS = 1296; + public static GUIDE_SESSION_CREATE = 3338; + public static GUIDE_SESSION_FEEDBACK = 477; + public static GUIDE_SESSION_GET_REQUESTER_ROOM = 1052; + public static GUIDE_SESSION_GUIDE_DECIDES = 1424; + public static GUIDE_SESSION_INVITE_REQUESTER = 234; + public static GUIDE_SESSION_IS_TYPING = 519; + public static GUIDE_SESSION_MESSAGE = 3899; + public static GUIDE_SESSION_ON_DUTY_UPDATE = 1922; + public static GUIDE_SESSION_REPORT = 3969; + public static GUIDE_SESSION_REQUESTER_CANCELS = 291; + public static GUIDE_SESSION_RESOLVED = 887; + public static POST_QUIZ_ANSWERS = 3720; + public static SEARCH_FAQS = 2031; + public static POLL_ANSWER = 3505; + public static POLL_REJECT = 1773; + public static POLL_START = 109; + public static POLL_VOTE_COUNTER = 6200; + public static DISCONNECT = 2445; + public static SCR_GET_KICKBACK_INFO = 869; + public static COMPOST_PLANT = 3835; + public static HARVEST_PET = 1521; + public static SET_CLOTHING_CHANGE_DATA = 924; + public static GROUP_UNFAVORITE = 1820; + public static NEW_USER_EXPERIENCE_GET_GIFTS = 1822; + public static NEW_USER_EXPERIENCE_SCRIPT_PROCEED = 1299; + public static HANDSHAKE_INIT_DIFFIE = 3110; + public static HANDSHAKE_COMPLETE_DIFFIE = 773; + public static WELCOME_OPEN_GIFT = 2638; + public static WELCOME_GIFT_CHANGE_EMAIL = 66; + public static EMAIL_GET_STATUS = 2557; + public static EMAIL_CHANGE = 3965; + public static APPROVE_ALL_MEMBERSHIP_REQUESTS = 882; + public static RENTABLE_SPACE_CANCEL_RENT = 1667; + public static RENTABLE_SPACE_RENT = 2946; + public static RENTABLE_SPACE_STATUS = 872; + public static TRACKING_PERFORMANCE_LOG = 3230; + public static TRACKING_LAG_WARNING_REPORT = 3847; + public static ROOM_DIRECTORY_ROOM_NETWORK_OPEN_CONNECTION = 3736; + public static RENTABLE_EXTEND_RENT_OR_BUYOUT_STRIP_ITEM = 2115; + public static RENTABLE_EXTEND_RENT_OR_BUYOUT_FURNI = 1071; + public static RENTABLE_GET_RENT_OR_BUYOUT_OFFER = 2518; +} diff --git a/packages/communication/src/messages/outgoing/advertisement/GetInterstitialMessageComposer.ts b/packages/communication/src/messages/outgoing/advertisement/GetInterstitialMessageComposer.ts new file mode 100644 index 0000000..187c2b7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/advertisement/GetInterstitialMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetInterstitialMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public dispose(): void + { + return; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/advertisement/InterstitialShownMessageComposer.ts b/packages/communication/src/messages/outgoing/advertisement/InterstitialShownMessageComposer.ts new file mode 100644 index 0000000..7af8212 --- /dev/null +++ b/packages/communication/src/messages/outgoing/advertisement/InterstitialShownMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class InterstitialShownMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public dispose(): void + { + return; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/advertisement/RequestAchievementsMessageComposer.ts b/packages/communication/src/messages/outgoing/advertisement/RequestAchievementsMessageComposer.ts new file mode 100644 index 0000000..a61513e --- /dev/null +++ b/packages/communication/src/messages/outgoing/advertisement/RequestAchievementsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RequestAchievementsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/advertisement/index.ts b/packages/communication/src/messages/outgoing/advertisement/index.ts new file mode 100644 index 0000000..20e10fa --- /dev/null +++ b/packages/communication/src/messages/outgoing/advertisement/index.ts @@ -0,0 +1,3 @@ +export * from './GetInterstitialMessageComposer'; +export * from './InterstitialShownMessageComposer'; +export * from './RequestAchievementsMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/avatar/ChangeUserNameMessageComposer.ts b/packages/communication/src/messages/outgoing/avatar/ChangeUserNameMessageComposer.ts new file mode 100644 index 0000000..c720e17 --- /dev/null +++ b/packages/communication/src/messages/outgoing/avatar/ChangeUserNameMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ChangeUserNameMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(name: string) + { + this._data = [name]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/avatar/CheckUserNameMessageComposer.ts b/packages/communication/src/messages/outgoing/avatar/CheckUserNameMessageComposer.ts new file mode 100644 index 0000000..05c0f99 --- /dev/null +++ b/packages/communication/src/messages/outgoing/avatar/CheckUserNameMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CheckUserNameMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(name: string) + { + this._data = [name]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/avatar/GetWardrobeMessageComposer.ts b/packages/communication/src/messages/outgoing/avatar/GetWardrobeMessageComposer.ts new file mode 100644 index 0000000..ff75801 --- /dev/null +++ b/packages/communication/src/messages/outgoing/avatar/GetWardrobeMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetWardrobeMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(pageId: number = 0) + { + this._data = [pageId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/avatar/SaveWardrobeOutfitMessageComposer.ts b/packages/communication/src/messages/outgoing/avatar/SaveWardrobeOutfitMessageComposer.ts new file mode 100644 index 0000000..0862e91 --- /dev/null +++ b/packages/communication/src/messages/outgoing/avatar/SaveWardrobeOutfitMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SaveWardrobeOutfitMessageComposer 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/packages/communication/src/messages/outgoing/avatar/index.ts b/packages/communication/src/messages/outgoing/avatar/index.ts new file mode 100644 index 0000000..fc2f210 --- /dev/null +++ b/packages/communication/src/messages/outgoing/avatar/index.ts @@ -0,0 +1,4 @@ +export * from './ChangeUserNameMessageComposer'; +export * from './CheckUserNameMessageComposer'; +export * from './GetWardrobeMessageComposer'; +export * from './SaveWardrobeOutfitMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/camera/PhotoCompetitionMessageComposer.ts b/packages/communication/src/messages/outgoing/camera/PhotoCompetitionMessageComposer.ts new file mode 100644 index 0000000..edc6c36 --- /dev/null +++ b/packages/communication/src/messages/outgoing/camera/PhotoCompetitionMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PhotoCompetitionMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/camera/PublishPhotoMessageComposer.ts b/packages/communication/src/messages/outgoing/camera/PublishPhotoMessageComposer.ts new file mode 100644 index 0000000..3ba3789 --- /dev/null +++ b/packages/communication/src/messages/outgoing/camera/PublishPhotoMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PublishPhotoMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/camera/PurchasePhotoMessageComposer.ts b/packages/communication/src/messages/outgoing/camera/PurchasePhotoMessageComposer.ts new file mode 100644 index 0000000..6ee27d0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/camera/PurchasePhotoMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PurchasePhotoMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(photoId: string) + { + this._data = [photoId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/camera/RenderRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/camera/RenderRoomMessageComposer.ts new file mode 100644 index 0000000..cf4c3ac --- /dev/null +++ b/packages/communication/src/messages/outgoing/camera/RenderRoomMessageComposer.ts @@ -0,0 +1,43 @@ +import { IMessageComposer } from '@nitrots/api'; +import { TextureUtils } from '@nitrots/utils'; +import { RenderTexture } from 'pixi.js'; + +export class RenderRoomMessageComposer implements IMessageComposer> +{ + private _data: any; + + constructor(k: any = '', _arg_2: string = '', _arg_3: string = '', _arg_4: number = -1, _arg_5: number = -1) + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = []; + } + + public async assignBitmap(texture: RenderTexture): Promise + { + const url = await TextureUtils.generateImageUrl(texture); + + if(!url) return; + + const base64Data = url.split(',')[1]; + const binaryData = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0)); + + this._data.push(binaryData.byteLength, binaryData.buffer); + } + + public assignBase64(base64: string): void + { + const base64Data = base64.split(',')[1]; + const binaryData = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0)); + + this._data.push(binaryData.byteLength, binaryData.buffer); + } +} diff --git a/packages/communication/src/messages/outgoing/camera/RenderRoomThumbnailMessageComposer.ts b/packages/communication/src/messages/outgoing/camera/RenderRoomThumbnailMessageComposer.ts new file mode 100644 index 0000000..78a2bf4 --- /dev/null +++ b/packages/communication/src/messages/outgoing/camera/RenderRoomThumbnailMessageComposer.ts @@ -0,0 +1,9 @@ +import { RenderRoomMessageComposer } from './RenderRoomMessageComposer'; + +export class RenderRoomThumbnailMessageComposer extends RenderRoomMessageComposer +{ + constructor(k:any = '', _arg_2: string = '', _arg_3: string = '', _arg_4: number = -1, _arg_5: number = -1) + { + super(k, _arg_2, _arg_3, _arg_4, _arg_5); + } +} diff --git a/packages/communication/src/messages/outgoing/camera/RequestCameraConfigurationComposer.ts b/packages/communication/src/messages/outgoing/camera/RequestCameraConfigurationComposer.ts new file mode 100644 index 0000000..e845049 --- /dev/null +++ b/packages/communication/src/messages/outgoing/camera/RequestCameraConfigurationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RequestCameraConfigurationComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/camera/index.ts b/packages/communication/src/messages/outgoing/camera/index.ts new file mode 100644 index 0000000..626c1cd --- /dev/null +++ b/packages/communication/src/messages/outgoing/camera/index.ts @@ -0,0 +1,6 @@ +export * from './PhotoCompetitionMessageComposer'; +export * from './PublishPhotoMessageComposer'; +export * from './PurchasePhotoMessageComposer'; +export * from './RenderRoomMessageComposer'; +export * from './RenderRoomThumbnailMessageComposer'; +export * from './RequestCameraConfigurationComposer'; diff --git a/packages/communication/src/messages/outgoing/campaign/OpenCampaignCalendarDoorAsStaffComposer.ts b/packages/communication/src/messages/outgoing/campaign/OpenCampaignCalendarDoorAsStaffComposer.ts new file mode 100644 index 0000000..d58a329 --- /dev/null +++ b/packages/communication/src/messages/outgoing/campaign/OpenCampaignCalendarDoorAsStaffComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class OpenCampaignCalendarDoorAsStaffComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/campaign/OpenCampaignCalendarDoorComposer.ts b/packages/communication/src/messages/outgoing/campaign/OpenCampaignCalendarDoorComposer.ts new file mode 100644 index 0000000..27290a7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/campaign/OpenCampaignCalendarDoorComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class OpenCampaignCalendarDoorComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/campaign/index.ts b/packages/communication/src/messages/outgoing/campaign/index.ts new file mode 100644 index 0000000..2ecdb09 --- /dev/null +++ b/packages/communication/src/messages/outgoing/campaign/index.ts @@ -0,0 +1,2 @@ +export * from './OpenCampaignCalendarDoorAsStaffComposer'; +export * from './OpenCampaignCalendarDoorComposer'; diff --git a/packages/communication/src/messages/outgoing/catalog/BuildersClubPlaceRoomItemMessageComposer.ts b/packages/communication/src/messages/outgoing/catalog/BuildersClubPlaceRoomItemMessageComposer.ts new file mode 100644 index 0000000..5ee050a --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/BuildersClubPlaceRoomItemMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class BuildersClubPlaceRoomItemMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: string, _arg_4: number, _arg_5: number, _arg_6: number) + { + this._data = [k, _arg_2, _arg_3, _arg_4, _arg_5, _arg_6]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/BuildersClubPlaceWallItemMessageComposer.ts b/packages/communication/src/messages/outgoing/catalog/BuildersClubPlaceWallItemMessageComposer.ts new file mode 100644 index 0000000..85a560b --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/BuildersClubPlaceWallItemMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class BuildersClubPlaceWallItemMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: string, _arg_4: string) + { + this._data = [k, _arg_2, _arg_3, _arg_4]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/BuildersClubQueryFurniCountMessageComposer.ts b/packages/communication/src/messages/outgoing/catalog/BuildersClubQueryFurniCountMessageComposer.ts new file mode 100644 index 0000000..6250ea9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/BuildersClubQueryFurniCountMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class BuildersClubQueryFurniCountMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetBonusRareInfoMessageComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetBonusRareInfoMessageComposer.ts new file mode 100644 index 0000000..b95e3f3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetBonusRareInfoMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetBonusRareInfoMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetBundleDiscountRulesetComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetBundleDiscountRulesetComposer.ts new file mode 100644 index 0000000..24e3564 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetBundleDiscountRulesetComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetBundleDiscountRulesetComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetCatalogIndexComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetCatalogIndexComposer.ts new file mode 100644 index 0000000..9fbc8f3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetCatalogIndexComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCatalogIndexComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(mode: string) + { + this._data = [mode]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetCatalogPageComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetCatalogPageComposer.ts new file mode 100644 index 0000000..0b174ea --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetCatalogPageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCatalogPageComposer 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; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetCatalogPageExpirationComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetCatalogPageExpirationComposer.ts new file mode 100644 index 0000000..c55aa49 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetCatalogPageExpirationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCatalogPageExpirationComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetCatalogPageWithEarliestExpiryComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetCatalogPageWithEarliestExpiryComposer.ts new file mode 100644 index 0000000..9599381 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetCatalogPageWithEarliestExpiryComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCatalogPageWithEarliestExpiryComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetClubGiftInfo.ts b/packages/communication/src/messages/outgoing/catalog/GetClubGiftInfo.ts new file mode 100644 index 0000000..ed23ada --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetClubGiftInfo.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetClubGiftInfo implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetClubOffersMessageComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetClubOffersMessageComposer.ts new file mode 100644 index 0000000..bd9bbf8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetClubOffersMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetClubOffersMessageComposer 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/packages/communication/src/messages/outgoing/catalog/GetDirectClubBuyAvailableComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetDirectClubBuyAvailableComposer.ts new file mode 100644 index 0000000..8b6ab07 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetDirectClubBuyAvailableComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetDirectClubBuyAvailableComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(days: number) + { + this._data = [days]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetGiftWrappingConfigurationComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetGiftWrappingConfigurationComposer.ts new file mode 100644 index 0000000..34e1dc1 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetGiftWrappingConfigurationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetGiftWrappingConfigurationComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetHabboBasicMembershipExtendOfferComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetHabboBasicMembershipExtendOfferComposer.ts new file mode 100644 index 0000000..03611db --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetHabboBasicMembershipExtendOfferComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetHabboBasicMembershipExtendOfferComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetHabboClubExtendOfferMessageComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetHabboClubExtendOfferMessageComposer.ts new file mode 100644 index 0000000..ab895bc --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetHabboClubExtendOfferMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetHabboClubExtendOfferMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetIsOfferGiftableComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetIsOfferGiftableComposer.ts new file mode 100644 index 0000000..25ba416 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetIsOfferGiftableComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetIsOfferGiftableComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetLimitedOfferAppearingNextComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetLimitedOfferAppearingNextComposer.ts new file mode 100644 index 0000000..69ff44e --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetLimitedOfferAppearingNextComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetLimitedOfferAppearingNextComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetNextTargetedOfferComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetNextTargetedOfferComposer.ts new file mode 100644 index 0000000..5384330 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetNextTargetedOfferComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetNextTargetedOfferComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetProductOfferComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetProductOfferComposer.ts new file mode 100644 index 0000000..65ac19b --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetProductOfferComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetProductOfferComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(offerId: number) + { + this._data = [offerId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetRoomAdPurchaseInfoComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetRoomAdPurchaseInfoComposer.ts new file mode 100644 index 0000000..6f7d3f0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetRoomAdPurchaseInfoComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetRoomAdPurchaseInfoComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetSeasonalCalendarDailyOfferComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetSeasonalCalendarDailyOfferComposer.ts new file mode 100644 index 0000000..3cff9bd --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetSeasonalCalendarDailyOfferComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetSeasonalCalendarDailyOfferComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetSellablePetPalettesComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetSellablePetPalettesComposer.ts new file mode 100644 index 0000000..7b00e14 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetSellablePetPalettesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetSellablePetPalettesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(name: string) + { + this._data = [name]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/GetTargetedOfferComposer.ts b/packages/communication/src/messages/outgoing/catalog/GetTargetedOfferComposer.ts new file mode 100644 index 0000000..bb70069 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/GetTargetedOfferComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetTargetedOfferComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/MarkCatalogNewAdditionsPageOpenedComposer.ts b/packages/communication/src/messages/outgoing/catalog/MarkCatalogNewAdditionsPageOpenedComposer.ts new file mode 100644 index 0000000..0989a39 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/MarkCatalogNewAdditionsPageOpenedComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MarkCatalogNewAdditionsPageOpenedComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/PurchaseBasicMembershipExtensionComposer.ts b/packages/communication/src/messages/outgoing/catalog/PurchaseBasicMembershipExtensionComposer.ts new file mode 100644 index 0000000..34249dd --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/PurchaseBasicMembershipExtensionComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PurchaseBasicMembershipExtensionComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/PurchaseFromCatalogAsGiftComposer.ts b/packages/communication/src/messages/outgoing/catalog/PurchaseFromCatalogAsGiftComposer.ts new file mode 100644 index 0000000..7471d73 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/PurchaseFromCatalogAsGiftComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PurchaseFromCatalogAsGiftComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(pageId: number, itemId: number, extraData: string, receivingName: string, giftMessage: string, spriteId: number, boxId: number, ribbonId: number, showMyFace: boolean) + { + this._data = [pageId, itemId, extraData, receivingName, giftMessage, spriteId, boxId, ribbonId, showMyFace]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/PurchaseFromCatalogComposer.ts b/packages/communication/src/messages/outgoing/catalog/PurchaseFromCatalogComposer.ts new file mode 100644 index 0000000..fcc916a --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/PurchaseFromCatalogComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PurchaseFromCatalogComposer 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; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/PurchaseRoomAdMessageComposer.ts b/packages/communication/src/messages/outgoing/catalog/PurchaseRoomAdMessageComposer.ts new file mode 100644 index 0000000..7c9604e --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/PurchaseRoomAdMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PurchaseRoomAdMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: string, _arg_5: boolean, _arg_6: string, _arg_7: number) + { + this._data = [k, _arg_2, _arg_3, _arg_4, _arg_5, _arg_6, _arg_7]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/PurchaseTargetedOfferComposer.ts b/packages/communication/src/messages/outgoing/catalog/PurchaseTargetedOfferComposer.ts new file mode 100644 index 0000000..15ec1a5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/PurchaseTargetedOfferComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PurchaseTargetedOfferComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/PurchaseVipMembershipExtensionComposer.ts b/packages/communication/src/messages/outgoing/catalog/PurchaseVipMembershipExtensionComposer.ts new file mode 100644 index 0000000..9160054 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/PurchaseVipMembershipExtensionComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PurchaseVipMembershipExtensionComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/RedeemVoucherMessageComposer.ts b/packages/communication/src/messages/outgoing/catalog/RedeemVoucherMessageComposer.ts new file mode 100644 index 0000000..5d4c373 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/RedeemVoucherMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RedeemVoucherMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(voucherCode: string) + { + this._data = [voucherCode]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/RoomAdPurchaseInitiatedComposer.ts b/packages/communication/src/messages/outgoing/catalog/RoomAdPurchaseInitiatedComposer.ts new file mode 100644 index 0000000..9753c7e --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/RoomAdPurchaseInitiatedComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomAdPurchaseInitiatedComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/SelectClubGiftComposer.ts b/packages/communication/src/messages/outgoing/catalog/SelectClubGiftComposer.ts new file mode 100644 index 0000000..4117956 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/SelectClubGiftComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SelectClubGiftComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemName: string) + { + this._data = [itemName]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/SetTargetedOfferStateComposer.ts b/packages/communication/src/messages/outgoing/catalog/SetTargetedOfferStateComposer.ts new file mode 100644 index 0000000..511bf8a --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/SetTargetedOfferStateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SetTargetedOfferStateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/ShopTargetedOfferViewedComposer.ts b/packages/communication/src/messages/outgoing/catalog/ShopTargetedOfferViewedComposer.ts new file mode 100644 index 0000000..22079a8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/ShopTargetedOfferViewedComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ShopTargetedOfferViewedComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/catalog/index.ts b/packages/communication/src/messages/outgoing/catalog/index.ts new file mode 100644 index 0000000..c30e6e8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/catalog/index.ts @@ -0,0 +1,35 @@ +export * from './BuildersClubPlaceRoomItemMessageComposer'; +export * from './BuildersClubPlaceWallItemMessageComposer'; +export * from './BuildersClubQueryFurniCountMessageComposer'; +export * from './GetBonusRareInfoMessageComposer'; +export * from './GetBundleDiscountRulesetComposer'; +export * from './GetCatalogIndexComposer'; +export * from './GetCatalogPageComposer'; +export * from './GetCatalogPageExpirationComposer'; +export * from './GetCatalogPageWithEarliestExpiryComposer'; +export * from './GetClubGiftInfo'; +export * from './GetClubOffersMessageComposer'; +export * from './GetDirectClubBuyAvailableComposer'; +export * from './GetGiftWrappingConfigurationComposer'; +export * from './GetHabboBasicMembershipExtendOfferComposer'; +export * from './GetHabboClubExtendOfferMessageComposer'; +export * from './GetIsOfferGiftableComposer'; +export * from './GetLimitedOfferAppearingNextComposer'; +export * from './GetNextTargetedOfferComposer'; +export * from './GetProductOfferComposer'; +export * from './GetRoomAdPurchaseInfoComposer'; +export * from './GetSeasonalCalendarDailyOfferComposer'; +export * from './GetSellablePetPalettesComposer'; +export * from './GetTargetedOfferComposer'; +export * from './MarkCatalogNewAdditionsPageOpenedComposer'; +export * from './PurchaseBasicMembershipExtensionComposer'; +export * from './PurchaseFromCatalogAsGiftComposer'; +export * from './PurchaseFromCatalogComposer'; +export * from './PurchaseRoomAdMessageComposer'; +export * from './PurchaseTargetedOfferComposer'; +export * from './PurchaseVipMembershipExtensionComposer'; +export * from './RedeemVoucherMessageComposer'; +export * from './RoomAdPurchaseInitiatedComposer'; +export * from './SelectClubGiftComposer'; +export * from './SetTargetedOfferStateComposer'; +export * from './ShopTargetedOfferViewedComposer'; diff --git a/packages/communication/src/messages/outgoing/competition/ForwardToACompetitionRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/competition/ForwardToACompetitionRoomMessageComposer.ts new file mode 100644 index 0000000..cb60f62 --- /dev/null +++ b/packages/communication/src/messages/outgoing/competition/ForwardToACompetitionRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ForwardToACompetitionRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/competition/ForwardToASubmittableRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/competition/ForwardToASubmittableRoomMessageComposer.ts new file mode 100644 index 0000000..e216731 --- /dev/null +++ b/packages/communication/src/messages/outgoing/competition/ForwardToASubmittableRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ForwardToASubmittableRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/competition/ForwardToRandomCompetitionRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/competition/ForwardToRandomCompetitionRoomMessageComposer.ts new file mode 100644 index 0000000..c5c087a --- /dev/null +++ b/packages/communication/src/messages/outgoing/competition/ForwardToRandomCompetitionRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ForwardToRandomCompetitionRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/competition/GetCurrentTimingCodeMessageComposer.ts b/packages/communication/src/messages/outgoing/competition/GetCurrentTimingCodeMessageComposer.ts new file mode 100644 index 0000000..d1033ab --- /dev/null +++ b/packages/communication/src/messages/outgoing/competition/GetCurrentTimingCodeMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCurrentTimingCodeMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/competition/GetIsUserPartOfCompetitionMessageComposer.ts b/packages/communication/src/messages/outgoing/competition/GetIsUserPartOfCompetitionMessageComposer.ts new file mode 100644 index 0000000..6e669d5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/competition/GetIsUserPartOfCompetitionMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetIsUserPartOfCompetitionMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/competition/GetSecondsUntilMessageComposer.ts b/packages/communication/src/messages/outgoing/competition/GetSecondsUntilMessageComposer.ts new file mode 100644 index 0000000..f99a04f --- /dev/null +++ b/packages/communication/src/messages/outgoing/competition/GetSecondsUntilMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetSecondsUntilMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/competition/RoomCompetitionInitMessageComposer.ts b/packages/communication/src/messages/outgoing/competition/RoomCompetitionInitMessageComposer.ts new file mode 100644 index 0000000..6e995d6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/competition/RoomCompetitionInitMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomCompetitionInitMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/competition/SubmitRoomToCompetitionMessageComposer.ts b/packages/communication/src/messages/outgoing/competition/SubmitRoomToCompetitionMessageComposer.ts new file mode 100644 index 0000000..337b487 --- /dev/null +++ b/packages/communication/src/messages/outgoing/competition/SubmitRoomToCompetitionMessageComposer.ts @@ -0,0 +1,26 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SubmitRoomToCompetitionMessageComposer implements IMessageComposer> +{ + public static readonly CONFIRM_LEVEL_NOT_ACCEPTED = 0; + public static readonly CONFIRM_LEVEL_NOT_SUBMITTED = 1; + public static readonly CONFIRM_LEVEL_NOT_CONFIRMED = 2; + public static readonly CONFIRM_LEVEL_COMMIT = 3; + + private _data: ConstructorParameters; + + constructor(k: string, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/competition/VoteForRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/competition/VoteForRoomMessageComposer.ts new file mode 100644 index 0000000..683a017 --- /dev/null +++ b/packages/communication/src/messages/outgoing/competition/VoteForRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class VoteForRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/competition/index.ts b/packages/communication/src/messages/outgoing/competition/index.ts new file mode 100644 index 0000000..c99db8f --- /dev/null +++ b/packages/communication/src/messages/outgoing/competition/index.ts @@ -0,0 +1,9 @@ +export * from './ForwardToACompetitionRoomMessageComposer'; +export * from './ForwardToASubmittableRoomMessageComposer'; +export * from './ForwardToRandomCompetitionRoomMessageComposer'; +export * from './GetCurrentTimingCodeMessageComposer'; +export * from './GetIsUserPartOfCompetitionMessageComposer'; +export * from './GetSecondsUntilMessageComposer'; +export * from './RoomCompetitionInitMessageComposer'; +export * from './SubmitRoomToCompetitionMessageComposer'; +export * from './VoteForRoomMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/crafting/CraftComposer.ts b/packages/communication/src/messages/outgoing/crafting/CraftComposer.ts new file mode 100644 index 0000000..d70a478 --- /dev/null +++ b/packages/communication/src/messages/outgoing/crafting/CraftComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CraftComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: string) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/crafting/CraftSecretComposer.ts b/packages/communication/src/messages/outgoing/crafting/CraftSecretComposer.ts new file mode 100644 index 0000000..79929a7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/crafting/CraftSecretComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CraftSecretComposer implements IMessageComposer +{ + private _data: number[]; + + constructor(k: number, _arg_2: number[]) + { + this._data = [k, _arg_2.length].concat(_arg_2); + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/crafting/GetCraftableProductsComposer.ts b/packages/communication/src/messages/outgoing/crafting/GetCraftableProductsComposer.ts new file mode 100644 index 0000000..52feb40 --- /dev/null +++ b/packages/communication/src/messages/outgoing/crafting/GetCraftableProductsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCraftableProductsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/crafting/GetCraftingRecipeComposer.ts b/packages/communication/src/messages/outgoing/crafting/GetCraftingRecipeComposer.ts new file mode 100644 index 0000000..dfcfd28 --- /dev/null +++ b/packages/communication/src/messages/outgoing/crafting/GetCraftingRecipeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCraftingRecipeComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/crafting/GetCraftingRecipesAvailableComposer.ts b/packages/communication/src/messages/outgoing/crafting/GetCraftingRecipesAvailableComposer.ts new file mode 100644 index 0000000..a6b94a8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/crafting/GetCraftingRecipesAvailableComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCraftingRecipesAvailableComposer implements IMessageComposer +{ + private _data: number[]; + + constructor(k: number, _arg_2: number[]) + { + this._data = [k, _arg_2.length].concat(_arg_2); + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/crafting/index.ts b/packages/communication/src/messages/outgoing/crafting/index.ts new file mode 100644 index 0000000..ab46a6d --- /dev/null +++ b/packages/communication/src/messages/outgoing/crafting/index.ts @@ -0,0 +1,5 @@ +export * from './CraftComposer'; +export * from './CraftSecretComposer'; +export * from './GetCraftableProductsComposer'; +export * from './GetCraftingRecipeComposer'; +export * from './GetCraftingRecipesAvailableComposer'; diff --git a/packages/communication/src/messages/outgoing/desktop/DesktopViewComposer.ts b/packages/communication/src/messages/outgoing/desktop/DesktopViewComposer.ts new file mode 100644 index 0000000..1c4bb8c --- /dev/null +++ b/packages/communication/src/messages/outgoing/desktop/DesktopViewComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class DesktopViewComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/desktop/index.ts b/packages/communication/src/messages/outgoing/desktop/index.ts new file mode 100644 index 0000000..af7fc6e --- /dev/null +++ b/packages/communication/src/messages/outgoing/desktop/index.ts @@ -0,0 +1 @@ +export * from './DesktopViewComposer'; diff --git a/packages/communication/src/messages/outgoing/friendfurni/FriendFurniConfirmLockMessageComposer.ts b/packages/communication/src/messages/outgoing/friendfurni/FriendFurniConfirmLockMessageComposer.ts new file mode 100644 index 0000000..95bdf69 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendfurni/FriendFurniConfirmLockMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FriendFurniConfirmLockMessageComposer 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/packages/communication/src/messages/outgoing/friendfurni/index.ts b/packages/communication/src/messages/outgoing/friendfurni/index.ts new file mode 100644 index 0000000..545be87 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendfurni/index.ts @@ -0,0 +1 @@ +export * from './FriendFurniConfirmLockMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/friendlist/AcceptFriendMessageComposer.ts b/packages/communication/src/messages/outgoing/friendlist/AcceptFriendMessageComposer.ts new file mode 100644 index 0000000..b52d23b --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/AcceptFriendMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class AcceptFriendMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(...userIds: number[]) + { + this._data = [userIds.length, ...userIds]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/DeclineFriendMessageComposer.ts b/packages/communication/src/messages/outgoing/friendlist/DeclineFriendMessageComposer.ts new file mode 100644 index 0000000..68c632e --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/DeclineFriendMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class DeclineFriendMessageComposer 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; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/FindNewFriendsMessageComposer.ts b/packages/communication/src/messages/outgoing/friendlist/FindNewFriendsMessageComposer.ts new file mode 100644 index 0000000..d581512 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/FindNewFriendsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FindNewFriendsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/FollowFriendMessageComposer.ts b/packages/communication/src/messages/outgoing/friendlist/FollowFriendMessageComposer.ts new file mode 100644 index 0000000..47a2a58 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/FollowFriendMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FollowFriendMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/FriendListUpdateComposer.ts b/packages/communication/src/messages/outgoing/friendlist/FriendListUpdateComposer.ts new file mode 100644 index 0000000..b8973fc --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/FriendListUpdateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FriendListUpdateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/GetFriendRequestsComposer.ts b/packages/communication/src/messages/outgoing/friendlist/GetFriendRequestsComposer.ts new file mode 100644 index 0000000..b8bae25 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/GetFriendRequestsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetFriendRequestsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/HabboSearchComposer.ts b/packages/communication/src/messages/outgoing/friendlist/HabboSearchComposer.ts new file mode 100644 index 0000000..c770344 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/HabboSearchComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class HabboSearchComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(search: string) + { + this._data = [search]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/MessengerInitComposer.ts b/packages/communication/src/messages/outgoing/friendlist/MessengerInitComposer.ts new file mode 100644 index 0000000..000ceac --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/MessengerInitComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MessengerInitComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/RemoveFriendComposer.ts b/packages/communication/src/messages/outgoing/friendlist/RemoveFriendComposer.ts new file mode 100644 index 0000000..ccdab6c --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/RemoveFriendComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/RequestFriendComposer.ts b/packages/communication/src/messages/outgoing/friendlist/RequestFriendComposer.ts new file mode 100644 index 0000000..0b56bd6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/RequestFriendComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RequestFriendComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(username: string) + { + this._data = [username]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/SendMessageComposer.ts b/packages/communication/src/messages/outgoing/friendlist/SendMessageComposer.ts new file mode 100644 index 0000000..1fce699 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/SendMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/SendRoomInviteComposer.ts b/packages/communication/src/messages/outgoing/friendlist/SendRoomInviteComposer.ts new file mode 100644 index 0000000..3fe9d8d --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/SendRoomInviteComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SendRoomInviteComposer implements IMessageComposer +{ + private _data: any; + + constructor(message: string, userIds: number[]) + { + this._data = [userIds.length, ...userIds, message]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/SetRelationshipStatusComposer.ts b/packages/communication/src/messages/outgoing/friendlist/SetRelationshipStatusComposer.ts new file mode 100644 index 0000000..4a04c04 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/SetRelationshipStatusComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/VisitUserComposer.ts b/packages/communication/src/messages/outgoing/friendlist/VisitUserComposer.ts new file mode 100644 index 0000000..ea53582 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/VisitUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class VisitUserComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(username: string) + { + this._data = [username]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/friendlist/index.ts b/packages/communication/src/messages/outgoing/friendlist/index.ts new file mode 100644 index 0000000..501c3c9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/friendlist/index.ts @@ -0,0 +1,14 @@ +export * from './AcceptFriendMessageComposer'; +export * from './DeclineFriendMessageComposer'; +export * from './FindNewFriendsMessageComposer'; +export * from './FollowFriendMessageComposer'; +export * from './FriendListUpdateComposer'; +export * from './GetFriendRequestsComposer'; +export * from './HabboSearchComposer'; +export * from './MessengerInitComposer'; +export * from './RemoveFriendComposer'; +export * from './RequestFriendComposer'; +export * from './SendMessageComposer'; +export * from './SendRoomInviteComposer'; +export * from './SetRelationshipStatusComposer'; +export * from './VisitUserComposer'; diff --git a/packages/communication/src/messages/outgoing/game/arena/Game2ExitGameMessageComposer.ts b/packages/communication/src/messages/outgoing/game/arena/Game2ExitGameMessageComposer.ts new file mode 100644 index 0000000..31885ac --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/arena/Game2ExitGameMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class Game2ExitGameMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(exitToRoomBeforeGame = true) + { + this._data = [ exitToRoomBeforeGame ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/arena/Game2GameChatMessageComposer.ts b/packages/communication/src/messages/outgoing/game/arena/Game2GameChatMessageComposer.ts new file mode 100644 index 0000000..9e3ee81 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/arena/Game2GameChatMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class Game2GameChatMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(chatLine: string) + { + this._data = [ chatLine ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/arena/Game2LoadStageReadyMessageComposer.ts b/packages/communication/src/messages/outgoing/game/arena/Game2LoadStageReadyMessageComposer.ts new file mode 100644 index 0000000..61584c7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/arena/Game2LoadStageReadyMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class Game2LoadStageReadyMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/arena/Game2PlayAgainMessageComposer.ts b/packages/communication/src/messages/outgoing/game/arena/Game2PlayAgainMessageComposer.ts new file mode 100644 index 0000000..2e537e5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/arena/Game2PlayAgainMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class Game2PlayAgainMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = [ ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/arena/index.ts b/packages/communication/src/messages/outgoing/game/arena/index.ts new file mode 100644 index 0000000..b13a00d --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/arena/index.ts @@ -0,0 +1,4 @@ +export * from './Game2ExitGameMessageComposer'; +export * from './Game2GameChatMessageComposer'; +export * from './Game2LoadStageReadyMessageComposer'; +export * from './Game2PlayAgainMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/game/directory/Game2CheckGameDirectoryStatusMessageComposer.ts b/packages/communication/src/messages/outgoing/game/directory/Game2CheckGameDirectoryStatusMessageComposer.ts new file mode 100644 index 0000000..66b2da9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/directory/Game2CheckGameDirectoryStatusMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class Game2CheckGameDirectoryStatusMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = [ ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/directory/Game2GetAccountGameStatusMessageComposer.ts b/packages/communication/src/messages/outgoing/game/directory/Game2GetAccountGameStatusMessageComposer.ts new file mode 100644 index 0000000..e850477 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/directory/Game2GetAccountGameStatusMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class Game2GetAccountGameStatusMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/directory/index.ts b/packages/communication/src/messages/outgoing/game/directory/index.ts new file mode 100644 index 0000000..9274423 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/directory/index.ts @@ -0,0 +1,2 @@ +export * from './Game2CheckGameDirectoryStatusMessageComposer'; +export * from './Game2GetAccountGameStatusMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/game/index.ts b/packages/communication/src/messages/outgoing/game/index.ts new file mode 100644 index 0000000..af311fb --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/index.ts @@ -0,0 +1,5 @@ +export * from './arena'; +export * from './directory'; +export * from './ingame'; +export * from './lobby'; +export * from './score'; diff --git a/packages/communication/src/messages/outgoing/game/ingame/Game2RequestFullStatusUpdateMessageComposer.ts b/packages/communication/src/messages/outgoing/game/ingame/Game2RequestFullStatusUpdateMessageComposer.ts new file mode 100644 index 0000000..132e461 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/ingame/Game2RequestFullStatusUpdateMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class Game2RequestFullStatusUpdateMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/ingame/index.ts b/packages/communication/src/messages/outgoing/game/ingame/index.ts new file mode 100644 index 0000000..b406813 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/ingame/index.ts @@ -0,0 +1 @@ +export * from './Game2RequestFullStatusUpdateMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/game/lobby/AcceptGameInviteMessageComposer.ts b/packages/communication/src/messages/outgoing/game/lobby/AcceptGameInviteMessageComposer.ts new file mode 100644 index 0000000..7ddab13 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/AcceptGameInviteMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class AcceptGameInviteMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k:number, _arg_2:number) + { + this._data = [ k, _arg_2 ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/lobby/GameUnloadedMessageComposer.ts b/packages/communication/src/messages/outgoing/game/lobby/GameUnloadedMessageComposer.ts new file mode 100644 index 0000000..6631653 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/GameUnloadedMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GameUnloadedMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/lobby/GetGameAchievementsMessageComposer.ts b/packages/communication/src/messages/outgoing/game/lobby/GetGameAchievementsMessageComposer.ts new file mode 100644 index 0000000..a89303c --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/GetGameAchievementsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetGameAchievementsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = [ ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/lobby/GetGameListMessageComposer.ts b/packages/communication/src/messages/outgoing/game/lobby/GetGameListMessageComposer.ts new file mode 100644 index 0000000..671e88b --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/GetGameListMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetGameListMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = [ ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/lobby/GetGameStatusMessageComposer.ts b/packages/communication/src/messages/outgoing/game/lobby/GetGameStatusMessageComposer.ts new file mode 100644 index 0000000..465e212 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/GetGameStatusMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetGameStatusMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/lobby/GetResolutionAchievementsMessageComposer.ts b/packages/communication/src/messages/outgoing/game/lobby/GetResolutionAchievementsMessageComposer.ts new file mode 100644 index 0000000..c70d91e --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/GetResolutionAchievementsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetResolutionAchievementsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(objectId: number, achievementId: number) + { + this._data = [objectId, achievementId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/game/lobby/GetUserGameAchievementsMessageComposer.ts b/packages/communication/src/messages/outgoing/game/lobby/GetUserGameAchievementsMessageComposer.ts new file mode 100644 index 0000000..c721f13 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/GetUserGameAchievementsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetUserGameAchievementsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/lobby/JoinQueueMessageComposer.ts b/packages/communication/src/messages/outgoing/game/lobby/JoinQueueMessageComposer.ts new file mode 100644 index 0000000..e65dd6c --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/JoinQueueMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class JoinQueueMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/lobby/LeaveQueueMessageComposer.ts b/packages/communication/src/messages/outgoing/game/lobby/LeaveQueueMessageComposer.ts new file mode 100644 index 0000000..5105a3e --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/LeaveQueueMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class LeaveQueueMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/lobby/ResetResolutionAchievementMessageComposer.ts b/packages/communication/src/messages/outgoing/game/lobby/ResetResolutionAchievementMessageComposer.ts new file mode 100644 index 0000000..c28b61d --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/ResetResolutionAchievementMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ResetResolutionAchievementMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/lobby/index.ts b/packages/communication/src/messages/outgoing/game/lobby/index.ts new file mode 100644 index 0000000..e6ed4d2 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/lobby/index.ts @@ -0,0 +1,10 @@ +export * from './AcceptGameInviteMessageComposer'; +export * from './GameUnloadedMessageComposer'; +export * from './GetGameAchievementsMessageComposer'; +export * from './GetGameListMessageComposer'; +export * from './GetGameStatusMessageComposer'; +export * from './GetResolutionAchievementsMessageComposer'; +export * from './GetUserGameAchievementsMessageComposer'; +export * from './JoinQueueMessageComposer'; +export * from './LeaveQueueMessageComposer'; +export * from './ResetResolutionAchievementMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/game/score/Game2GetWeeklyFriendsLeaderboardComposer.ts b/packages/communication/src/messages/outgoing/game/score/Game2GetWeeklyFriendsLeaderboardComposer.ts new file mode 100644 index 0000000..a1f05ef --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/score/Game2GetWeeklyFriendsLeaderboardComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class Game2GetWeeklyFriendsLeaderboardComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k:number, _arg_2:number, _arg_3:number, _arg_4:number, _arg_5:number, _arg_6:number) + { + this._data = [ k, _arg_2, _arg_3, _arg_4, _arg_5, _arg_6 ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/score/Game2GetWeeklyLeaderboardComposer.ts b/packages/communication/src/messages/outgoing/game/score/Game2GetWeeklyLeaderboardComposer.ts new file mode 100644 index 0000000..d47fc11 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/score/Game2GetWeeklyLeaderboardComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class Game2GetWeeklyLeaderboardComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k:number, _arg_2:number, _arg_3:number, _arg_4:number, _arg_5:number, _arg_6:number) + { + this._data = [ k, _arg_2, _arg_3, _arg_4, _arg_5, _arg_6 ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/score/GetWeeklyGameRewardComposer.ts b/packages/communication/src/messages/outgoing/game/score/GetWeeklyGameRewardComposer.ts new file mode 100644 index 0000000..eae9874 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/score/GetWeeklyGameRewardComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetWeeklyGameRewardComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/score/GetWeeklyGameRewardWinnersComposer.ts b/packages/communication/src/messages/outgoing/game/score/GetWeeklyGameRewardWinnersComposer.ts new file mode 100644 index 0000000..e604f42 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/score/GetWeeklyGameRewardWinnersComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetWeeklyGameRewardWinnersComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/game/score/index.ts b/packages/communication/src/messages/outgoing/game/score/index.ts new file mode 100644 index 0000000..96ea0b1 --- /dev/null +++ b/packages/communication/src/messages/outgoing/game/score/index.ts @@ -0,0 +1,4 @@ +export * from './Game2GetWeeklyFriendsLeaderboardComposer'; +export * from './Game2GetWeeklyLeaderboardComposer'; +export * from './GetWeeklyGameRewardComposer'; +export * from './GetWeeklyGameRewardWinnersComposer'; diff --git a/packages/communication/src/messages/outgoing/gifts/GetGiftMessageComposer.ts b/packages/communication/src/messages/outgoing/gifts/GetGiftMessageComposer.ts new file mode 100644 index 0000000..398a9e7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/gifts/GetGiftMessageComposer.ts @@ -0,0 +1,23 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetGiftMessageComposer implements IMessageComposer> +{ + public static readonly NO_ISSUE_ID = -1; + + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/gifts/ResetPhoneNumberStateMessageComposer.ts b/packages/communication/src/messages/outgoing/gifts/ResetPhoneNumberStateMessageComposer.ts new file mode 100644 index 0000000..0ffd305 --- /dev/null +++ b/packages/communication/src/messages/outgoing/gifts/ResetPhoneNumberStateMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ResetPhoneNumberStateMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/gifts/SetPhoneNumberVerificationStatusMessageComposer.ts b/packages/communication/src/messages/outgoing/gifts/SetPhoneNumberVerificationStatusMessageComposer.ts new file mode 100644 index 0000000..5842bfd --- /dev/null +++ b/packages/communication/src/messages/outgoing/gifts/SetPhoneNumberVerificationStatusMessageComposer.ts @@ -0,0 +1,23 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SetPhoneNumberVerificationStatusMessageComposer implements IMessageComposer> +{ + public static readonly NO_ISSUE_ID = -1; + + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/gifts/TryPhoneNumberMessageComposer.ts b/packages/communication/src/messages/outgoing/gifts/TryPhoneNumberMessageComposer.ts new file mode 100644 index 0000000..94d7f62 --- /dev/null +++ b/packages/communication/src/messages/outgoing/gifts/TryPhoneNumberMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TryPhoneNumberMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string, _arg_2: string) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/gifts/VerifyCodeMessageComposer.ts b/packages/communication/src/messages/outgoing/gifts/VerifyCodeMessageComposer.ts new file mode 100644 index 0000000..38ff10c --- /dev/null +++ b/packages/communication/src/messages/outgoing/gifts/VerifyCodeMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class VerifyCodeMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/gifts/index.ts b/packages/communication/src/messages/outgoing/gifts/index.ts new file mode 100644 index 0000000..daa097b --- /dev/null +++ b/packages/communication/src/messages/outgoing/gifts/index.ts @@ -0,0 +1,5 @@ +export * from './GetGiftMessageComposer'; +export * from './ResetPhoneNumberStateMessageComposer'; +export * from './SetPhoneNumberVerificationStatusMessageComposer'; +export * from './TryPhoneNumberMessageComposer'; +export * from './VerifyCodeMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/group/ApproveAllMembershipRequestsMessageComposer.ts b/packages/communication/src/messages/outgoing/group/ApproveAllMembershipRequestsMessageComposer.ts new file mode 100644 index 0000000..44f230e --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/ApproveAllMembershipRequestsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ApproveAllMembershipRequestsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number) + { + this._data = [groupId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupAdminGiveComposer.ts b/packages/communication/src/messages/outgoing/group/GroupAdminGiveComposer.ts new file mode 100644 index 0000000..881472e --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupAdminGiveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupAdminTakeComposer.ts b/packages/communication/src/messages/outgoing/group/GroupAdminTakeComposer.ts new file mode 100644 index 0000000..0af0f2c --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupAdminTakeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupBadgePartsComposer.ts b/packages/communication/src/messages/outgoing/group/GroupBadgePartsComposer.ts new file mode 100644 index 0000000..7291bb4 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupBadgePartsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GroupBadgePartsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupBuyComposer.ts b/packages/communication/src/messages/outgoing/group/GroupBuyComposer.ts new file mode 100644 index 0000000..4a64015 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupBuyComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/group/GroupBuyDataComposer.ts b/packages/communication/src/messages/outgoing/group/GroupBuyDataComposer.ts new file mode 100644 index 0000000..3922458 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupBuyDataComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GroupBuyDataComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupConfirmRemoveMemberComposer.ts b/packages/communication/src/messages/outgoing/group/GroupConfirmRemoveMemberComposer.ts new file mode 100644 index 0000000..ac57bdd --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupConfirmRemoveMemberComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupDeleteComposer.ts b/packages/communication/src/messages/outgoing/group/GroupDeleteComposer.ts new file mode 100644 index 0000000..7c051ae --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupDeleteComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GroupDeleteComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number) + { + this._data = [groupId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupFavoriteComposer.ts b/packages/communication/src/messages/outgoing/group/GroupFavoriteComposer.ts new file mode 100644 index 0000000..f875a24 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupFavoriteComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GroupFavoriteComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number) + { + this._data = [groupId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupInformationComposer.ts b/packages/communication/src/messages/outgoing/group/GroupInformationComposer.ts new file mode 100644 index 0000000..02940b3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupInformationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupJoinComposer.ts b/packages/communication/src/messages/outgoing/group/GroupJoinComposer.ts new file mode 100644 index 0000000..0c970e0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupJoinComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GroupJoinComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number) + { + this._data = [groupId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupMembersComposer.ts b/packages/communication/src/messages/outgoing/group/GroupMembersComposer.ts new file mode 100644 index 0000000..bed05fa --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupMembersComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupMembershipAcceptComposer.ts b/packages/communication/src/messages/outgoing/group/GroupMembershipAcceptComposer.ts new file mode 100644 index 0000000..808064b --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupMembershipAcceptComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupMembershipDeclineComposer.ts b/packages/communication/src/messages/outgoing/group/GroupMembershipDeclineComposer.ts new file mode 100644 index 0000000..1f0e371 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupMembershipDeclineComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupRemoveMemberComposer.ts b/packages/communication/src/messages/outgoing/group/GroupRemoveMemberComposer.ts new file mode 100644 index 0000000..7686efa --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupRemoveMemberComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/group/GroupSaveBadgeComposer.ts b/packages/communication/src/messages/outgoing/group/GroupSaveBadgeComposer.ts new file mode 100644 index 0000000..20f2fc7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupSaveBadgeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/group/GroupSaveColorsComposer.ts b/packages/communication/src/messages/outgoing/group/GroupSaveColorsComposer.ts new file mode 100644 index 0000000..9b04b9a --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupSaveColorsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/group/GroupSaveInformationComposer.ts b/packages/communication/src/messages/outgoing/group/GroupSaveInformationComposer.ts new file mode 100644 index 0000000..c21a740 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupSaveInformationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/group/GroupSavePreferencesComposer.ts b/packages/communication/src/messages/outgoing/group/GroupSavePreferencesComposer.ts new file mode 100644 index 0000000..173102c --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupSavePreferencesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/group/GroupSettingsComposer.ts b/packages/communication/src/messages/outgoing/group/GroupSettingsComposer.ts new file mode 100644 index 0000000..bede058 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupSettingsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/group/GroupUnfavoriteComposer.ts b/packages/communication/src/messages/outgoing/group/GroupUnfavoriteComposer.ts new file mode 100644 index 0000000..72177fd --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/GroupUnfavoriteComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GroupUnfavoriteComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number) + { + this._data = [groupId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/group/index.ts b/packages/communication/src/messages/outgoing/group/index.ts new file mode 100644 index 0000000..d8c14a2 --- /dev/null +++ b/packages/communication/src/messages/outgoing/group/index.ts @@ -0,0 +1,21 @@ +export * from './ApproveAllMembershipRequestsMessageComposer'; +export * from './GroupAdminGiveComposer'; +export * from './GroupAdminTakeComposer'; +export * from './GroupBadgePartsComposer'; +export * from './GroupBuyComposer'; +export * from './GroupBuyDataComposer'; +export * from './GroupConfirmRemoveMemberComposer'; +export * from './GroupDeleteComposer'; +export * from './GroupFavoriteComposer'; +export * from './GroupInformationComposer'; +export * from './GroupJoinComposer'; +export * from './GroupMembersComposer'; +export * from './GroupMembershipAcceptComposer'; +export * from './GroupMembershipDeclineComposer'; +export * from './GroupRemoveMemberComposer'; +export * from './GroupSaveBadgeComposer'; +export * from './GroupSaveColorsComposer'; +export * from './GroupSaveInformationComposer'; +export * from './GroupSavePreferencesComposer'; +export * from './GroupSettingsComposer'; +export * from './GroupUnfavoriteComposer'; diff --git a/packages/communication/src/messages/outgoing/groupforums/GetForumStatsMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/GetForumStatsMessageComposer.ts new file mode 100644 index 0000000..5e7daf6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/GetForumStatsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetForumStatsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/GetForumsListMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/GetForumsListMessageComposer.ts new file mode 100644 index 0000000..7df78d7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/GetForumsListMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetForumsListMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number) + { + this._data = [k, _arg_2, _arg_3]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/GetMessagesMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/GetMessagesMessageComposer.ts new file mode 100644 index 0000000..b5f1dec --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/GetMessagesMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetMessagesMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number) + { + this._data = [k, _arg_2, _arg_3, _arg_4]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/GetThreadMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/GetThreadMessageComposer.ts new file mode 100644 index 0000000..5e5e507 --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/GetThreadMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetThreadMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/GetThreadsMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/GetThreadsMessageComposer.ts new file mode 100644 index 0000000..54ff560 --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/GetThreadsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetThreadsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number) + { + this._data = [k, _arg_2, _arg_3]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/GetUnreadForumsCountMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/GetUnreadForumsCountMessageComposer.ts new file mode 100644 index 0000000..db41d8d --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/GetUnreadForumsCountMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetUnreadForumsCountMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/ModerateMessageMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/ModerateMessageMessageComposer.ts new file mode 100644 index 0000000..316bc25 --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/ModerateMessageMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ModerateMessageMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number) + { + this._data = [k, _arg_2, _arg_3, _arg_4]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/ModerateThreadMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/ModerateThreadMessageComposer.ts new file mode 100644 index 0000000..5fd5a4e --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/ModerateThreadMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ModerateThreadMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number) + { + this._data = [k, _arg_2, _arg_3]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/PostMessageMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/PostMessageMessageComposer.ts new file mode 100644 index 0000000..f358a08 --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/PostMessageMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PostMessageMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: string, _arg_4: string) + { + this._data = [k, _arg_2, _arg_3, _arg_4]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/UpdateForumReadMarkerMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/UpdateForumReadMarkerMessageComposer.ts new file mode 100644 index 0000000..e147dda --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/UpdateForumReadMarkerMessageComposer.ts @@ -0,0 +1,33 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UpdateForumReadMarkerMessageComposer implements IMessageComposer +{ + private _data: any; + + constructor(...data: UpdateForumReadMarkerEntry[]) + { + this._data = [data.length]; + data.forEach(entry => + { + this._data.push(entry.k); + this._data.push(entry._arg_2); + this._data.push(entry._arg_3); + }); + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} + +export class UpdateForumReadMarkerEntry +{ + constructor(public k: number, public _arg_2: number, public _arg_3: boolean) + { } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/UpdateForumSettingsMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/UpdateForumSettingsMessageComposer.ts new file mode 100644 index 0000000..48650bf --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/UpdateForumSettingsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UpdateForumSettingsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: number) + { + this._data = [k, _arg_2, _arg_3, _arg_4, _arg_5]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/UpdateThreadMessageComposer.ts b/packages/communication/src/messages/outgoing/groupforums/UpdateThreadMessageComposer.ts new file mode 100644 index 0000000..f1f5efa --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/UpdateThreadMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UpdateThreadMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: boolean, _arg_4: boolean) + { + this._data = [k, _arg_2, _arg_4, _arg_3]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/groupforums/index.ts b/packages/communication/src/messages/outgoing/groupforums/index.ts new file mode 100644 index 0000000..fc1825b --- /dev/null +++ b/packages/communication/src/messages/outgoing/groupforums/index.ts @@ -0,0 +1,12 @@ +export * from './GetForumsListMessageComposer'; +export * from './GetForumStatsMessageComposer'; +export * from './GetMessagesMessageComposer'; +export * from './GetThreadMessageComposer'; +export * from './GetThreadsMessageComposer'; +export * from './GetUnreadForumsCountMessageComposer'; +export * from './ModerateMessageMessageComposer'; +export * from './ModerateThreadMessageComposer'; +export * from './PostMessageMessageComposer'; +export * from './UpdateForumReadMarkerMessageComposer'; +export * from './UpdateForumSettingsMessageComposer'; +export * from './UpdateThreadMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/handshake/AuthenticationMessageComposer.ts b/packages/communication/src/messages/outgoing/handshake/AuthenticationMessageComposer.ts new file mode 100644 index 0000000..0937096 --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/AuthenticationMessageComposer.ts @@ -0,0 +1,32 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class AuthenticationMessageComposer implements IMessageComposer +{ + private _type: string; + private _data: string[]; + + constructor(type: string, keys: string[], values: string[]) + { + this._type = type; + + if(keys.length !== values.length) return; + + this._data = []; + + for(let i = 0; i < keys.length; i++) + { + this._data.push(keys[i]); + this._data.push(values[i]); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/handshake/ClientHelloMessageComposer.ts b/packages/communication/src/messages/outgoing/handshake/ClientHelloMessageComposer.ts new file mode 100644 index 0000000..46b1ff1 --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/ClientHelloMessageComposer.ts @@ -0,0 +1,22 @@ +import { ClientDeviceCategoryEnum, ClientPlatformEnum, IMessageComposer } from '@nitrots/api'; +import { NitroVersion } from '@nitrots/utils'; + +export class ClientHelloMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(releaseVersion: string, type: string, platform: number, category: number) + { + this._data = [`NITRO-${NitroVersion.RENDERER_VERSION.replaceAll('.', '-')}`, 'HTML5', ClientPlatformEnum.HTML5, ClientDeviceCategoryEnum.BROWSER]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/handshake/CompleteDiffieHandshakeMessageComposer.ts b/packages/communication/src/messages/outgoing/handshake/CompleteDiffieHandshakeMessageComposer.ts new file mode 100644 index 0000000..1b84fc7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/CompleteDiffieHandshakeMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CompleteDiffieHandshakeMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(publicKey: string) + { + this._data = [publicKey]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/handshake/DisconnectMessageComposer.ts b/packages/communication/src/messages/outgoing/handshake/DisconnectMessageComposer.ts new file mode 100644 index 0000000..dd1b6a4 --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/DisconnectMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class DisconnectMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/handshake/InfoRetrieveMessageComposer.ts b/packages/communication/src/messages/outgoing/handshake/InfoRetrieveMessageComposer.ts new file mode 100644 index 0000000..68e79be --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/InfoRetrieveMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class InfoRetrieveMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/handshake/InitDiffieHandshakeMessageComposer.ts b/packages/communication/src/messages/outgoing/handshake/InitDiffieHandshakeMessageComposer.ts new file mode 100644 index 0000000..58e7231 --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/InitDiffieHandshakeMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class InitDiffieHandshakeMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/handshake/PongMessageComposer.ts b/packages/communication/src/messages/outgoing/handshake/PongMessageComposer.ts new file mode 100644 index 0000000..7508851 --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/PongMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PongMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/handshake/SSOTicketMessageComposer.ts b/packages/communication/src/messages/outgoing/handshake/SSOTicketMessageComposer.ts new file mode 100644 index 0000000..0d6d8df --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/SSOTicketMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SSOTicketMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(ticket: string, time: number) + { + this._data = [ticket, time]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/handshake/UniqueIDMessageComposer.ts b/packages/communication/src/messages/outgoing/handshake/UniqueIDMessageComposer.ts new file mode 100644 index 0000000..4d9c5fb --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/UniqueIDMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UniqueIDMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(machineId: string, fingerprint: string, flashVersion: string) + { + this._data = [machineId, fingerprint, flashVersion]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/handshake/VersionCheckMessageComposer.ts b/packages/communication/src/messages/outgoing/handshake/VersionCheckMessageComposer.ts new file mode 100644 index 0000000..8399469 --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/VersionCheckMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class VersionCheckMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(clientID: number, clientURL: string, externalVariablesURL: string) + { + this._data = [clientID, clientURL, externalVariablesURL]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/handshake/index.ts b/packages/communication/src/messages/outgoing/handshake/index.ts new file mode 100644 index 0000000..4dc6ada --- /dev/null +++ b/packages/communication/src/messages/outgoing/handshake/index.ts @@ -0,0 +1,10 @@ +export * from './AuthenticationMessageComposer'; +export * from './ClientHelloMessageComposer'; +export * from './CompleteDiffieHandshakeMessageComposer'; +export * from './DisconnectMessageComposer'; +export * from './InfoRetrieveMessageComposer'; +export * from './InitDiffieHandshakeMessageComposer'; +export * from './PongMessageComposer'; +export * from './SSOTicketMessageComposer'; +export * from './UniqueIDMessageComposer'; +export * from './VersionCheckMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/help/CallForHelpFromForumMessageMessageComposer.ts b/packages/communication/src/messages/outgoing/help/CallForHelpFromForumMessageMessageComposer.ts new file mode 100644 index 0000000..3bb059e --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/CallForHelpFromForumMessageMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CallForHelpFromForumMessageMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: string) + { + this._data = [k, _arg_2, _arg_3, _arg_4, _arg_5]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/CallForHelpFromForumThreadMessageComposer.ts b/packages/communication/src/messages/outgoing/help/CallForHelpFromForumThreadMessageComposer.ts new file mode 100644 index 0000000..f34441d --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/CallForHelpFromForumThreadMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CallForHelpFromForumThreadMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: string) + { + this._data = [k, _arg_2, _arg_3, _arg_4]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/CallForHelpFromIMMessageComposer.ts b/packages/communication/src/messages/outgoing/help/CallForHelpFromIMMessageComposer.ts new file mode 100644 index 0000000..627635a --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/CallForHelpFromIMMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CallForHelpFromIMMessageComposer implements IMessageComposer +{ + private _data: any; + + constructor(message: string, topicId: number, reportedUserId: number, chatEntries: (string | number)[]) + { + this._data = [message, topicId, reportedUserId, chatEntries.length / 2, ...chatEntries]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/CallForHelpFromPhotoMessageComposer.ts b/packages/communication/src/messages/outgoing/help/CallForHelpFromPhotoMessageComposer.ts new file mode 100644 index 0000000..7069e1c --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/CallForHelpFromPhotoMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CallForHelpFromPhotoMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(extraData: string, roomId: number, reportedUserId: number, topicId: number, roomObjectId: number) + { + this._data = [extraData, roomId, reportedUserId, topicId, roomObjectId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/CallForHelpFromSelfieMessageComposer.ts b/packages/communication/src/messages/outgoing/help/CallForHelpFromSelfieMessageComposer.ts new file mode 100644 index 0000000..bf4997b --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/CallForHelpFromSelfieMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CallForHelpFromSelfieMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string, _arg_2: number, _arg_3: number, _arg_4: string, _arg_5: number) + { + this._data = [k, _arg_2, _arg_3, _arg_4, _arg_5]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/CallForHelpMessageComposer.ts b/packages/communication/src/messages/outgoing/help/CallForHelpMessageComposer.ts new file mode 100644 index 0000000..593237e --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/CallForHelpMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CallForHelpMessageComposer implements IMessageComposer +{ + private _data: any; + + constructor(message: string, topicIndex: number, reportedUserId: number, reportedRoomId: number, chatEntries: (string | number)[]) + { + this._data = [message, topicIndex, reportedUserId, reportedRoomId, chatEntries.length / 2, ...chatEntries]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/ChatReviewGuideDecidesOnOfferMessageComposer.ts b/packages/communication/src/messages/outgoing/help/ChatReviewGuideDecidesOnOfferMessageComposer.ts new file mode 100644 index 0000000..bddbe93 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/ChatReviewGuideDecidesOnOfferMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ChatReviewGuideDecidesOnOfferMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: boolean) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/ChatReviewGuideDetachedMessageComposer.ts b/packages/communication/src/messages/outgoing/help/ChatReviewGuideDetachedMessageComposer.ts new file mode 100644 index 0000000..0968d67 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/ChatReviewGuideDetachedMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ChatReviewGuideDetachedMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/ChatReviewGuideVoteMessageComposer.ts b/packages/communication/src/messages/outgoing/help/ChatReviewGuideVoteMessageComposer.ts new file mode 100644 index 0000000..4545f64 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/ChatReviewGuideVoteMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ChatReviewGuideVoteMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/ChatReviewSessionCreateMessageComposer.ts b/packages/communication/src/messages/outgoing/help/ChatReviewSessionCreateMessageComposer.ts new file mode 100644 index 0000000..a7866b4 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/ChatReviewSessionCreateMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ChatReviewSessionCreateMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/DeletePendingCallsForHelpMessageComposer.ts b/packages/communication/src/messages/outgoing/help/DeletePendingCallsForHelpMessageComposer.ts new file mode 100644 index 0000000..7e0f157 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/DeletePendingCallsForHelpMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class DeletePendingCallsForHelpMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GetCfhStatusMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GetCfhStatusMessageComposer.ts new file mode 100644 index 0000000..333f185 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GetCfhStatusMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCfhStatusMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: boolean) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GetFaqCategoryMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GetFaqCategoryMessageComposer.ts new file mode 100644 index 0000000..f00f066 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GetFaqCategoryMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetFaqCategoryMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(categoryId: number) + { + this._data = [categoryId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GetFaqTextMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GetFaqTextMessageComposer.ts new file mode 100644 index 0000000..4ebad2b --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GetFaqTextMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetFaqTextMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(questionId: number) + { + this._data = [questionId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GetGuideReportingStatusMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GetGuideReportingStatusMessageComposer.ts new file mode 100644 index 0000000..6ba0f17 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GetGuideReportingStatusMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetGuideReportingStatusMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GetPendingCallsForHelpMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GetPendingCallsForHelpMessageComposer.ts new file mode 100644 index 0000000..574863d --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GetPendingCallsForHelpMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetPendingCallsForHelpMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GetQuizQuestionsComposer.ts b/packages/communication/src/messages/outgoing/help/GetQuizQuestionsComposer.ts new file mode 100644 index 0000000..b893303 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GetQuizQuestionsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetQuizQuestionsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionCreateMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionCreateMessageComposer.ts new file mode 100644 index 0000000..f006273 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionCreateMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionCreateMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: string) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionFeedbackMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionFeedbackMessageComposer.ts new file mode 100644 index 0000000..040c7de --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionFeedbackMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionFeedbackMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: boolean) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionGetRequesterRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionGetRequesterRoomMessageComposer.ts new file mode 100644 index 0000000..888d1ff --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionGetRequesterRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionGetRequesterRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionGuideDecidesMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionGuideDecidesMessageComposer.ts new file mode 100644 index 0000000..caa6647 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionGuideDecidesMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionGuideDecidesMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: boolean) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionInviteRequesterMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionInviteRequesterMessageComposer.ts new file mode 100644 index 0000000..68628a2 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionInviteRequesterMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionInviteRequesterMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionIsTypingMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionIsTypingMessageComposer.ts new file mode 100644 index 0000000..05de66f --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionIsTypingMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionIsTypingMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: boolean) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionMessageMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionMessageMessageComposer.ts new file mode 100644 index 0000000..6d1dee9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionMessageMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionMessageMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionOnDutyUpdateMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionOnDutyUpdateMessageComposer.ts new file mode 100644 index 0000000..2b2ec78 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionOnDutyUpdateMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionOnDutyUpdateMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: boolean, _arg_2: boolean, _arg_3: boolean, _arg_4: boolean) + { + this._data = [k, _arg_2, _arg_3, _arg_4]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionReportMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionReportMessageComposer.ts new file mode 100644 index 0000000..ffb4c7a --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionReportMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionReportMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionRequesterCancelsMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionRequesterCancelsMessageComposer.ts new file mode 100644 index 0000000..4a60b4c --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionRequesterCancelsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionRequesterCancelsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/GuideSessionResolvedMessageComposer.ts b/packages/communication/src/messages/outgoing/help/GuideSessionResolvedMessageComposer.ts new file mode 100644 index 0000000..1164847 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/GuideSessionResolvedMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuideSessionResolvedMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/PostQuizAnswersComposer.ts b/packages/communication/src/messages/outgoing/help/PostQuizAnswersComposer.ts new file mode 100644 index 0000000..341984f --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/PostQuizAnswersComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PostQuizAnswersComposer implements IMessageComposer +{ + private _data: any; + + constructor(quizCode: string, answerIds: number[]) + { + this._data = [quizCode, answerIds.length, ...answerIds]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/SearchFaqsMessageComposer.ts b/packages/communication/src/messages/outgoing/help/SearchFaqsMessageComposer.ts new file mode 100644 index 0000000..82f5073 --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/SearchFaqsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SearchFaqsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/help/index.ts b/packages/communication/src/messages/outgoing/help/index.ts new file mode 100644 index 0000000..9824e8c --- /dev/null +++ b/packages/communication/src/messages/outgoing/help/index.ts @@ -0,0 +1,30 @@ +export * from './CallForHelpFromForumMessageMessageComposer'; +export * from './CallForHelpFromForumThreadMessageComposer'; +export * from './CallForHelpFromIMMessageComposer'; +export * from './CallForHelpFromPhotoMessageComposer'; +export * from './CallForHelpFromSelfieMessageComposer'; +export * from './CallForHelpMessageComposer'; +export * from './ChatReviewGuideDecidesOnOfferMessageComposer'; +export * from './ChatReviewGuideDetachedMessageComposer'; +export * from './ChatReviewGuideVoteMessageComposer'; +export * from './ChatReviewSessionCreateMessageComposer'; +export * from './DeletePendingCallsForHelpMessageComposer'; +export * from './GetCfhStatusMessageComposer'; +export * from './GetFaqCategoryMessageComposer'; +export * from './GetFaqTextMessageComposer'; +export * from './GetGuideReportingStatusMessageComposer'; +export * from './GetPendingCallsForHelpMessageComposer'; +export * from './GetQuizQuestionsComposer'; +export * from './GuideSessionCreateMessageComposer'; +export * from './GuideSessionFeedbackMessageComposer'; +export * from './GuideSessionGetRequesterRoomMessageComposer'; +export * from './GuideSessionGuideDecidesMessageComposer'; +export * from './GuideSessionInviteRequesterMessageComposer'; +export * from './GuideSessionIsTypingMessageComposer'; +export * from './GuideSessionMessageMessageComposer'; +export * from './GuideSessionOnDutyUpdateMessageComposer'; +export * from './GuideSessionReportMessageComposer'; +export * from './GuideSessionRequesterCancelsMessageComposer'; +export * from './GuideSessionResolvedMessageComposer'; +export * from './PostQuizAnswersComposer'; +export * from './SearchFaqsMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/index.ts b/packages/communication/src/messages/outgoing/index.ts new file mode 100644 index 0000000..4e36160 --- /dev/null +++ b/packages/communication/src/messages/outgoing/index.ts @@ -0,0 +1,74 @@ +export * from './OutgoingHeader'; +export * from './advertisement'; +export * from './avatar'; +export * from './camera'; +export * from './campaign'; +export * from './catalog'; +export * from './competition'; +export * from './crafting'; +export * from './desktop'; +export * from './friendfurni'; +export * from './friendlist'; +export * from './game'; +export * from './game/arena'; +export * from './game/directory'; +export * from './game/ingame'; +export * from './game/lobby'; +export * from './game/score'; +export * from './gifts'; +export * from './group'; +export * from './groupforums'; +export * from './handshake'; +export * from './help'; +export * from './inventory'; +export * from './inventory/avatareffect'; +export * from './inventory/badges'; +export * from './inventory/bots'; +export * from './inventory/furni'; +export * from './inventory/pets'; +export * from './inventory/trading'; +export * from './inventory/unseen'; +export * from './landingview'; +export * from './landingview/votes'; +export * from './marketplace'; +export * from './moderation'; +export * from './mysterybox'; +export * from './navigator'; +export * from './nux'; +export * from './pet'; +export * from './poll'; +export * from './quest'; +export * from './recycler'; +export * from './room'; +export * from './room/access'; +export * from './room/action'; +export * from './room/bots'; +export * from './room/data'; +export * from './room/engine'; +export * from './room/furniture'; +export * from './room/furniture/dimmer'; +export * from './room/furniture/floor'; +export * from './room/furniture/logic'; +export * from './room/furniture/mannequin'; +export * from './room/furniture/presents'; +export * from './room/furniture/toner'; +export * from './room/furniture/wall'; +export * from './room/furniture/youtube'; +export * from './room/layout'; +export * from './room/pets'; +export * from './room/session'; +export * from './room/unit'; +export * from './room/unit/chat'; +export * from './roomdirectory'; +export * from './roomevents'; +export * from './roomsettings'; +export * from './sound'; +export * from './talent'; +export * from './tracking'; +export * from './user'; +export * from './user/data'; +export * from './user/inventory'; +export * from './user/inventory/currency'; +export * from './user/inventory/subscription'; +export * from './user/settings'; +export * from './userclassification'; diff --git a/packages/communication/src/messages/outgoing/inventory/avatareffect/AvatarEffectActivatedComposer.ts b/packages/communication/src/messages/outgoing/inventory/avatareffect/AvatarEffectActivatedComposer.ts new file mode 100644 index 0000000..d4f6f54 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/avatareffect/AvatarEffectActivatedComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class AvatarEffectActivatedComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(type: number) + { + this._data = [ type ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/avatareffect/AvatarEffectSelectedComposer.ts b/packages/communication/src/messages/outgoing/inventory/avatareffect/AvatarEffectSelectedComposer.ts new file mode 100644 index 0000000..40dd157 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/avatareffect/AvatarEffectSelectedComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class AvatarEffectSelectedComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(type: number) + { + this._data = [ type ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/avatareffect/index.ts b/packages/communication/src/messages/outgoing/inventory/avatareffect/index.ts new file mode 100644 index 0000000..f03f144 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/avatareffect/index.ts @@ -0,0 +1,2 @@ +export * from './AvatarEffectActivatedComposer'; +export * from './AvatarEffectSelectedComposer'; diff --git a/packages/communication/src/messages/outgoing/inventory/badges/GetBadgePointLimitsComposer.ts b/packages/communication/src/messages/outgoing/inventory/badges/GetBadgePointLimitsComposer.ts new file mode 100644 index 0000000..0fc527b --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/badges/GetBadgePointLimitsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetBadgePointLimitsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = [ ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/badges/GetIsBadgeRequestFulfilledComposer.ts b/packages/communication/src/messages/outgoing/inventory/badges/GetIsBadgeRequestFulfilledComposer.ts new file mode 100644 index 0000000..348a890 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/badges/GetIsBadgeRequestFulfilledComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetIsBadgeRequestFulfilledComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/badges/RequestABadgeComposer.ts b/packages/communication/src/messages/outgoing/inventory/badges/RequestABadgeComposer.ts new file mode 100644 index 0000000..cac7185 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/badges/RequestABadgeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RequestABadgeComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(requestCode: string) + { + this._data = [ requestCode ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/badges/RequestBadgesComposer.ts b/packages/communication/src/messages/outgoing/inventory/badges/RequestBadgesComposer.ts new file mode 100644 index 0000000..1d5de2a --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/badges/RequestBadgesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RequestBadgesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/badges/SetActivatedBadgesComposer.ts b/packages/communication/src/messages/outgoing/inventory/badges/SetActivatedBadgesComposer.ts new file mode 100644 index 0000000..7c91be5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/badges/SetActivatedBadgesComposer.ts @@ -0,0 +1,29 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SetActivatedBadgesComposer implements IMessageComposer +{ + private _badges: string[] = []; + + public getMessageArray() + { + const data = []; + + for(let i = 1; i <= this._badges.length; i++) + { + data.push(i); + data.push(this._badges[i - 1]); + } + + return data; + } + + public dispose(): void + { + return; + } + + public addActivatedBadge(badge: string): void + { + this._badges.push(badge); + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/badges/index.ts b/packages/communication/src/messages/outgoing/inventory/badges/index.ts new file mode 100644 index 0000000..a29bc57 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/badges/index.ts @@ -0,0 +1,5 @@ +export * from './GetBadgePointLimitsComposer'; +export * from './GetIsBadgeRequestFulfilledComposer'; +export * from './RequestABadgeComposer'; +export * from './RequestBadgesComposer'; +export * from './SetActivatedBadgesComposer'; diff --git a/packages/communication/src/messages/outgoing/inventory/bots/GetBotInventoryComposer.ts b/packages/communication/src/messages/outgoing/inventory/bots/GetBotInventoryComposer.ts new file mode 100644 index 0000000..28fd50d --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/bots/GetBotInventoryComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetBotInventoryComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/bots/index.ts b/packages/communication/src/messages/outgoing/inventory/bots/index.ts new file mode 100644 index 0000000..bab9f59 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/bots/index.ts @@ -0,0 +1 @@ +export * from './GetBotInventoryComposer'; diff --git a/packages/communication/src/messages/outgoing/inventory/furni/FurnitureListComposer.ts b/packages/communication/src/messages/outgoing/inventory/furni/FurnitureListComposer.ts new file mode 100644 index 0000000..81e5d9e --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/furni/FurnitureListComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FurnitureListComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/furni/RequestFurniInventoryWhenNotInRoomComposer.ts b/packages/communication/src/messages/outgoing/inventory/furni/RequestFurniInventoryWhenNotInRoomComposer.ts new file mode 100644 index 0000000..8360547 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/furni/RequestFurniInventoryWhenNotInRoomComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RequestFurniInventoryWhenNotInRoomComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/furni/index.ts b/packages/communication/src/messages/outgoing/inventory/furni/index.ts new file mode 100644 index 0000000..9e0a8f7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/furni/index.ts @@ -0,0 +1,2 @@ +export * from './FurnitureListComposer'; +export * from './RequestFurniInventoryWhenNotInRoomComposer'; diff --git a/packages/communication/src/messages/outgoing/inventory/index.ts b/packages/communication/src/messages/outgoing/inventory/index.ts new file mode 100644 index 0000000..4fc8506 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/index.ts @@ -0,0 +1,7 @@ +export * from './avatareffect'; +export * from './badges'; +export * from './bots'; +export * from './furni'; +export * from './pets'; +export * from './trading'; +export * from './unseen'; diff --git a/packages/communication/src/messages/outgoing/inventory/pets/CancelPetBreedingComposer.ts b/packages/communication/src/messages/outgoing/inventory/pets/CancelPetBreedingComposer.ts new file mode 100644 index 0000000..c23c971 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/pets/CancelPetBreedingComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CancelPetBreedingComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/pets/ConfirmPetBreedingComposer.ts b/packages/communication/src/messages/outgoing/inventory/pets/ConfirmPetBreedingComposer.ts new file mode 100644 index 0000000..aeb4275 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/pets/ConfirmPetBreedingComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ConfirmPetBreedingComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, name: string, petOneId: number, petTwoId: number) + { + this._data = [itemId, name, petOneId, petTwoId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/pets/RequestPetsComposer.ts b/packages/communication/src/messages/outgoing/inventory/pets/RequestPetsComposer.ts new file mode 100644 index 0000000..e3fafdf --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/pets/RequestPetsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RequestPetsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/pets/index.ts b/packages/communication/src/messages/outgoing/inventory/pets/index.ts new file mode 100644 index 0000000..af32d91 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/pets/index.ts @@ -0,0 +1,3 @@ +export * from './CancelPetBreedingComposer'; +export * from './ConfirmPetBreedingComposer'; +export * from './RequestPetsComposer'; diff --git a/packages/communication/src/messages/outgoing/inventory/trading/TradingAcceptComposer.ts b/packages/communication/src/messages/outgoing/inventory/trading/TradingAcceptComposer.ts new file mode 100644 index 0000000..05a3daa --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/trading/TradingAcceptComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TradingAcceptComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/trading/TradingCancelComposer.ts b/packages/communication/src/messages/outgoing/inventory/trading/TradingCancelComposer.ts new file mode 100644 index 0000000..facdde3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/trading/TradingCancelComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TradingCancelComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/trading/TradingCloseComposer.ts b/packages/communication/src/messages/outgoing/inventory/trading/TradingCloseComposer.ts new file mode 100644 index 0000000..5f701a5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/trading/TradingCloseComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TradingCloseComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/trading/TradingConfirmationComposer.ts b/packages/communication/src/messages/outgoing/inventory/trading/TradingConfirmationComposer.ts new file mode 100644 index 0000000..62a7f44 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/trading/TradingConfirmationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TradingConfirmationComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/trading/TradingListAddItemComposer.ts b/packages/communication/src/messages/outgoing/inventory/trading/TradingListAddItemComposer.ts new file mode 100644 index 0000000..30fe5ca --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/trading/TradingListAddItemComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TradingListAddItemComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/trading/TradingListAddItemsComposer.ts b/packages/communication/src/messages/outgoing/inventory/trading/TradingListAddItemsComposer.ts new file mode 100644 index 0000000..acecc86 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/trading/TradingListAddItemsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/trading/TradingListRemoveItemComposer.ts b/packages/communication/src/messages/outgoing/inventory/trading/TradingListRemoveItemComposer.ts new file mode 100644 index 0000000..6e87da8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/trading/TradingListRemoveItemComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TradingListItemRemoveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/trading/TradingOpenComposer.ts b/packages/communication/src/messages/outgoing/inventory/trading/TradingOpenComposer.ts new file mode 100644 index 0000000..7a961c9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/trading/TradingOpenComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TradingOpenComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/trading/TradingUnacceptComposer.ts b/packages/communication/src/messages/outgoing/inventory/trading/TradingUnacceptComposer.ts new file mode 100644 index 0000000..ca9bb77 --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/trading/TradingUnacceptComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TradingUnacceptComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/trading/index.ts b/packages/communication/src/messages/outgoing/inventory/trading/index.ts new file mode 100644 index 0000000..6f850eb --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/trading/index.ts @@ -0,0 +1,9 @@ +export * from './TradingAcceptComposer'; +export * from './TradingCancelComposer'; +export * from './TradingCloseComposer'; +export * from './TradingConfirmationComposer'; +export * from './TradingListAddItemComposer'; +export * from './TradingListAddItemsComposer'; +export * from './TradingListRemoveItemComposer'; +export * from './TradingOpenComposer'; +export * from './TradingUnacceptComposer'; diff --git a/packages/communication/src/messages/outgoing/inventory/unseen/UnseenResetCategoryComposer.ts b/packages/communication/src/messages/outgoing/inventory/unseen/UnseenResetCategoryComposer.ts new file mode 100644 index 0000000..5ff0d0e --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/unseen/UnseenResetCategoryComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UnseenResetCategoryComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(category: number) + { + this._data = [category]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/unseen/UnseenResetItemsComposer.ts b/packages/communication/src/messages/outgoing/inventory/unseen/UnseenResetItemsComposer.ts new file mode 100644 index 0000000..99ea8bf --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/unseen/UnseenResetItemsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UnseenResetItemsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(category: number, ...itemIds: number[]) + { + this._data = [category, itemIds.length, ...itemIds]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/inventory/unseen/index.ts b/packages/communication/src/messages/outgoing/inventory/unseen/index.ts new file mode 100644 index 0000000..52f1b4e --- /dev/null +++ b/packages/communication/src/messages/outgoing/inventory/unseen/index.ts @@ -0,0 +1,2 @@ +export * from './UnseenResetCategoryComposer'; +export * from './UnseenResetItemsComposer'; diff --git a/packages/communication/src/messages/outgoing/landingview/GetPromoArticlesComposer.ts b/packages/communication/src/messages/outgoing/landingview/GetPromoArticlesComposer.ts new file mode 100644 index 0000000..8a7bbf9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/landingview/GetPromoArticlesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetPromoArticlesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/landingview/index.ts b/packages/communication/src/messages/outgoing/landingview/index.ts new file mode 100644 index 0000000..9adfb30 --- /dev/null +++ b/packages/communication/src/messages/outgoing/landingview/index.ts @@ -0,0 +1,2 @@ +export * from './GetPromoArticlesComposer'; +export * from './votes'; diff --git a/packages/communication/src/messages/outgoing/landingview/votes/CommunityGoalVoteMessageComposer.ts b/packages/communication/src/messages/outgoing/landingview/votes/CommunityGoalVoteMessageComposer.ts new file mode 100644 index 0000000..48a652d --- /dev/null +++ b/packages/communication/src/messages/outgoing/landingview/votes/CommunityGoalVoteMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CommunityGoalVoteMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(voteOption: number) + { + this._data = [voteOption]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/landingview/votes/index.ts b/packages/communication/src/messages/outgoing/landingview/votes/index.ts new file mode 100644 index 0000000..ceaf9d7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/landingview/votes/index.ts @@ -0,0 +1 @@ +export * from './CommunityGoalVoteMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/marketplace/BuyMarketplaceOfferMessageComposer.ts b/packages/communication/src/messages/outgoing/marketplace/BuyMarketplaceOfferMessageComposer.ts new file mode 100644 index 0000000..b527684 --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/BuyMarketplaceOfferMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class BuyMarketplaceOfferMessageComposer 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/packages/communication/src/messages/outgoing/marketplace/BuyMarketplaceTokensMessageComposer.ts b/packages/communication/src/messages/outgoing/marketplace/BuyMarketplaceTokensMessageComposer.ts new file mode 100644 index 0000000..cdd1b9e --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/BuyMarketplaceTokensMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class BuyMarketplaceTokensMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/marketplace/CancelMarketplaceOfferMessageComposer.ts b/packages/communication/src/messages/outgoing/marketplace/CancelMarketplaceOfferMessageComposer.ts new file mode 100644 index 0000000..658115b --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/CancelMarketplaceOfferMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CancelMarketplaceOfferMessageComposer 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/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceCanMakeOfferComposer.ts b/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceCanMakeOfferComposer.ts new file mode 100644 index 0000000..773f0f0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceCanMakeOfferComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetMarketplaceCanMakeOfferComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceConfigurationMessageComposer.ts b/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceConfigurationMessageComposer.ts new file mode 100644 index 0000000..68f138a --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceConfigurationMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetMarketplaceConfigurationMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceItemStatsComposer.ts b/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceItemStatsComposer.ts new file mode 100644 index 0000000..f4365d2 --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceItemStatsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetMarketplaceItemStatsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(unknown: number, itemId: number) + { + this._data = [unknown, itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceOffersMessageComposer.ts b/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceOffersMessageComposer.ts new file mode 100644 index 0000000..fa08436 --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceOffersMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetMarketplaceOffersMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(min: number, max: number, query: string, type: number) + { + this._data = [min, max, query, type]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceOwnOffersMessageComposer.ts b/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceOwnOffersMessageComposer.ts new file mode 100644 index 0000000..8997f40 --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/GetMarketplaceOwnOffersMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetMarketplaceOwnOffersMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/marketplace/MakeOfferMessageComposer.ts b/packages/communication/src/messages/outgoing/marketplace/MakeOfferMessageComposer.ts new file mode 100644 index 0000000..62d5f47 --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/MakeOfferMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MakeOfferMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(credits: number, arg2: number, itemId: number) + { + this._data = [credits, arg2, itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/marketplace/RedeemMarketplaceOfferCreditsMessageComposer.ts b/packages/communication/src/messages/outgoing/marketplace/RedeemMarketplaceOfferCreditsMessageComposer.ts new file mode 100644 index 0000000..16f42e4 --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/RedeemMarketplaceOfferCreditsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RedeemMarketplaceOfferCreditsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/packages/communication/src/messages/outgoing/marketplace/index.ts b/packages/communication/src/messages/outgoing/marketplace/index.ts new file mode 100644 index 0000000..742161a --- /dev/null +++ b/packages/communication/src/messages/outgoing/marketplace/index.ts @@ -0,0 +1,10 @@ +export * from './BuyMarketplaceOfferMessageComposer'; +export * from './BuyMarketplaceTokensMessageComposer'; +export * from './CancelMarketplaceOfferMessageComposer'; +export * from './GetMarketplaceCanMakeOfferComposer'; +export * from './GetMarketplaceConfigurationMessageComposer'; +export * from './GetMarketplaceItemStatsComposer'; +export * from './GetMarketplaceOffersMessageComposer'; +export * from './GetMarketplaceOwnOffersMessageComposer'; +export * from './MakeOfferMessageComposer'; +export * from './RedeemMarketplaceOfferCreditsMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/moderation/CloseIssueDefaultActionMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/CloseIssueDefaultActionMessageComposer.ts new file mode 100644 index 0000000..59b58b6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/CloseIssueDefaultActionMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CloseIssueDefaultActionMessageComposer implements IMessageComposer +{ + private _data: number[]; + + constructor(k: number, issueIds: number[], _arg_2: number) + { + this._data = [k, issueIds.length, ...issueIds, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/CloseIssuesMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/CloseIssuesMessageComposer.ts new file mode 100644 index 0000000..26cd182 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/CloseIssuesMessageComposer.ts @@ -0,0 +1,25 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CloseIssuesMessageComposer implements IMessageComposer +{ + public static readonly RESOLUTION_USELESS = 1; + public static readonly RESOLUTION_ABUSIVE = 2; + public static readonly RESOLUTION_RESOLVED = 3; + + private _data: number[]; + + constructor(issueIds: number[], resolutionType: number) + { + this._data = [resolutionType, issueIds.length, ...issueIds]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/DefaultSanctionMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/DefaultSanctionMessageComposer.ts new file mode 100644 index 0000000..0cc9e3c --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/DefaultSanctionMessageComposer.ts @@ -0,0 +1,26 @@ +import { IMessageComposer } from '@nitrots/api'; +import { ModBanMessageComposer } from './ModBanMessageComposer'; + +export class DefaultSanctionMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: string, _arg_4: number = -1) + { + this._data = [k, _arg_2, _arg_3]; + if(_arg_4 != ModBanMessageComposer.NO_ISSUE_ID) + { + this._data.push(_arg_4); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/GetCfhChatlogMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/GetCfhChatlogMessageComposer.ts new file mode 100644 index 0000000..54b3251 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/GetCfhChatlogMessageComposer.ts @@ -0,0 +1,22 @@ +import { IMessageComposer } from '@nitrots/api'; + + +export class GetCfhChatlogMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(issueId: number) + { + this._data = [issueId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/GetModeratorRoomInfoMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/GetModeratorRoomInfoMessageComposer.ts new file mode 100644 index 0000000..cc094a2 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/GetModeratorRoomInfoMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetModeratorRoomInfoMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/GetModeratorUserInfoMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/GetModeratorUserInfoMessageComposer.ts new file mode 100644 index 0000000..bf48e63 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/GetModeratorUserInfoMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetModeratorUserInfoMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/GetRoomChatlogMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/GetRoomChatlogMessageComposer.ts new file mode 100644 index 0000000..a25c54b --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/GetRoomChatlogMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetRoomChatlogMessageComposer 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/packages/communication/src/messages/outgoing/moderation/GetRoomVisitsMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/GetRoomVisitsMessageComposer.ts new file mode 100644 index 0000000..aa44ea7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/GetRoomVisitsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetRoomVisitsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/GetUserChatlogMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/GetUserChatlogMessageComposer.ts new file mode 100644 index 0000000..8b52e27 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/GetUserChatlogMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetUserChatlogMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/ModAlertMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/ModAlertMessageComposer.ts new file mode 100644 index 0000000..ec1d786 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ModAlertMessageComposer.ts @@ -0,0 +1,26 @@ +import { IMessageComposer } from '@nitrots/api'; +import { ModBanMessageComposer } from './ModBanMessageComposer'; + +export class ModAlertMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, arg2: string, arg3: number, arg4: number = -1) + { + this._data = [k, arg2, arg3]; + if(arg4 != ModBanMessageComposer.NO_ISSUE_ID) + { + this._data.push(arg4); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/ModBanMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/ModBanMessageComposer.ts new file mode 100644 index 0000000..fd740e4 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ModBanMessageComposer.ts @@ -0,0 +1,27 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ModBanMessageComposer implements IMessageComposer> +{ + public static readonly NO_ISSUE_ID = -1; + + private _data: ConstructorParameters; + + constructor(k: number, arg2: string, arg3: number, arg4: number, arg5: boolean, arg6: number = -1) + { + this._data = [k, arg2, arg3, arg4, arg5]; + if(arg6 != ModBanMessageComposer.NO_ISSUE_ID) + { + this._data.push(arg6); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/ModKickMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/ModKickMessageComposer.ts new file mode 100644 index 0000000..12e0da9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ModKickMessageComposer.ts @@ -0,0 +1,27 @@ +import { IMessageComposer } from '@nitrots/api'; +import { ModBanMessageComposer } from './ModBanMessageComposer'; + +export class ModKickMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, arg2: string, arg3: number, arg4: number = -1) + { + this._data = [k, arg2, arg3]; + + if(arg4 != ModBanMessageComposer.NO_ISSUE_ID) + { + this._data.push(arg4); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/ModMessageMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/ModMessageMessageComposer.ts new file mode 100644 index 0000000..76b8be0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ModMessageMessageComposer.ts @@ -0,0 +1,30 @@ +import { IMessageComposer } from '@nitrots/api'; +import { ModBanMessageComposer } from './ModBanMessageComposer'; + +export class ModMessageMessageComposer 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(''); + this._data.push(''); + this._data.push(arg3); + if(arg4 != ModBanMessageComposer.NO_ISSUE_ID) + { + this._data.push(arg4); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/ModMuteMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/ModMuteMessageComposer.ts new file mode 100644 index 0000000..329fb2a --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ModMuteMessageComposer.ts @@ -0,0 +1,26 @@ +import { IMessageComposer } from '@nitrots/api'; +import { ModBanMessageComposer } from './ModBanMessageComposer'; + +export class ModMuteMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, arg2: string, arg3: number, arg4: number = -1) + { + this._data = [k, arg2, arg3]; + if(arg4 != ModBanMessageComposer.NO_ISSUE_ID) + { + this._data.push(arg4); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/ModToolPreferencesComposer.ts b/packages/communication/src/messages/outgoing/moderation/ModToolPreferencesComposer.ts new file mode 100644 index 0000000..6412491 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ModToolPreferencesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ModToolPreferencesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number) + { + this._data = [k, _arg_2, _arg_3, _arg_4]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/ModToolSanctionComposer.ts b/packages/communication/src/messages/outgoing/moderation/ModToolSanctionComposer.ts new file mode 100644 index 0000000..6bb9a71 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ModToolSanctionComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ModToolSanctionComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number) + { + this._data = [k, _arg_2, _arg_3]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/ModTradingLockMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/ModTradingLockMessageComposer.ts new file mode 100644 index 0000000..17a1c44 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ModTradingLockMessageComposer.ts @@ -0,0 +1,27 @@ +import { IMessageComposer } from '@nitrots/api'; +import { ModBanMessageComposer } from './ModBanMessageComposer'; + +export class ModTradingLockMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, arg2: string, arg3: number, arg4: number, arg5: number = -1) + { + this._data = [k, arg2, arg3, arg4]; + + if(arg5 != ModBanMessageComposer.NO_ISSUE_ID) + { + this._data.push(arg5); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/ModerateRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/ModerateRoomMessageComposer.ts new file mode 100644 index 0000000..44fd233 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ModerateRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ModerateRoomMessageComposer 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/packages/communication/src/messages/outgoing/moderation/ModeratorActionMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/ModeratorActionMessageComposer.ts new file mode 100644 index 0000000..6e42613 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ModeratorActionMessageComposer.ts @@ -0,0 +1,28 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ModeratorActionMessageComposer implements IMessageComposer +{ + public static readonly ACTION_ALERT = 0; + public static readonly ACTION_KICK = 1; + public static readonly ACTION_MESSAGE = 3; + public static readonly ACTION_MESSAGE_AND_SOFT_KICK = 4; + + 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/packages/communication/src/messages/outgoing/moderation/PickIssuesMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/PickIssuesMessageComposer.ts new file mode 100644 index 0000000..a5f8ea0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/PickIssuesMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PickIssuesMessageComposer implements IMessageComposer +{ + private _data: any; + + constructor(issueIds: number[], retryEnabled: boolean, retryCount: number, message: string) + { + this._data = [issueIds.length, ...issueIds, retryEnabled, retryCount, message]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/ReleaseIssuesMessageComposer.ts b/packages/communication/src/messages/outgoing/moderation/ReleaseIssuesMessageComposer.ts new file mode 100644 index 0000000..4d69869 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/ReleaseIssuesMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ReleaseIssuesMessageComposer implements IMessageComposer +{ + private _data: number[]; + + constructor(issueIds: number[]) + { + this._data = [issueIds.length, ...issueIds]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/moderation/index.ts b/packages/communication/src/messages/outgoing/moderation/index.ts new file mode 100644 index 0000000..6f35762 --- /dev/null +++ b/packages/communication/src/messages/outgoing/moderation/index.ts @@ -0,0 +1,21 @@ +export * from './CloseIssueDefaultActionMessageComposer'; +export * from './CloseIssuesMessageComposer'; +export * from './DefaultSanctionMessageComposer'; +export * from './GetCfhChatlogMessageComposer'; +export * from './GetModeratorRoomInfoMessageComposer'; +export * from './GetModeratorUserInfoMessageComposer'; +export * from './GetRoomChatlogMessageComposer'; +export * from './GetRoomVisitsMessageComposer'; +export * from './GetUserChatlogMessageComposer'; +export * from './ModAlertMessageComposer'; +export * from './ModBanMessageComposer'; +export * from './ModerateRoomMessageComposer'; +export * from './ModeratorActionMessageComposer'; +export * from './ModKickMessageComposer'; +export * from './ModMessageMessageComposer'; +export * from './ModMuteMessageComposer'; +export * from './ModToolPreferencesComposer'; +export * from './ModToolSanctionComposer'; +export * from './ModTradingLockMessageComposer'; +export * from './PickIssuesMessageComposer'; +export * from './ReleaseIssuesMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/mysterybox/MysteryBoxWaitingCanceledMessageComposer.ts b/packages/communication/src/messages/outgoing/mysterybox/MysteryBoxWaitingCanceledMessageComposer.ts new file mode 100644 index 0000000..d16a8e9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/mysterybox/MysteryBoxWaitingCanceledMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MysteryBoxWaitingCanceledMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/mysterybox/index.ts b/packages/communication/src/messages/outgoing/mysterybox/index.ts new file mode 100644 index 0000000..d4ed8fb --- /dev/null +++ b/packages/communication/src/messages/outgoing/mysterybox/index.ts @@ -0,0 +1 @@ +export * from './MysteryBoxWaitingCanceledMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/navigator/AddFavouriteRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/AddFavouriteRoomMessageComposer.ts new file mode 100644 index 0000000..1093bc3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/AddFavouriteRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class AddFavouriteRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/CanCreateRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/CanCreateRoomMessageComposer.ts new file mode 100644 index 0000000..8be84d5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/CanCreateRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CanCreateRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/CancelEventMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/CancelEventMessageComposer.ts new file mode 100644 index 0000000..d56200d --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/CancelEventMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CancelEventMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/CompetitionRoomsSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/CompetitionRoomsSearchMessageComposer.ts new file mode 100644 index 0000000..96d9ecd --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/CompetitionRoomsSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CompetitionRoomsSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/ConvertGlobalRoomIdComposer.ts b/packages/communication/src/messages/outgoing/navigator/ConvertGlobalRoomIdComposer.ts new file mode 100644 index 0000000..836da31 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/ConvertGlobalRoomIdComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ConvertGlobalRoomIdMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(flatId: string) + { + this._data = [flatId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/CreateFlatMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/CreateFlatMessageComposer.ts new file mode 100644 index 0000000..e65d1a8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/CreateFlatMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CreateFlatMessageComposer 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; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/DeleteFavouriteRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/DeleteFavouriteRoomMessageComposer.ts new file mode 100644 index 0000000..8bbe867 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/DeleteFavouriteRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class DeleteFavouriteRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/EditEventMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/EditEventMessageComposer.ts new file mode 100644 index 0000000..6244e5a --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/EditEventMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class EditEventMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: string, _arg_3: string) + { + this._data = [k, _arg_2, _arg_3]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/ForwardToARandomPromotedRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/ForwardToARandomPromotedRoomMessageComposer.ts new file mode 100644 index 0000000..08060fe --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/ForwardToARandomPromotedRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ForwardToARandomPromotedRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/ForwardToSomeRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/ForwardToSomeRoomMessageComposer.ts new file mode 100644 index 0000000..b4b48dc --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/ForwardToSomeRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ForwardToSomeRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/GetCategoriesWithUserCountMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/GetCategoriesWithUserCountMessageComposer.ts new file mode 100644 index 0000000..6993f54 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/GetCategoriesWithUserCountMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCategoriesWithUserCountMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/GetCustomRoomFilterMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/GetCustomRoomFilterMessageComposer.ts new file mode 100644 index 0000000..a790aa1 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/GetCustomRoomFilterMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCustomRoomFilterMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/GetGuestRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/GetGuestRoomMessageComposer.ts new file mode 100644 index 0000000..99218ce --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/GetGuestRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetGuestRoomMessageComposer 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; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/GetOfficialRoomsMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/GetOfficialRoomsMessageComposer.ts new file mode 100644 index 0000000..3c34c60 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/GetOfficialRoomsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetOfficialRoomsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number = 0) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/GetPopularRoomTagsMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/GetPopularRoomTagsMessageComposer.ts new file mode 100644 index 0000000..b716c69 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/GetPopularRoomTagsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetPopularRoomTagsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/GetUserEventCatsMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/GetUserEventCatsMessageComposer.ts new file mode 100644 index 0000000..40ae56d --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/GetUserEventCatsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetUserEventCatsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/GetUserFlatCatsMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/GetUserFlatCatsMessageComposer.ts new file mode 100644 index 0000000..9e92a0e --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/GetUserFlatCatsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetUserFlatCatsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/GuildBaseSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/GuildBaseSearchMessageComposer.ts new file mode 100644 index 0000000..7fab8a6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/GuildBaseSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GuildBaseSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/MyFavouriteRoomsSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/MyFavouriteRoomsSearchMessageComposer.ts new file mode 100644 index 0000000..84b8e09 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/MyFavouriteRoomsSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MyFavouriteRoomsSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/MyFrequentRoomHistorySearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/MyFrequentRoomHistorySearchMessageComposer.ts new file mode 100644 index 0000000..91de6f9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/MyFrequentRoomHistorySearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MyFrequentRoomHistorySearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/MyFriendsRoomsSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/MyFriendsRoomsSearchMessageComposer.ts new file mode 100644 index 0000000..e48ad1d --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/MyFriendsRoomsSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MyFriendsRoomsSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/MyGuildBasesSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/MyGuildBasesSearchMessageComposer.ts new file mode 100644 index 0000000..1d6237b --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/MyGuildBasesSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MyGuildBasesSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/MyRecommendedRoomsMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/MyRecommendedRoomsMessageComposer.ts new file mode 100644 index 0000000..2fc05ff --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/MyRecommendedRoomsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MyRecommendedRoomsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/MyRoomHistorySearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/MyRoomHistorySearchMessageComposer.ts new file mode 100644 index 0000000..5c74447 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/MyRoomHistorySearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MyRoomHistorySearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/MyRoomRightsSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/MyRoomRightsSearchMessageComposer.ts new file mode 100644 index 0000000..f7edd3a --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/MyRoomRightsSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MyRoomRightsSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/MyRoomsSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/MyRoomsSearchMessageComposer.ts new file mode 100644 index 0000000..a24e987 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/MyRoomsSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MyRoomsSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/NavigatorCategoryListModeComposer.ts b/packages/communication/src/messages/outgoing/navigator/NavigatorCategoryListModeComposer.ts new file mode 100644 index 0000000..4ac96b0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/NavigatorCategoryListModeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/NavigatorDeleteSavedSearchComposer.ts b/packages/communication/src/messages/outgoing/navigator/NavigatorDeleteSavedSearchComposer.ts new file mode 100644 index 0000000..60ebb19 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/NavigatorDeleteSavedSearchComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class NavigatorDeleteSavedSearchComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(searchId: number) + { + this._data = [searchId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/NavigatorInitComposer.ts b/packages/communication/src/messages/outgoing/navigator/NavigatorInitComposer.ts new file mode 100644 index 0000000..74e6efd --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/NavigatorInitComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class NavigatorInitComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/NavigatorSearchCloseComposer.ts b/packages/communication/src/messages/outgoing/navigator/NavigatorSearchCloseComposer.ts new file mode 100644 index 0000000..0823bf1 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/NavigatorSearchCloseComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class NavigatorSearchCloseComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(code: string) + { + this._data = [code]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/NavigatorSearchComposer.ts b/packages/communication/src/messages/outgoing/navigator/NavigatorSearchComposer.ts new file mode 100644 index 0000000..522ecb4 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/NavigatorSearchComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/NavigatorSearchOpenComposer.ts b/packages/communication/src/messages/outgoing/navigator/NavigatorSearchOpenComposer.ts new file mode 100644 index 0000000..679b559 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/NavigatorSearchOpenComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class NavigatorSearchOpenComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(code: string) + { + this._data = [code]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/NavigatorSearchSaveComposer.ts b/packages/communication/src/messages/outgoing/navigator/NavigatorSearchSaveComposer.ts new file mode 100644 index 0000000..c4745eb --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/NavigatorSearchSaveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/NavigatorSettingsSaveComposer.ts b/packages/communication/src/messages/outgoing/navigator/NavigatorSettingsSaveComposer.ts new file mode 100644 index 0000000..fcbff21 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/NavigatorSettingsSaveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/PopularRoomsSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/PopularRoomsSearchMessageComposer.ts new file mode 100644 index 0000000..df0b56b --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/PopularRoomsSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PopularRoomsSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/RateFlatMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/RateFlatMessageComposer.ts new file mode 100644 index 0000000..afeab01 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/RateFlatMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RateFlatMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/RemoveOwnRoomRightsRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/RemoveOwnRoomRightsRoomMessageComposer.ts new file mode 100644 index 0000000..605bdb6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/RemoveOwnRoomRightsRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RemoveOwnRoomRightsRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/RoomAdEventTabAdClickedComposer.ts b/packages/communication/src/messages/outgoing/navigator/RoomAdEventTabAdClickedComposer.ts new file mode 100644 index 0000000..66f0022 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/RoomAdEventTabAdClickedComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomAdEventTabAdClickedComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: string, _arg_3: number) + { + this._data = [k, _arg_2, _arg_3]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/RoomAdEventTabViewedComposer.ts b/packages/communication/src/messages/outgoing/navigator/RoomAdEventTabViewedComposer.ts new file mode 100644 index 0000000..dbb271e --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/RoomAdEventTabViewedComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomAdEventTabViewedComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/RoomAdSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/RoomAdSearchMessageComposer.ts new file mode 100644 index 0000000..d22bf96 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/RoomAdSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomAdSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/RoomTextSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/RoomTextSearchMessageComposer.ts new file mode 100644 index 0000000..3d5c1f7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/RoomTextSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomTextSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/RoomsWhereMyFriendsAreSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/RoomsWhereMyFriendsAreSearchMessageComposer.ts new file mode 100644 index 0000000..67cab58 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/RoomsWhereMyFriendsAreSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomsWhereMyFriendsAreSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/RoomsWithHighestScoreSearchMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/RoomsWithHighestScoreSearchMessageComposer.ts new file mode 100644 index 0000000..bb87c5d --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/RoomsWithHighestScoreSearchMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomsWithHighestScoreSearchMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/SetRoomSessionTagsMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/SetRoomSessionTagsMessageComposer.ts new file mode 100644 index 0000000..a79d520 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/SetRoomSessionTagsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SetRoomSessionTagsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string, _arg_2: string) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/ToggleStaffPickMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/ToggleStaffPickMessageComposer.ts new file mode 100644 index 0000000..d1462e2 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/ToggleStaffPickMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ToggleStaffPickMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/UpdateHomeRoomMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/UpdateHomeRoomMessageComposer.ts new file mode 100644 index 0000000..ce555e5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/UpdateHomeRoomMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UpdateHomeRoomMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/UpdateRoomFilterMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/UpdateRoomFilterMessageComposer.ts new file mode 100644 index 0000000..a79b70c --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/UpdateRoomFilterMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UpdateRoomFilterMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number, isAddingWord: boolean, word: string) + { + this._data = [roomId, isAddingWord, word]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/UpdateRoomThumbnailMessageComposer.ts b/packages/communication/src/messages/outgoing/navigator/UpdateRoomThumbnailMessageComposer.ts new file mode 100644 index 0000000..c12e83e --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/UpdateRoomThumbnailMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UpdateRoomThumbnailMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(flatId: number, bgImgId: number, frontImgId: number, objCount: number) + { + this._data = [flatId, bgImgId, frontImgId, objCount]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/navigator/index.ts b/packages/communication/src/messages/outgoing/navigator/index.ts new file mode 100644 index 0000000..4a73ec7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/navigator/index.ts @@ -0,0 +1,48 @@ +export * from './AddFavouriteRoomMessageComposer'; +export * from './CancelEventMessageComposer'; +export * from './CanCreateRoomMessageComposer'; +export * from './CompetitionRoomsSearchMessageComposer'; +export * from './ConvertGlobalRoomIdComposer'; +export * from './CreateFlatMessageComposer'; +export * from './DeleteFavouriteRoomMessageComposer'; +export * from './EditEventMessageComposer'; +export * from './ForwardToARandomPromotedRoomMessageComposer'; +export * from './ForwardToSomeRoomMessageComposer'; +export * from './GetCategoriesWithUserCountMessageComposer'; +export * from './GetCustomRoomFilterMessageComposer'; +export * from './GetGuestRoomMessageComposer'; +export * from './GetOfficialRoomsMessageComposer'; +export * from './GetPopularRoomTagsMessageComposer'; +export * from './GetUserEventCatsMessageComposer'; +export * from './GetUserFlatCatsMessageComposer'; +export * from './GuildBaseSearchMessageComposer'; +export * from './MyFavouriteRoomsSearchMessageComposer'; +export * from './MyFrequentRoomHistorySearchMessageComposer'; +export * from './MyFriendsRoomsSearchMessageComposer'; +export * from './MyGuildBasesSearchMessageComposer'; +export * from './MyRecommendedRoomsMessageComposer'; +export * from './MyRoomHistorySearchMessageComposer'; +export * from './MyRoomRightsSearchMessageComposer'; +export * from './MyRoomsSearchMessageComposer'; +export * from './NavigatorCategoryListModeComposer'; +export * from './NavigatorDeleteSavedSearchComposer'; +export * from './NavigatorInitComposer'; +export * from './NavigatorSearchCloseComposer'; +export * from './NavigatorSearchComposer'; +export * from './NavigatorSearchOpenComposer'; +export * from './NavigatorSearchSaveComposer'; +export * from './NavigatorSettingsSaveComposer'; +export * from './PopularRoomsSearchMessageComposer'; +export * from './RateFlatMessageComposer'; +export * from './RemoveOwnRoomRightsRoomMessageComposer'; +export * from './RoomAdEventTabAdClickedComposer'; +export * from './RoomAdEventTabViewedComposer'; +export * from './RoomAdSearchMessageComposer'; +export * from './RoomsWhereMyFriendsAreSearchMessageComposer'; +export * from './RoomsWithHighestScoreSearchMessageComposer'; +export * from './RoomTextSearchMessageComposer'; +export * from './SetRoomSessionTagsMessageComposer'; +export * from './ToggleStaffPickMessageComposer'; +export * from './UpdateHomeRoomMessageComposer'; +export * from './UpdateRoomFilterMessageComposer'; +export * from './UpdateRoomThumbnailMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/nux/NewUserExperienceGetGiftsComposer.ts b/packages/communication/src/messages/outgoing/nux/NewUserExperienceGetGiftsComposer.ts new file mode 100644 index 0000000..918a82d --- /dev/null +++ b/packages/communication/src/messages/outgoing/nux/NewUserExperienceGetGiftsComposer.ts @@ -0,0 +1,28 @@ +import { IMessageComposer } from '@nitrots/api'; +import { NewUserExperienceGetGiftsSelection } from './NewUserExperienceGetGiftsSelection'; + +export class NewUserExperienceGetGiftsComposer implements IMessageComposer> +{ + private _data: any; + + constructor(...data: NewUserExperienceGetGiftsSelection[]) + { + this._data = [data.length * 3]; + data.forEach(entry => + { + this._data.push(entry.dayIndex); + this._data.push(entry.stepIndex); + this._data.push(entry.giftIndex); + }); + } + + dispose(): void + { + this._data = null; + } + + public getMessageArray() + { + return this._data; + } +} diff --git a/packages/communication/src/messages/outgoing/nux/NewUserExperienceGetGiftsSelection.ts b/packages/communication/src/messages/outgoing/nux/NewUserExperienceGetGiftsSelection.ts new file mode 100644 index 0000000..fd95d6b --- /dev/null +++ b/packages/communication/src/messages/outgoing/nux/NewUserExperienceGetGiftsSelection.ts @@ -0,0 +1,28 @@ +export class NewUserExperienceGetGiftsSelection +{ + private _dayIndex: number; + private _stepIndex: number; + private _giftIndex: number; + + constructor(dayIndex: number, stepIndex: number, giftIndex: number) + { + this._dayIndex = dayIndex; + this._stepIndex = stepIndex; + this._giftIndex = giftIndex; + } + + public get dayIndex(): number + { + return this._dayIndex; + } + + public get stepIndex(): number + { + return this._stepIndex; + } + + public get giftIndex(): number + { + return this._giftIndex; + } +} diff --git a/packages/communication/src/messages/outgoing/nux/NewUserExperienceScriptProceedComposer.ts b/packages/communication/src/messages/outgoing/nux/NewUserExperienceScriptProceedComposer.ts new file mode 100644 index 0000000..31ee0d3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/nux/NewUserExperienceScriptProceedComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class NewUserExperienceScriptProceedComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/nux/index.ts b/packages/communication/src/messages/outgoing/nux/index.ts new file mode 100644 index 0000000..31d517b --- /dev/null +++ b/packages/communication/src/messages/outgoing/nux/index.ts @@ -0,0 +1,3 @@ +export * from './NewUserExperienceGetGiftsComposer'; +export * from './NewUserExperienceGetGiftsSelection'; +export * from './NewUserExperienceScriptProceedComposer'; diff --git a/packages/communication/src/messages/outgoing/pet/GetPetCommandsComposer.ts b/packages/communication/src/messages/outgoing/pet/GetPetCommandsComposer.ts new file mode 100644 index 0000000..727faed --- /dev/null +++ b/packages/communication/src/messages/outgoing/pet/GetPetCommandsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetPetCommandsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number) + { + this._data = [petId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/pet/PetMountComposer.ts b/packages/communication/src/messages/outgoing/pet/PetMountComposer.ts new file mode 100644 index 0000000..93ff9c1 --- /dev/null +++ b/packages/communication/src/messages/outgoing/pet/PetMountComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PetMountComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number, flag: boolean) + { + this._data = [petId, flag]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/pet/PetRespectComposer.ts b/packages/communication/src/messages/outgoing/pet/PetRespectComposer.ts new file mode 100644 index 0000000..fdb919a --- /dev/null +++ b/packages/communication/src/messages/outgoing/pet/PetRespectComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PetRespectComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number) + { + this._data = [petId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/pet/PetSupplementComposer.ts b/packages/communication/src/messages/outgoing/pet/PetSupplementComposer.ts new file mode 100644 index 0000000..b0f4d12 --- /dev/null +++ b/packages/communication/src/messages/outgoing/pet/PetSupplementComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PetSupplementComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number, supplement: number) + { + this._data = [petId, supplement]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/pet/RemovePetSaddleComposer.ts b/packages/communication/src/messages/outgoing/pet/RemovePetSaddleComposer.ts new file mode 100644 index 0000000..de933bd --- /dev/null +++ b/packages/communication/src/messages/outgoing/pet/RemovePetSaddleComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RemovePetSaddleComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number) + { + this._data = [petId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/pet/RequestPetInfoComposer.ts b/packages/communication/src/messages/outgoing/pet/RequestPetInfoComposer.ts new file mode 100644 index 0000000..b4d03dd --- /dev/null +++ b/packages/communication/src/messages/outgoing/pet/RequestPetInfoComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/pet/TogglePetBreedingComposer.ts b/packages/communication/src/messages/outgoing/pet/TogglePetBreedingComposer.ts new file mode 100644 index 0000000..cbe72c5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/pet/TogglePetBreedingComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TogglePetBreedingComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number) + { + this._data = [petId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/pet/TogglePetRidingComposer.ts b/packages/communication/src/messages/outgoing/pet/TogglePetRidingComposer.ts new file mode 100644 index 0000000..2bfdb96 --- /dev/null +++ b/packages/communication/src/messages/outgoing/pet/TogglePetRidingComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TogglePetRidingComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number) + { + this._data = [petId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/pet/UsePetProductComposer.ts b/packages/communication/src/messages/outgoing/pet/UsePetProductComposer.ts new file mode 100644 index 0000000..5ef7354 --- /dev/null +++ b/packages/communication/src/messages/outgoing/pet/UsePetProductComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UsePetProductComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, petId: number) + { + this._data = [itemId, petId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/pet/index.ts b/packages/communication/src/messages/outgoing/pet/index.ts new file mode 100644 index 0000000..6e1205d --- /dev/null +++ b/packages/communication/src/messages/outgoing/pet/index.ts @@ -0,0 +1,9 @@ +export * from './GetPetCommandsComposer'; +export * from './PetMountComposer'; +export * from './PetRespectComposer'; +export * from './PetSupplementComposer'; +export * from './RemovePetSaddleComposer'; +export * from './RequestPetInfoComposer'; +export * from './TogglePetBreedingComposer'; +export * from './TogglePetRidingComposer'; +export * from './UsePetProductComposer'; diff --git a/packages/communication/src/messages/outgoing/poll/PollAnswerComposer.ts b/packages/communication/src/messages/outgoing/poll/PollAnswerComposer.ts new file mode 100644 index 0000000..e49a948 --- /dev/null +++ b/packages/communication/src/messages/outgoing/poll/PollAnswerComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PollAnswerComposer implements IMessageComposer +{ + private _data: any; + + constructor(pollId: number, questionId: number, answers: string[]) + { + this._data = [pollId, questionId, answers.length, ...answers]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/poll/PollRejectComposer.ts b/packages/communication/src/messages/outgoing/poll/PollRejectComposer.ts new file mode 100644 index 0000000..ac38682 --- /dev/null +++ b/packages/communication/src/messages/outgoing/poll/PollRejectComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PollRejectComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/poll/PollStartComposer.ts b/packages/communication/src/messages/outgoing/poll/PollStartComposer.ts new file mode 100644 index 0000000..9621d09 --- /dev/null +++ b/packages/communication/src/messages/outgoing/poll/PollStartComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PollStartComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/poll/VotePollCounterMessageComposer.ts b/packages/communication/src/messages/outgoing/poll/VotePollCounterMessageComposer.ts new file mode 100644 index 0000000..4edfc37 --- /dev/null +++ b/packages/communication/src/messages/outgoing/poll/VotePollCounterMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class VotePollCounterMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(counter: number) + { + this._data = [counter]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/poll/index.ts b/packages/communication/src/messages/outgoing/poll/index.ts new file mode 100644 index 0000000..0055b90 --- /dev/null +++ b/packages/communication/src/messages/outgoing/poll/index.ts @@ -0,0 +1,4 @@ +export * from './PollAnswerComposer'; +export * from './PollRejectComposer'; +export * from './PollStartComposer'; +export * from './VotePollCounterMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/quest/AcceptQuestMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/AcceptQuestMessageComposer.ts new file mode 100644 index 0000000..ef06b30 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/AcceptQuestMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class AcceptQuestMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/ActivateQuestMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/ActivateQuestMessageComposer.ts new file mode 100644 index 0000000..366e648 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/ActivateQuestMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ActivateQuestMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/CancelQuestMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/CancelQuestMessageComposer.ts new file mode 100644 index 0000000..e4238d8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/CancelQuestMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CancelQuestMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/FriendRequestQuestCompleteMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/FriendRequestQuestCompleteMessageComposer.ts new file mode 100644 index 0000000..1270d71 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/FriendRequestQuestCompleteMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FriendRequestQuestCompleteMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/GetCommunityGoalEarnedPrizesMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/GetCommunityGoalEarnedPrizesMessageComposer.ts new file mode 100644 index 0000000..6c47134 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/GetCommunityGoalEarnedPrizesMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCommunityGoalEarnedPrizesMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/GetCommunityGoalHallOfFameMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/GetCommunityGoalHallOfFameMessageComposer.ts new file mode 100644 index 0000000..8ea1711 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/GetCommunityGoalHallOfFameMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCommunityGoalHallOfFameMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/GetCommunityGoalProgressMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/GetCommunityGoalProgressMessageComposer.ts new file mode 100644 index 0000000..042fcb3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/GetCommunityGoalProgressMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetCommunityGoalProgressMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/GetConcurrentUsersGoalProgressMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/GetConcurrentUsersGoalProgressMessageComposer.ts new file mode 100644 index 0000000..ebc5f26 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/GetConcurrentUsersGoalProgressMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetConcurrentUsersGoalProgressMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/GetConcurrentUsersRewardMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/GetConcurrentUsersRewardMessageComposer.ts new file mode 100644 index 0000000..812e794 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/GetConcurrentUsersRewardMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetConcurrentUsersRewardMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/GetDailyQuestMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/GetDailyQuestMessageComposer.ts new file mode 100644 index 0000000..6e23417 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/GetDailyQuestMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetDailyQuestMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: boolean, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/GetQuestsMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/GetQuestsMessageComposer.ts new file mode 100644 index 0000000..0500bf6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/GetQuestsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetQuestsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/GetSeasonalQuestsOnlyMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/GetSeasonalQuestsOnlyMessageComposer.ts new file mode 100644 index 0000000..08a2930 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/GetSeasonalQuestsOnlyMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetSeasonalQuestsOnlyMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/OpenQuestTrackerMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/OpenQuestTrackerMessageComposer.ts new file mode 100644 index 0000000..1e5ceaa --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/OpenQuestTrackerMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class OpenQuestTrackerMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/RedeemCommunityGoalPrizeMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/RedeemCommunityGoalPrizeMessageComposer.ts new file mode 100644 index 0000000..8807a00 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/RedeemCommunityGoalPrizeMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RedeemCommunityGoalPrizeMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(communityGoalId: number) + { + this._data = [communityGoalId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/RejectQuestMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/RejectQuestMessageComposer.ts new file mode 100644 index 0000000..ddbfd07 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/RejectQuestMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RejectQuestMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/StartCampaignMessageComposer.ts b/packages/communication/src/messages/outgoing/quest/StartCampaignMessageComposer.ts new file mode 100644 index 0000000..f3c9d70 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/StartCampaignMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class StartCampaignMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/quest/index.ts b/packages/communication/src/messages/outgoing/quest/index.ts new file mode 100644 index 0000000..e9f5c99 --- /dev/null +++ b/packages/communication/src/messages/outgoing/quest/index.ts @@ -0,0 +1,16 @@ +export * from './AcceptQuestMessageComposer'; +export * from './ActivateQuestMessageComposer'; +export * from './CancelQuestMessageComposer'; +export * from './FriendRequestQuestCompleteMessageComposer'; +export * from './GetCommunityGoalEarnedPrizesMessageComposer'; +export * from './GetCommunityGoalHallOfFameMessageComposer'; +export * from './GetCommunityGoalProgressMessageComposer'; +export * from './GetConcurrentUsersGoalProgressMessageComposer'; +export * from './GetConcurrentUsersRewardMessageComposer'; +export * from './GetDailyQuestMessageComposer'; +export * from './GetQuestsMessageComposer'; +export * from './GetSeasonalQuestsOnlyMessageComposer'; +export * from './OpenQuestTrackerMessageComposer'; +export * from './RedeemCommunityGoalPrizeMessageComposer'; +export * from './RejectQuestMessageComposer'; +export * from './StartCampaignMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/recycler/GetRecyclerStatusMessageComposer.ts b/packages/communication/src/messages/outgoing/recycler/GetRecyclerStatusMessageComposer.ts new file mode 100644 index 0000000..2a6d74b --- /dev/null +++ b/packages/communication/src/messages/outgoing/recycler/GetRecyclerStatusMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetRecyclerStatusMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/recycler/RecycleItemsMessageComposer.ts b/packages/communication/src/messages/outgoing/recycler/RecycleItemsMessageComposer.ts new file mode 100644 index 0000000..1b0fdbb --- /dev/null +++ b/packages/communication/src/messages/outgoing/recycler/RecycleItemsMessageComposer.ts @@ -0,0 +1,31 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RecycleItemsMessageComposer implements IMessageComposer +{ + private _data: any; + + constructor(...data: RecycleItemsEntry[]) + { + this._data = [data.length]; + data.forEach(entry => + { + this._data.push(entry.itemId); + }); + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} + +export class RecycleItemsEntry +{ + constructor(public itemId: number) + { } +} diff --git a/packages/communication/src/messages/outgoing/recycler/index.ts b/packages/communication/src/messages/outgoing/recycler/index.ts new file mode 100644 index 0000000..b3fc57c --- /dev/null +++ b/packages/communication/src/messages/outgoing/recycler/index.ts @@ -0,0 +1,2 @@ +export * from './GetRecyclerStatusMessageComposer'; +export * from './RecycleItemsMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/room/RedeemItemClothingComposer.ts b/packages/communication/src/messages/outgoing/room/RedeemItemClothingComposer.ts new file mode 100644 index 0000000..58f5847 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/RedeemItemClothingComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RedeemItemClothingComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(setId: number) + { + this._data = [setId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/access/RoomDoorbellAccessComposer.ts b/packages/communication/src/messages/outgoing/room/access/RoomDoorbellAccessComposer.ts new file mode 100644 index 0000000..a9c31f5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/access/RoomDoorbellAccessComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/access/RoomEnterComposer.ts b/packages/communication/src/messages/outgoing/room/access/RoomEnterComposer.ts new file mode 100644 index 0000000..a195223 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/access/RoomEnterComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/access/index.ts b/packages/communication/src/messages/outgoing/room/access/index.ts new file mode 100644 index 0000000..2025545 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/access/index.ts @@ -0,0 +1,2 @@ +export * from './RoomDoorbellAccessComposer'; +export * from './RoomEnterComposer'; diff --git a/packages/communication/src/messages/outgoing/room/action/RemoveAllRightsMessageComposer.ts b/packages/communication/src/messages/outgoing/room/action/RemoveAllRightsMessageComposer.ts new file mode 100644 index 0000000..f9c25cf --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/action/RemoveAllRightsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RemoveAllRightsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/action/RoomAmbassadorAlertComposer.ts b/packages/communication/src/messages/outgoing/room/action/RoomAmbassadorAlertComposer.ts new file mode 100644 index 0000000..55d4944 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/action/RoomAmbassadorAlertComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomAmbassadorAlertComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/action/RoomBanUserComposer.ts b/packages/communication/src/messages/outgoing/room/action/RoomBanUserComposer.ts new file mode 100644 index 0000000..75744a7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/action/RoomBanUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/action/RoomDeleteComposer.ts b/packages/communication/src/messages/outgoing/room/action/RoomDeleteComposer.ts new file mode 100644 index 0000000..95648c5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/action/RoomDeleteComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomDeleteComposer implements IMessageComposer<[number]> +{ + private _data: [number]; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/action/RoomGiveRightsComposer.ts b/packages/communication/src/messages/outgoing/room/action/RoomGiveRightsComposer.ts new file mode 100644 index 0000000..8654eea --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/action/RoomGiveRightsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomGiveRightsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/action/RoomKickUserComposer.ts b/packages/communication/src/messages/outgoing/room/action/RoomKickUserComposer.ts new file mode 100644 index 0000000..042e4a5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/action/RoomKickUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomKickUserComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/action/RoomMuteUserComposer.ts b/packages/communication/src/messages/outgoing/room/action/RoomMuteUserComposer.ts new file mode 100644 index 0000000..35277f6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/action/RoomMuteUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomMuteUserComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number, minutes: number, roomId: number = 0) + { + this._data = [userId, roomId, minutes]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/action/RoomTakeRightsComposer.ts b/packages/communication/src/messages/outgoing/room/action/RoomTakeRightsComposer.ts new file mode 100644 index 0000000..2068bf7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/action/RoomTakeRightsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/action/RoomUnbanUserComposer.ts b/packages/communication/src/messages/outgoing/room/action/RoomUnbanUserComposer.ts new file mode 100644 index 0000000..49b80dd --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/action/RoomUnbanUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/action/index.ts b/packages/communication/src/messages/outgoing/room/action/index.ts new file mode 100644 index 0000000..3846b4a --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/action/index.ts @@ -0,0 +1,9 @@ +export * from './RemoveAllRightsMessageComposer'; +export * from './RoomAmbassadorAlertComposer'; +export * from './RoomBanUserComposer'; +export * from './RoomDeleteComposer'; +export * from './RoomGiveRightsComposer'; +export * from './RoomKickUserComposer'; +export * from './RoomMuteUserComposer'; +export * from './RoomTakeRightsComposer'; +export * from './RoomUnbanUserComposer'; diff --git a/packages/communication/src/messages/outgoing/room/bots/RequestBotConfigurationComposer.ts b/packages/communication/src/messages/outgoing/room/bots/RequestBotConfigurationComposer.ts new file mode 100644 index 0000000..7851651 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/bots/RequestBotConfigurationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/bots/index.ts b/packages/communication/src/messages/outgoing/room/bots/index.ts new file mode 100644 index 0000000..d4b295a --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/bots/index.ts @@ -0,0 +1 @@ +export * from './RequestBotConfigurationComposer'; diff --git a/packages/communication/src/messages/outgoing/room/data/RoomBannedUsersComposer.ts b/packages/communication/src/messages/outgoing/room/data/RoomBannedUsersComposer.ts new file mode 100644 index 0000000..2a944d9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/data/RoomBannedUsersComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomBannedUsersComposer implements IMessageComposer<[number]> +{ + private _data: [number]; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/data/RoomSettingsComposer.ts b/packages/communication/src/messages/outgoing/room/data/RoomSettingsComposer.ts new file mode 100644 index 0000000..6fb8af1 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/data/RoomSettingsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomSettingsComposer implements IMessageComposer<[number]> +{ + private _data: [number]; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/data/RoomUsersWithRightsComposer.ts b/packages/communication/src/messages/outgoing/room/data/RoomUsersWithRightsComposer.ts new file mode 100644 index 0000000..ec2902c --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/data/RoomUsersWithRightsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/data/SaveRoomSettingsComposer.ts b/packages/communication/src/messages/outgoing/room/data/SaveRoomSettingsComposer.ts new file mode 100644 index 0000000..8b69492 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/data/SaveRoomSettingsComposer.ts @@ -0,0 +1,81 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SaveRoomSettingsComposer +implements + IMessageComposer< + ConstructorParameters + > +{ + 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 + ) + { + //@ts-ignore + this._data = []; + + this._data.push( + roomId, + roomName, + roomDescription, + lockState, + password, + userCount, + categoryId + ); + + this._data.push(tags.length, ...tags); + + this._data.push( + tradeState, + allowPets, + allowPetsEat, + allowWalkthrough, + hideWalls, + wallThickness, + floorThickness, + muteState, + kickState, + banState, + chatBubbleMode, + chatBubbleWeight, + chatBubbleSpeed, + chatDistance, + chatFloodProtection + ); + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/data/index.ts b/packages/communication/src/messages/outgoing/room/data/index.ts new file mode 100644 index 0000000..27df6c7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/data/index.ts @@ -0,0 +1,4 @@ +export * from './RoomBannedUsersComposer'; +export * from './RoomSettingsComposer'; +export * from './RoomUsersWithRightsComposer'; +export * from './SaveRoomSettingsComposer'; diff --git a/packages/communication/src/messages/outgoing/room/engine/BotPlaceComposer.ts b/packages/communication/src/messages/outgoing/room/engine/BotPlaceComposer.ts new file mode 100644 index 0000000..f658b65 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/BotPlaceComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/engine/BotRemoveComposer.ts b/packages/communication/src/messages/outgoing/room/engine/BotRemoveComposer.ts new file mode 100644 index 0000000..ddead05 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/BotRemoveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/engine/BotSkillSaveComposer.ts b/packages/communication/src/messages/outgoing/room/engine/BotSkillSaveComposer.ts new file mode 100644 index 0000000..c5aca60 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/BotSkillSaveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/engine/CompostPlantMessageComposer.ts b/packages/communication/src/messages/outgoing/room/engine/CompostPlantMessageComposer.ts new file mode 100644 index 0000000..bc23ccb --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/CompostPlantMessageComposer.ts @@ -0,0 +1,9 @@ +import { PetMessageComposer } from './PetMessageComposer'; + +export class CompostPlantMessageComposer extends PetMessageComposer +{ + constructor(id: number) + { + super(id); + } +} diff --git a/packages/communication/src/messages/outgoing/room/engine/GetItemDataComposer.ts b/packages/communication/src/messages/outgoing/room/engine/GetItemDataComposer.ts new file mode 100644 index 0000000..11a9f12 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/GetItemDataComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetItemDataComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/engine/HarvestPetMessageComposer.ts b/packages/communication/src/messages/outgoing/room/engine/HarvestPetMessageComposer.ts new file mode 100644 index 0000000..8c14acc --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/HarvestPetMessageComposer.ts @@ -0,0 +1,9 @@ +import { PetMessageComposer } from './PetMessageComposer'; + +export class HarvestPetMessageComposer extends PetMessageComposer +{ + constructor(id: number) + { + super(id); + } +} diff --git a/packages/communication/src/messages/outgoing/room/engine/PetMessageComposer.ts b/packages/communication/src/messages/outgoing/room/engine/PetMessageComposer.ts new file mode 100644 index 0000000..27f8ee2 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/PetMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PetMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(id: number) + { + this._data = [id]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/engine/PetMoveComposer.ts b/packages/communication/src/messages/outgoing/room/engine/PetMoveComposer.ts new file mode 100644 index 0000000..f9c2fab --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/PetMoveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/engine/PetPlaceComposer.ts b/packages/communication/src/messages/outgoing/room/engine/PetPlaceComposer.ts new file mode 100644 index 0000000..4549692 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/PetPlaceComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/engine/PetRemoveComposer.ts b/packages/communication/src/messages/outgoing/room/engine/PetRemoveComposer.ts new file mode 100644 index 0000000..b011032 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/PetRemoveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/engine/RemoveWallItemComposer.ts b/packages/communication/src/messages/outgoing/room/engine/RemoveWallItemComposer.ts new file mode 100644 index 0000000..ce427b7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/RemoveWallItemComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RemoveWallItemComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/engine/SetClothingChangeDataMessageComposer.ts b/packages/communication/src/messages/outgoing/room/engine/SetClothingChangeDataMessageComposer.ts new file mode 100644 index 0000000..742902b --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/SetClothingChangeDataMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SetClothingChangeDataMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(objectId: number, gender: string, look: string = '') + { + this._data = [objectId, gender, look]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/engine/SetItemDataMessageComposer.ts b/packages/communication/src/messages/outgoing/room/engine/SetItemDataMessageComposer.ts new file mode 100644 index 0000000..6b4a855 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/SetItemDataMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SetItemDataMessageComposer 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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/engine/SetObjectDataMessageComposer.ts b/packages/communication/src/messages/outgoing/room/engine/SetObjectDataMessageComposer.ts new file mode 100644 index 0000000..4915d07 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/SetObjectDataMessageComposer.ts @@ -0,0 +1,23 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SetObjectDataMessageComposer implements IMessageComposer +{ + private _data: any[]; + + constructor(objectId: number, data: Map) + { + this._data = [objectId, (data.size * 2)]; + + for(const [key, value] of data.entries()) this._data.push(key, value); + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/engine/index.ts b/packages/communication/src/messages/outgoing/room/engine/index.ts new file mode 100644 index 0000000..d8c89dc --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/engine/index.ts @@ -0,0 +1,14 @@ +export * from './BotPlaceComposer'; +export * from './BotRemoveComposer'; +export * from './BotSkillSaveComposer'; +export * from './CompostPlantMessageComposer'; +export * from './GetItemDataComposer'; +export * from './HarvestPetMessageComposer'; +export * from './PetMessageComposer'; +export * from './PetMoveComposer'; +export * from './PetPlaceComposer'; +export * from './PetRemoveComposer'; +export * from './RemoveWallItemComposer'; +export * from './SetClothingChangeDataMessageComposer'; +export * from './SetItemDataMessageComposer'; +export * from './SetObjectDataMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/room/furniture/AddSpamWallPostItMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/AddSpamWallPostItMessageComposer.ts new file mode 100644 index 0000000..31de585 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/AddSpamWallPostItMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class AddSpamWallPostItMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, location: string, colorHex: string, message: string) + { + this._data = [itemId, location, colorHex, message]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/ExtendRentOrBuyoutFurniMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/ExtendRentOrBuyoutFurniMessageComposer.ts new file mode 100644 index 0000000..b607985 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/ExtendRentOrBuyoutFurniMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ExtendRentOrBuyoutFurniMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(isWall: boolean, roomInstanceId: number, isBuyout: boolean) + { + this._data = [isWall, roomInstanceId, isBuyout]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/ExtendRentOrBuyoutStripItemMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/ExtendRentOrBuyoutStripItemMessageComposer.ts new file mode 100644 index 0000000..d77d9a1 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/ExtendRentOrBuyoutStripItemMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ExtendRentOrBuyoutStripItemMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(stripId: number, isBuyout: boolean) + { + this._data = [stripId, isBuyout]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/FurnitureAliasesComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/FurnitureAliasesComposer.ts new file mode 100644 index 0000000..056bf97 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/FurnitureAliasesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FurnitureAliasesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/FurnitureGroupInfoComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/FurnitureGroupInfoComposer.ts new file mode 100644 index 0000000..6e133e6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/FurnitureGroupInfoComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FurnitureGroupInfoComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(objectId: number, guildId: number) + { + this._data = [objectId, guildId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/FurniturePickupComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/FurniturePickupComposer.ts new file mode 100644 index 0000000..006a64e --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/FurniturePickupComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/FurniturePlaceComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/FurniturePlaceComposer.ts new file mode 100644 index 0000000..e45b74e --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/FurniturePlaceComposer.ts @@ -0,0 +1,39 @@ +import { IMessageComposer, RoomObjectCategory } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/FurniturePlacePaintComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/FurniturePlacePaintComposer.ts new file mode 100644 index 0000000..22f8608 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/FurniturePlacePaintComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FurniturePlacePaintComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(furniId: number) + { + this._data = [furniId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/FurniturePostItPlaceComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/FurniturePostItPlaceComposer.ts new file mode 100644 index 0000000..087ecb4 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/FurniturePostItPlaceComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/GetRentOrBuyoutOfferMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/GetRentOrBuyoutOfferMessageComposer.ts new file mode 100644 index 0000000..c7753eb --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/GetRentOrBuyoutOfferMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetRentOrBuyoutOfferMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(isWall: boolean, furnitureFullName: string, isBuyout: boolean) + { + this._data = [isWall, furnitureFullName, isBuyout]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/OpenMysteryTrophyMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/OpenMysteryTrophyMessageComposer.ts new file mode 100644 index 0000000..e406a6e --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/OpenMysteryTrophyMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class OpenMysteryTrophyMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(objectId: number, text: string) + { + this._data = [objectId, text]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/OpenPetPackageMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/OpenPetPackageMessageComposer.ts new file mode 100644 index 0000000..4de2ad8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/OpenPetPackageMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class OpenPetPackageMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(objectId: number, petName: string) + { + this._data = [objectId, petName]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/OpenWelcomeGiftComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/OpenWelcomeGiftComposer.ts new file mode 100644 index 0000000..cd1ecc3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/OpenWelcomeGiftComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class OpenWelcomeGiftComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(furniId: number) + { + this._data = [furniId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/RentableSpaceCancelRentMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/RentableSpaceCancelRentMessageComposer.ts new file mode 100644 index 0000000..2c8715d --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/RentableSpaceCancelRentMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RentableSpaceCancelRentMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/RentableSpaceRentMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/RentableSpaceRentMessageComposer.ts new file mode 100644 index 0000000..d75efca --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/RentableSpaceRentMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RentableSpaceRentMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/RentableSpaceStatusMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/RentableSpaceStatusMessageComposer.ts new file mode 100644 index 0000000..fe31e36 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/RentableSpaceStatusMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RentableSpaceStatusMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightSettingsComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightSettingsComposer.ts new file mode 100644 index 0000000..cc7c715 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightSettingsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MoodlightSettingsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightSettingsSaveComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightSettingsSaveComposer.ts new file mode 100644 index 0000000..3dfd717 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightSettingsSaveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightTogggleStateComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightTogggleStateComposer.ts new file mode 100644 index 0000000..df59f1c --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/dimmer/MoodlightTogggleStateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class MoodlightTogggleStateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/dimmer/index.ts b/packages/communication/src/messages/outgoing/room/furniture/dimmer/index.ts new file mode 100644 index 0000000..842aa30 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/dimmer/index.ts @@ -0,0 +1,3 @@ +export * from './MoodlightSettingsComposer'; +export * from './MoodlightSettingsSaveComposer'; +export * from './MoodlightTogggleStateComposer'; diff --git a/packages/communication/src/messages/outgoing/room/furniture/floor/FurnitureFloorUpdateComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/floor/FurnitureFloorUpdateComposer.ts new file mode 100644 index 0000000..98d8ae5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/floor/FurnitureFloorUpdateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/floor/index.ts b/packages/communication/src/messages/outgoing/room/furniture/floor/index.ts new file mode 100644 index 0000000..8dde729 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/floor/index.ts @@ -0,0 +1 @@ +export * from './FurnitureFloorUpdateComposer'; diff --git a/packages/communication/src/messages/outgoing/room/furniture/index.ts b/packages/communication/src/messages/outgoing/room/furniture/index.ts new file mode 100644 index 0000000..c8fb636 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/index.ts @@ -0,0 +1,24 @@ +export * from './AddSpamWallPostItMessageComposer'; +export * from './dimmer'; +export * from './ExtendRentOrBuyoutFurniMessageComposer'; +export * from './ExtendRentOrBuyoutStripItemMessageComposer'; +export * from './floor'; +export * from './FurnitureAliasesComposer'; +export * from './FurnitureGroupInfoComposer'; +export * from './FurniturePickupComposer'; +export * from './FurniturePlaceComposer'; +export * from './FurniturePlacePaintComposer'; +export * from './FurniturePostItPlaceComposer'; +export * from './GetRentOrBuyoutOfferMessageComposer'; +export * from './logic'; +export * from './mannequin'; +export * from './OpenMysteryTrophyMessageComposer'; +export * from './OpenPetPackageMessageComposer'; +export * from './OpenWelcomeGiftComposer'; +export * from './presents'; +export * from './RentableSpaceCancelRentMessageComposer'; +export * from './RentableSpaceRentMessageComposer'; +export * from './RentableSpaceStatusMessageComposer'; +export * from './toner'; +export * from './wall'; +export * from './youtube'; diff --git a/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureColorWheelComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureColorWheelComposer.ts new file mode 100644 index 0000000..1b95091 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureColorWheelComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FurnitureColorWheelComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureDiceActivateComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureDiceActivateComposer.ts new file mode 100644 index 0000000..73361f4 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureDiceActivateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FurnitureDiceActivateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureDiceDeactivateComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureDiceDeactivateComposer.ts new file mode 100644 index 0000000..48ea006 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureDiceDeactivateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FurnitureDiceDeactivateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureExchangeComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureExchangeComposer.ts new file mode 100644 index 0000000..5b017df --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureExchangeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FurnitureExchangeComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureMultiStateComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureMultiStateComposer.ts new file mode 100644 index 0000000..4c149fe --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureMultiStateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureOneWayDoorComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureOneWayDoorComposer.ts new file mode 100644 index 0000000..e405984 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureOneWayDoorComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class FurnitureOneWayDoorComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [itemId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureRandomStateComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureRandomStateComposer.ts new file mode 100644 index 0000000..b4327a8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureRandomStateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureStackHeightComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureStackHeightComposer.ts new file mode 100644 index 0000000..95d9033 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureStackHeightComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureWallMultiStateComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureWallMultiStateComposer.ts new file mode 100644 index 0000000..a7159e5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/logic/FurnitureWallMultiStateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/logic/index.ts b/packages/communication/src/messages/outgoing/room/furniture/logic/index.ts new file mode 100644 index 0000000..838e338 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/logic/index.ts @@ -0,0 +1,9 @@ +export * from './FurnitureColorWheelComposer'; +export * from './FurnitureDiceActivateComposer'; +export * from './FurnitureDiceDeactivateComposer'; +export * from './FurnitureExchangeComposer'; +export * from './FurnitureMultiStateComposer'; +export * from './FurnitureOneWayDoorComposer'; +export * from './FurnitureRandomStateComposer'; +export * from './FurnitureStackHeightComposer'; +export * from './FurnitureWallMultiStateComposer'; diff --git a/packages/communication/src/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveLookComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveLookComposer.ts new file mode 100644 index 0000000..6d199e9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveLookComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveNameComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveNameComposer.ts new file mode 100644 index 0000000..d470b57 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveNameComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/furniture/mannequin/index.ts b/packages/communication/src/messages/outgoing/room/furniture/mannequin/index.ts new file mode 100644 index 0000000..ed49256 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/mannequin/index.ts @@ -0,0 +1,2 @@ +export * from './FurnitureMannequinSaveLookComposer'; +export * from './FurnitureMannequinSaveNameComposer'; diff --git a/packages/communication/src/messages/outgoing/room/furniture/presents/OpenPresentComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/presents/OpenPresentComposer.ts new file mode 100644 index 0000000..8c1e878 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/presents/OpenPresentComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/furniture/presents/index.ts b/packages/communication/src/messages/outgoing/room/furniture/presents/index.ts new file mode 100644 index 0000000..d0d4ced --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/presents/index.ts @@ -0,0 +1 @@ +export * from './OpenPresentComposer'; diff --git a/packages/communication/src/messages/outgoing/room/furniture/toner/ApplyTonerComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/toner/ApplyTonerComposer.ts new file mode 100644 index 0000000..02a9f7f --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/toner/ApplyTonerComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/furniture/toner/index.ts b/packages/communication/src/messages/outgoing/room/furniture/toner/index.ts new file mode 100644 index 0000000..f8e9d81 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/toner/index.ts @@ -0,0 +1 @@ +export * from './ApplyTonerComposer'; diff --git a/packages/communication/src/messages/outgoing/room/furniture/wall/FurnitureWallUpdateComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/wall/FurnitureWallUpdateComposer.ts new file mode 100644 index 0000000..a38dd0a --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/wall/FurnitureWallUpdateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/wall/index.ts b/packages/communication/src/messages/outgoing/room/furniture/wall/index.ts new file mode 100644 index 0000000..75abfb7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/wall/index.ts @@ -0,0 +1 @@ +export * from './FurnitureWallUpdateComposer'; diff --git a/packages/communication/src/messages/outgoing/room/furniture/youtube/ControlYoutubeDisplayPlaybackMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/youtube/ControlYoutubeDisplayPlaybackMessageComposer.ts new file mode 100644 index 0000000..f3dc474 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/youtube/ControlYoutubeDisplayPlaybackMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ControlYoutubeDisplayPlaybackMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/youtube/GetYoutubeDisplayStatusMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/youtube/GetYoutubeDisplayStatusMessageComposer.ts new file mode 100644 index 0000000..c4ed921 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/youtube/GetYoutubeDisplayStatusMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetYoutubeDisplayStatusMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/youtube/SetYoutubeDisplayPlaylistMessageComposer.ts b/packages/communication/src/messages/outgoing/room/furniture/youtube/SetYoutubeDisplayPlaylistMessageComposer.ts new file mode 100644 index 0000000..55d1840 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/youtube/SetYoutubeDisplayPlaylistMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class SetYoutubeDisplayPlaylistMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: string) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/furniture/youtube/index.ts b/packages/communication/src/messages/outgoing/room/furniture/youtube/index.ts new file mode 100644 index 0000000..c72bc63 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/furniture/youtube/index.ts @@ -0,0 +1,3 @@ +export * from './ControlYoutubeDisplayPlaybackMessageComposer'; +export * from './GetYoutubeDisplayStatusMessageComposer'; +export * from './SetYoutubeDisplayPlaylistMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/room/index.ts b/packages/communication/src/messages/outgoing/room/index.ts new file mode 100644 index 0000000..0067ee0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/index.ts @@ -0,0 +1,19 @@ +export * from './access'; +export * from './action'; +export * from './bots'; +export * from './data'; +export * from './engine'; +export * from './furniture'; +export * from './furniture/dimmer'; +export * from './furniture/floor'; +export * from './furniture/logic'; +export * from './furniture/mannequin'; +export * from './furniture/presents'; +export * from './furniture/toner'; +export * from './furniture/wall'; +export * from './furniture/youtube'; +export * from './layout'; +export * from './RedeemItemClothingComposer'; +export * from './session'; +export * from './unit'; +export * from './unit/chat'; diff --git a/packages/communication/src/messages/outgoing/room/layout/GetOccupiedTilesMessageComposer.ts b/packages/communication/src/messages/outgoing/room/layout/GetOccupiedTilesMessageComposer.ts new file mode 100644 index 0000000..1836f3d --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/layout/GetOccupiedTilesMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetOccupiedTilesMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/layout/GetRoomEntryDataMessageComposer.ts b/packages/communication/src/messages/outgoing/room/layout/GetRoomEntryDataMessageComposer.ts new file mode 100644 index 0000000..8252616 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/layout/GetRoomEntryDataMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetRoomEntryDataMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/layout/GetRoomEntryTileMessageComposer.ts b/packages/communication/src/messages/outgoing/room/layout/GetRoomEntryTileMessageComposer.ts new file mode 100644 index 0000000..604b893 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/layout/GetRoomEntryTileMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetRoomEntryTileMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/layout/UpdateFloorPropertiesMessageComposer.ts b/packages/communication/src/messages/outgoing/room/layout/UpdateFloorPropertiesMessageComposer.ts new file mode 100644 index 0000000..44b48d3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/layout/UpdateFloorPropertiesMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UpdateFloorPropertiesMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(model: string, doorX: number, doorY: number, doorDirection: number, thicknessWall: number, thicknessFloor: number, wallHeight: number) + { + this._data = [model, doorX, doorY, doorDirection, thicknessWall, thicknessFloor, wallHeight]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/layout/index.ts b/packages/communication/src/messages/outgoing/room/layout/index.ts new file mode 100644 index 0000000..e8a3d7c --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/layout/index.ts @@ -0,0 +1,4 @@ +export * from './GetOccupiedTilesMessageComposer'; +export * from './GetRoomEntryDataMessageComposer'; +export * from './GetRoomEntryTileMessageComposer'; +export * from './UpdateFloorPropertiesMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/room/pets/BreedPetsMessageComposer.ts b/packages/communication/src/messages/outgoing/room/pets/BreedPetsMessageComposer.ts new file mode 100644 index 0000000..cfb2cf4 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/pets/BreedPetsMessageComposer.ts @@ -0,0 +1,25 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class BreedPetsMessageComposer implements IMessageComposer> +{ + public static readonly STATE_START: number = 0; + public static readonly STATE_CANCEL: number = 1; + public static readonly STATE_ACCEPT: number = 2; + + private _data: ConstructorParameters; + + constructor(state: number, petOneId: number, petTwoId: number) + { + this._data = [state, petOneId, petTwoId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/pets/PetSelectedMessageComposer.ts b/packages/communication/src/messages/outgoing/room/pets/PetSelectedMessageComposer.ts new file mode 100644 index 0000000..1095897 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/pets/PetSelectedMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PetSelectedMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number) + { + this._data = [petId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/pets/index.ts b/packages/communication/src/messages/outgoing/room/pets/index.ts new file mode 100644 index 0000000..e53e7a0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/pets/index.ts @@ -0,0 +1,2 @@ +export * from './BreedPetsMessageComposer'; +export * from './PetSelectedMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/room/session/ChangeQueueMessageComposer.ts b/packages/communication/src/messages/outgoing/room/session/ChangeQueueMessageComposer.ts new file mode 100644 index 0000000..520461f --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/session/ChangeQueueMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ChangeQueueMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(targetQueue: number) + { + this._data = [targetQueue]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/session/GoToFlatMessageComposer.ts b/packages/communication/src/messages/outgoing/room/session/GoToFlatMessageComposer.ts new file mode 100644 index 0000000..bca45c5 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/session/GoToFlatMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GoToFlatMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [roomId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/session/index.ts b/packages/communication/src/messages/outgoing/room/session/index.ts new file mode 100644 index 0000000..990e23c --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/session/index.ts @@ -0,0 +1,2 @@ +export * from './ChangeQueueMessageComposer'; +export * from './GoToFlatMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/room/unit/RoomUnitActionComposer.ts b/packages/communication/src/messages/outgoing/room/unit/RoomUnitActionComposer.ts new file mode 100644 index 0000000..f5f0220 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/RoomUnitActionComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomUnitActionComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(actionType: number) + { + this._data = [actionType]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/RoomUnitDanceComposer.ts b/packages/communication/src/messages/outgoing/room/unit/RoomUnitDanceComposer.ts new file mode 100644 index 0000000..de43db9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/RoomUnitDanceComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomUnitDanceComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(danceType: number) + { + this._data = [danceType]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/RoomUnitDropHandItemComposer.ts b/packages/communication/src/messages/outgoing/room/unit/RoomUnitDropHandItemComposer.ts new file mode 100644 index 0000000..ffccd2a --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/RoomUnitDropHandItemComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomUnitDropHandItemComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/RoomUnitGiveHandItemComposer.ts b/packages/communication/src/messages/outgoing/room/unit/RoomUnitGiveHandItemComposer.ts new file mode 100644 index 0000000..713221c --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/RoomUnitGiveHandItemComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomUnitGiveHandItemComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(unitId: number) + { + this._data = [unitId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/RoomUnitGiveHandItemPetComposer.ts b/packages/communication/src/messages/outgoing/room/unit/RoomUnitGiveHandItemPetComposer.ts new file mode 100644 index 0000000..4f4a621 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/RoomUnitGiveHandItemPetComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomUnitGiveHandItemPetComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(unitId: number) + { + this._data = [unitId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/RoomUnitLookComposer.ts b/packages/communication/src/messages/outgoing/room/unit/RoomUnitLookComposer.ts new file mode 100644 index 0000000..ac3858c --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/RoomUnitLookComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/RoomUnitPostureComposer.ts b/packages/communication/src/messages/outgoing/room/unit/RoomUnitPostureComposer.ts new file mode 100644 index 0000000..902a6d2 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/RoomUnitPostureComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomUnitPostureComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(posture: number) + { + this._data = [posture]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/RoomUnitSignComposer.ts b/packages/communication/src/messages/outgoing/room/unit/RoomUnitSignComposer.ts new file mode 100644 index 0000000..0ac0e16 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/RoomUnitSignComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomUnitSignComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(signType: number) + { + this._data = [signType]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/RoomUnitWalkComposer.ts b/packages/communication/src/messages/outgoing/room/unit/RoomUnitWalkComposer.ts new file mode 100644 index 0000000..760e2b8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/RoomUnitWalkComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatComposer.ts b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatComposer.ts new file mode 100644 index 0000000..420d920 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatShoutComposer.ts b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatShoutComposer.ts new file mode 100644 index 0000000..6aa2265 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatShoutComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatStyleComposer.ts b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatStyleComposer.ts new file mode 100644 index 0000000..482f0fe --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatStyleComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatWhisperComposer.ts b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatWhisperComposer.ts new file mode 100644 index 0000000..8e02aff --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitChatWhisperComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitTypingStartComposer.ts b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitTypingStartComposer.ts new file mode 100644 index 0000000..1e4d635 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitTypingStartComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomUnitTypingStartComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitTypingStopComposer.ts b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitTypingStopComposer.ts new file mode 100644 index 0000000..fad82a0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/chat/RoomUnitTypingStopComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomUnitTypingStopComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/room/unit/chat/index.ts b/packages/communication/src/messages/outgoing/room/unit/chat/index.ts new file mode 100644 index 0000000..6e53b78 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/chat/index.ts @@ -0,0 +1,6 @@ +export * from './RoomUnitChatComposer'; +export * from './RoomUnitChatShoutComposer'; +export * from './RoomUnitChatStyleComposer'; +export * from './RoomUnitChatWhisperComposer'; +export * from './RoomUnitTypingStartComposer'; +export * from './RoomUnitTypingStopComposer'; diff --git a/packages/communication/src/messages/outgoing/room/unit/index.ts b/packages/communication/src/messages/outgoing/room/unit/index.ts new file mode 100644 index 0000000..52a7296 --- /dev/null +++ b/packages/communication/src/messages/outgoing/room/unit/index.ts @@ -0,0 +1,10 @@ +export * from './chat'; +export * from './RoomUnitActionComposer'; +export * from './RoomUnitDanceComposer'; +export * from './RoomUnitDropHandItemComposer'; +export * from './RoomUnitGiveHandItemComposer'; +export * from './RoomUnitGiveHandItemPetComposer'; +export * from './RoomUnitLookComposer'; +export * from './RoomUnitPostureComposer'; +export * from './RoomUnitSignComposer'; +export * from './RoomUnitWalkComposer'; diff --git a/packages/communication/src/messages/outgoing/roomdirectory/RoomNetworkOpenConnectionMessageComposer.ts b/packages/communication/src/messages/outgoing/roomdirectory/RoomNetworkOpenConnectionMessageComposer.ts new file mode 100644 index 0000000..5464bfd --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomdirectory/RoomNetworkOpenConnectionMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomNetworkOpenConnectionMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number) + { + this._data = [k, _arg_2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/roomdirectory/index.ts b/packages/communication/src/messages/outgoing/roomdirectory/index.ts new file mode 100644 index 0000000..4899347 --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomdirectory/index.ts @@ -0,0 +1 @@ +export * from './RoomNetworkOpenConnectionMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/roomevents/ApplySnapshotMessageComposer.ts b/packages/communication/src/messages/outgoing/roomevents/ApplySnapshotMessageComposer.ts new file mode 100644 index 0000000..17c1fdd --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomevents/ApplySnapshotMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ApplySnapshotMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(id: number) + { + this._data = [id]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/roomevents/OpenMessageComposer.ts b/packages/communication/src/messages/outgoing/roomevents/OpenMessageComposer.ts new file mode 100644 index 0000000..c32e5a0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomevents/OpenMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class OpenMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(id: number) + { + this._data = [id]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/roomevents/RoomMuteComposer.ts b/packages/communication/src/messages/outgoing/roomevents/RoomMuteComposer.ts new file mode 100644 index 0000000..7333076 --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomevents/RoomMuteComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomMuteComposer implements IMessageComposer +{ + private _data: unknown[]; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/roomevents/UpdateActionMessageComposer.ts b/packages/communication/src/messages/outgoing/roomevents/UpdateActionMessageComposer.ts new file mode 100644 index 0000000..b08dbd3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomevents/UpdateActionMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/roomevents/UpdateConditionMessageComposer.ts b/packages/communication/src/messages/outgoing/roomevents/UpdateConditionMessageComposer.ts new file mode 100644 index 0000000..35b3a60 --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomevents/UpdateConditionMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/roomevents/UpdateTriggerMessageComposer.ts b/packages/communication/src/messages/outgoing/roomevents/UpdateTriggerMessageComposer.ts new file mode 100644 index 0000000..21359f6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomevents/UpdateTriggerMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/roomevents/index.ts b/packages/communication/src/messages/outgoing/roomevents/index.ts new file mode 100644 index 0000000..9c4372e --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomevents/index.ts @@ -0,0 +1,6 @@ +export * from './ApplySnapshotMessageComposer'; +export * from './OpenMessageComposer'; +export * from './RoomMuteComposer'; +export * from './UpdateActionMessageComposer'; +export * from './UpdateConditionMessageComposer'; +export * from './UpdateTriggerMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/roomsettings/SaveableRoomSettingsData.ts b/packages/communication/src/messages/outgoing/roomsettings/SaveableRoomSettingsData.ts new file mode 100644 index 0000000..521045e --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomsettings/SaveableRoomSettingsData.ts @@ -0,0 +1,267 @@ +export class SaveableRoomSettingsData +{ + private _roomId: number; + private _name: string; + private _description: string; + private _doorMode: number; + private _password: string; + private _categoryId: number; + private _maximumVisitors: number; + private _tags: string[]; + private _tradeMode: number; + private _allowPets: boolean; + private _allowFoodConsume: boolean; + private _allowWalkThrough: boolean; + private _allowNavigatorDynCats: boolean; + private _hideWalls: boolean; + private _wallThickness: number; + private _floorThickness: number; + private _whoCanMute: number; + private _whoCanKick: number; + private _whoCanBan: number; + private _chatMode: number; + private _chatBubbleSize: number; + private _chatScrollUpFrequency: number; + private _chatFullHearRange: number; + private _chatFloodSensitivity: number; + + public get tradeMode(): number + { + return this._tradeMode; + } + + public set tradeMode(mode: number) + { + this._tradeMode = mode; + } + + public get allowPets(): boolean + { + return this._allowPets; + } + + public set allowPets(flag: boolean) + { + this._allowPets = flag; + } + + public get allowFoodConsume(): boolean + { + return this._allowFoodConsume; + } + + public set allowFoodConsume(flag: boolean) + { + this._allowFoodConsume = flag; + } + + public get allowWalkThrough(): boolean + { + return this._allowWalkThrough; + } + + public set allowWalkThrough(flag: boolean) + { + this._allowWalkThrough = flag; + } + + public get hideWalls(): boolean + { + return this._hideWalls; + } + + public set hideWalls(flag: boolean) + { + this._hideWalls = flag; + } + + public get wallThickness(): number + { + return this._wallThickness; + } + + public set wallThickness(thickness: number) + { + this._wallThickness = thickness; + } + + public get floorThickness(): number + { + return this._floorThickness; + } + + public set floorThickness(thickness: number) + { + this._floorThickness = thickness; + } + + public get roomId(): number + { + return this._roomId; + } + + public set roomId(id: number) + { + this._roomId = id; + } + + public get name(): string + { + return this._name; + } + + public set name(name: string) + { + this._name = name; + } + + public get description(): string + { + return this._description; + } + + public set description(description: string) + { + this._description = description; + } + + public get doorMode(): number + { + return this._doorMode; + } + + public set doorMode(mode: number) + { + this._doorMode = mode; + } + + public get password(): string + { + return this._password; + } + + public set password(password: string) + { + this._password = password; + } + + public get categoryId(): number + { + return this._categoryId; + } + + public set categoryId(id: number) + { + this._categoryId = id; + } + + public get maximumVisitors(): number + { + return this._maximumVisitors; + } + + public set maximumVisitors(max: number) + { + this._maximumVisitors = max; + } + + public get tags(): string[] + { + return this._tags; + } + + public set tags(tags: string[]) + { + this._tags = tags; + } + + public get whoCanMute(): number + { + return this._whoCanMute; + } + + public set whoCanMute(mute: number) + { + this._whoCanMute = mute; + } + + public get whoCanKick(): number + { + return this._whoCanKick; + } + + public set whoCanKick(kick: number) + { + this._whoCanKick = kick; + } + + public get whoCanBan(): number + { + return this._whoCanBan; + } + + public set whoCanBan(ban: number) + { + this._whoCanBan = ban; + } + + public get chatMode(): number + { + return this._chatMode; + } + + public set chatMode(mode: number) + { + this._chatMode = mode; + } + + public get chatBubbleSize(): number + { + return this._chatBubbleSize; + } + + public set chatBubbleSize(size: number) + { + this._chatBubbleSize = size; + } + + public get chatScrollUpFrequency(): number + { + return this._chatScrollUpFrequency; + } + + public set chatScrollUpFrequency(frequency: number) + { + this._chatScrollUpFrequency = frequency; + } + + public get chatFullHearRange(): number + { + return this._chatFullHearRange; + } + + public set chatFullHearRange(range: number) + { + this._chatFullHearRange = range; + } + + public get chatFloodSensitivity(): number + { + return this._chatFloodSensitivity; + } + + public set chatFloodSensitivity(sensitivity: number) + { + this._chatFloodSensitivity = sensitivity; + } + + public get allowNavigatorDynCats(): boolean + { + return this._allowNavigatorDynCats; + } + + public set allowNavigatorDynCats(flag: boolean) + { + this._allowNavigatorDynCats = flag; + } +} diff --git a/packages/communication/src/messages/outgoing/roomsettings/UpdateRoomCategoryAndTradeSettingsComposer.ts b/packages/communication/src/messages/outgoing/roomsettings/UpdateRoomCategoryAndTradeSettingsComposer.ts new file mode 100644 index 0000000..5e376f3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomsettings/UpdateRoomCategoryAndTradeSettingsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UpdateRoomCategoryAndTradeSettingsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg_2: number, _arg_3: number) + { + this._data = [k, _arg_2, _arg_3]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/roomsettings/index.ts b/packages/communication/src/messages/outgoing/roomsettings/index.ts new file mode 100644 index 0000000..21363c6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/roomsettings/index.ts @@ -0,0 +1,2 @@ +export * from './SaveableRoomSettingsData'; +export * from './UpdateRoomCategoryAndTradeSettingsComposer'; diff --git a/packages/communication/src/messages/outgoing/sound/AddJukeboxDiskComposer.ts b/packages/communication/src/messages/outgoing/sound/AddJukeboxDiskComposer.ts new file mode 100644 index 0000000..d4ce8ad --- /dev/null +++ b/packages/communication/src/messages/outgoing/sound/AddJukeboxDiskComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class AddJukeboxDiskComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, _arg2: number) + { + this._data = [k, _arg2]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/sound/GetJukeboxPlayListMessageComposer.ts b/packages/communication/src/messages/outgoing/sound/GetJukeboxPlayListMessageComposer.ts new file mode 100644 index 0000000..d889ae7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/sound/GetJukeboxPlayListMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetJukeboxPlayListMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/sound/GetNowPlayingMessageComposer.ts b/packages/communication/src/messages/outgoing/sound/GetNowPlayingMessageComposer.ts new file mode 100644 index 0000000..fffa9ed --- /dev/null +++ b/packages/communication/src/messages/outgoing/sound/GetNowPlayingMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetNowPlayingMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/sound/GetOfficialSongIdMessageComposer.ts b/packages/communication/src/messages/outgoing/sound/GetOfficialSongIdMessageComposer.ts new file mode 100644 index 0000000..d2de163 --- /dev/null +++ b/packages/communication/src/messages/outgoing/sound/GetOfficialSongIdMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetOfficialSongIdMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: string) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/sound/GetSongInfoMessageComposer.ts b/packages/communication/src/messages/outgoing/sound/GetSongInfoMessageComposer.ts new file mode 100644 index 0000000..ea18589 --- /dev/null +++ b/packages/communication/src/messages/outgoing/sound/GetSongInfoMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetSongInfoMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(...args: number[]) + { + this._data = [args.length].concat(args); + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/sound/GetSoundMachinePlayListMessageComposer.ts b/packages/communication/src/messages/outgoing/sound/GetSoundMachinePlayListMessageComposer.ts new file mode 100644 index 0000000..2c61be6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/sound/GetSoundMachinePlayListMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetSoundMachinePlayListMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/sound/GetSoundSettingsComposer.ts b/packages/communication/src/messages/outgoing/sound/GetSoundSettingsComposer.ts new file mode 100644 index 0000000..f8cf55f --- /dev/null +++ b/packages/communication/src/messages/outgoing/sound/GetSoundSettingsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetSoundSettingsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/sound/GetUserSongDisksMessageComposer.ts b/packages/communication/src/messages/outgoing/sound/GetUserSongDisksMessageComposer.ts new file mode 100644 index 0000000..677dad6 --- /dev/null +++ b/packages/communication/src/messages/outgoing/sound/GetUserSongDisksMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetUserSongDisksMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/sound/RemoveJukeboxDiskComposer.ts b/packages/communication/src/messages/outgoing/sound/RemoveJukeboxDiskComposer.ts new file mode 100644 index 0000000..93d14cf --- /dev/null +++ b/packages/communication/src/messages/outgoing/sound/RemoveJukeboxDiskComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RemoveJukeboxDiskComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/sound/index.ts b/packages/communication/src/messages/outgoing/sound/index.ts new file mode 100644 index 0000000..bb1dffd --- /dev/null +++ b/packages/communication/src/messages/outgoing/sound/index.ts @@ -0,0 +1,9 @@ +export * from './AddJukeboxDiskComposer'; +export * from './GetJukeboxPlayListMessageComposer'; +export * from './GetNowPlayingMessageComposer'; +export * from './GetOfficialSongIdMessageComposer'; +export * from './GetSongInfoMessageComposer'; +export * from './GetSoundMachinePlayListMessageComposer'; +export * from './GetSoundSettingsComposer'; +export * from './GetUserSongDisksMessageComposer'; +export * from './RemoveJukeboxDiskComposer'; diff --git a/packages/communication/src/messages/outgoing/talent/GetTalentTrackLevelMessageComposer.ts b/packages/communication/src/messages/outgoing/talent/GetTalentTrackLevelMessageComposer.ts new file mode 100644 index 0000000..7febf74 --- /dev/null +++ b/packages/communication/src/messages/outgoing/talent/GetTalentTrackLevelMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetTalentTrackLevelMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(name: string) + { + this._data = [name]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/talent/TalentTrackComposer.ts b/packages/communication/src/messages/outgoing/talent/TalentTrackComposer.ts new file mode 100644 index 0000000..2e0b977 --- /dev/null +++ b/packages/communication/src/messages/outgoing/talent/TalentTrackComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class TalentTrackComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(type: string) + { + this._data = [type]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/talent/index.ts b/packages/communication/src/messages/outgoing/talent/index.ts new file mode 100644 index 0000000..7d45f30 --- /dev/null +++ b/packages/communication/src/messages/outgoing/talent/index.ts @@ -0,0 +1,2 @@ +export * from './GetTalentTrackLevelMessageComposer'; +export * from './TalentTrackComposer'; diff --git a/packages/communication/src/messages/outgoing/tracking/LagWarningReportMessageComposer.ts b/packages/communication/src/messages/outgoing/tracking/LagWarningReportMessageComposer.ts new file mode 100644 index 0000000..9df3bdd --- /dev/null +++ b/packages/communication/src/messages/outgoing/tracking/LagWarningReportMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class LagWarningReportMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(warningCount: number) + { + this._data = [warningCount]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/tracking/PerformanceLogMessageComposer.ts b/packages/communication/src/messages/outgoing/tracking/PerformanceLogMessageComposer.ts new file mode 100644 index 0000000..e39624e --- /dev/null +++ b/packages/communication/src/messages/outgoing/tracking/PerformanceLogMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PerformanceLogMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, userAgent: string, flashVersion: string, operatingSystem: string, cpuArchitecture: string, isDebugger: boolean, totalMemory: number, _arg_8: number, gcCount: number, averageUpdateInterval: number, slowUpdateCount: number) + { + this._data = [k, userAgent, flashVersion, operatingSystem, cpuArchitecture, isDebugger, totalMemory, _arg_8, gcCount, averageUpdateInterval, slowUpdateCount]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/tracking/index.ts b/packages/communication/src/messages/outgoing/tracking/index.ts new file mode 100644 index 0000000..4a848a3 --- /dev/null +++ b/packages/communication/src/messages/outgoing/tracking/index.ts @@ -0,0 +1,2 @@ +export * from './LagWarningReportMessageComposer'; +export * from './PerformanceLogMessageComposer'; diff --git a/packages/communication/src/messages/outgoing/user/ApproveNameMessageComposer.ts b/packages/communication/src/messages/outgoing/user/ApproveNameMessageComposer.ts new file mode 100644 index 0000000..361ea3b --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/ApproveNameMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ApproveNameMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(name: string, type: number) + { + this._data = [name, type]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/CatalogGroupsComposer.ts b/packages/communication/src/messages/outgoing/user/CatalogGroupsComposer.ts new file mode 100644 index 0000000..8d1a54f --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/CatalogGroupsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class CatalogGroupsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/ChangeEmailComposer.ts b/packages/communication/src/messages/outgoing/user/ChangeEmailComposer.ts new file mode 100644 index 0000000..c5d50df --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/ChangeEmailComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ChangeEmailComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(newEmail: string) + { + this._data = [newEmail]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/GetEmailStatusComposer.ts b/packages/communication/src/messages/outgoing/user/GetEmailStatusComposer.ts new file mode 100644 index 0000000..b296d32 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/GetEmailStatusComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetEmailStatusComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/GetHabboGroupBadgesMessageComposer.ts b/packages/communication/src/messages/outgoing/user/GetHabboGroupBadgesMessageComposer.ts new file mode 100644 index 0000000..ed745bd --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/GetHabboGroupBadgesMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetHabboGroupBadgesMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/ScrGetKickbackInfoMessageComposer.ts b/packages/communication/src/messages/outgoing/user/ScrGetKickbackInfoMessageComposer.ts new file mode 100644 index 0000000..8843be0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/ScrGetKickbackInfoMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class ScrGetKickbackInfoMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/UnblockGroupMemberMessageComposer.ts b/packages/communication/src/messages/outgoing/user/UnblockGroupMemberMessageComposer.ts new file mode 100644 index 0000000..394ecdd --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/UnblockGroupMemberMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UnblockGroupMemberMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, userId: number) + { + this._data = [groupId, userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/UserRespectComposer.ts b/packages/communication/src/messages/outgoing/user/UserRespectComposer.ts new file mode 100644 index 0000000..fd4010e --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/UserRespectComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UserRespectComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/WelcomeGiftChangeEmailComposer.ts b/packages/communication/src/messages/outgoing/user/WelcomeGiftChangeEmailComposer.ts new file mode 100644 index 0000000..8b7e00a --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/WelcomeGiftChangeEmailComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class WelcomeGiftChangeEmailComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(newEmail: string) + { + this._data = [newEmail]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/data/GetExtendedProfileByNameMessageComposer.ts b/packages/communication/src/messages/outgoing/user/data/GetExtendedProfileByNameMessageComposer.ts new file mode 100644 index 0000000..040c011 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/GetExtendedProfileByNameMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetExtendedProfileByNameMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(username: string) + { + this._data = [username]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/data/GetIgnoredUsersComposer.ts b/packages/communication/src/messages/outgoing/user/data/GetIgnoredUsersComposer.ts new file mode 100644 index 0000000..42e4dc9 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/GetIgnoredUsersComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/user/data/GetUserTagsComposer.ts b/packages/communication/src/messages/outgoing/user/data/GetUserTagsComposer.ts new file mode 100644 index 0000000..2f388cd --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/GetUserTagsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class GetUserTagsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomUnitId: number) + { + this._data = [roomUnitId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/data/IgnoreUserComposer.ts b/packages/communication/src/messages/outgoing/user/data/IgnoreUserComposer.ts new file mode 100644 index 0000000..60c6b78 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/IgnoreUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/user/data/IgnoreUserIdComposer.ts b/packages/communication/src/messages/outgoing/user/data/IgnoreUserIdComposer.ts new file mode 100644 index 0000000..b179565 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/IgnoreUserIdComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/user/data/UnignoreUserComposer.ts b/packages/communication/src/messages/outgoing/user/data/UnignoreUserComposer.ts new file mode 100644 index 0000000..cf23616 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/UnignoreUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/user/data/UserCurrentBadgesComposer.ts b/packages/communication/src/messages/outgoing/user/data/UserCurrentBadgesComposer.ts new file mode 100644 index 0000000..6dfa156 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/UserCurrentBadgesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UserCurrentBadgesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/data/UserFigureComposer.ts b/packages/communication/src/messages/outgoing/user/data/UserFigureComposer.ts new file mode 100644 index 0000000..9df5006 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/UserFigureComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/outgoing/user/data/UserMottoComposer.ts b/packages/communication/src/messages/outgoing/user/data/UserMottoComposer.ts new file mode 100644 index 0000000..99b39b0 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/UserMottoComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UserMottoComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(motto: string) + { + this._data = [motto]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/data/UserProfileComposer.ts b/packages/communication/src/messages/outgoing/user/data/UserProfileComposer.ts new file mode 100644 index 0000000..9123053 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/UserProfileComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UserProfileComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number, flag: boolean = true) + { + this._data = [userId, flag]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/data/UserRelationshipsComposer.ts b/packages/communication/src/messages/outgoing/user/data/UserRelationshipsComposer.ts new file mode 100644 index 0000000..230771a --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/UserRelationshipsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UserRelationshipsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [userId]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/data/index.ts b/packages/communication/src/messages/outgoing/user/data/index.ts new file mode 100644 index 0000000..edc3289 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/data/index.ts @@ -0,0 +1,11 @@ +export * from './GetExtendedProfileByNameMessageComposer'; +export * from './GetIgnoredUsersComposer'; +export * from './GetUserTagsComposer'; +export * from './IgnoreUserComposer'; +export * from './IgnoreUserIdComposer'; +export * from './UnignoreUserComposer'; +export * from './UserCurrentBadgesComposer'; +export * from './UserFigureComposer'; +export * from './UserMottoComposer'; +export * from './UserProfileComposer'; +export * from './UserRelationshipsComposer'; diff --git a/packages/communication/src/messages/outgoing/user/index.ts b/packages/communication/src/messages/outgoing/user/index.ts new file mode 100644 index 0000000..9a10b1f --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/index.ts @@ -0,0 +1,14 @@ +export * from './ApproveNameMessageComposer'; +export * from './CatalogGroupsComposer'; +export * from './ChangeEmailComposer'; +export * from './data'; +export * from './GetEmailStatusComposer'; +export * from './GetHabboGroupBadgesMessageComposer'; +export * from './inventory'; +export * from './inventory/currency'; +export * from './inventory/subscription'; +export * from './ScrGetKickbackInfoMessageComposer'; +export * from './settings'; +export * from './UnblockGroupMemberMessageComposer'; +export * from './UserRespectComposer'; +export * from './WelcomeGiftChangeEmailComposer'; diff --git a/packages/communication/src/messages/outgoing/user/inventory/currency/UserCurrencyComposer.ts b/packages/communication/src/messages/outgoing/user/inventory/currency/UserCurrencyComposer.ts new file mode 100644 index 0000000..39d2a6a --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/inventory/currency/UserCurrencyComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UserCurrencyComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/inventory/currency/index.ts b/packages/communication/src/messages/outgoing/user/inventory/currency/index.ts new file mode 100644 index 0000000..5949cbb --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/inventory/currency/index.ts @@ -0,0 +1 @@ +export * from './UserCurrencyComposer'; diff --git a/packages/communication/src/messages/outgoing/user/inventory/index.ts b/packages/communication/src/messages/outgoing/user/inventory/index.ts new file mode 100644 index 0000000..e25bf08 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/inventory/index.ts @@ -0,0 +1,2 @@ +export * from './currency'; +export * from './subscription'; diff --git a/packages/communication/src/messages/outgoing/user/inventory/subscription/UserSubscriptionComposer.ts b/packages/communication/src/messages/outgoing/user/inventory/subscription/UserSubscriptionComposer.ts new file mode 100644 index 0000000..2bc4f00 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/inventory/subscription/UserSubscriptionComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class UserSubscriptionComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(type: string) + { + this._data = [type]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/user/inventory/subscription/index.ts b/packages/communication/src/messages/outgoing/user/inventory/subscription/index.ts new file mode 100644 index 0000000..34fd638 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/inventory/subscription/index.ts @@ -0,0 +1 @@ +export * from './UserSubscriptionComposer'; diff --git a/packages/communication/src/messages/outgoing/user/settings/UserSettingsCameraFollowComposer.ts b/packages/communication/src/messages/outgoing/user/settings/UserSettingsCameraFollowComposer.ts new file mode 100644 index 0000000..0b24eb8 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/settings/UserSettingsCameraFollowComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/user/settings/UserSettingsOldChatComposer.ts b/packages/communication/src/messages/outgoing/user/settings/UserSettingsOldChatComposer.ts new file mode 100644 index 0000000..96bdca7 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/settings/UserSettingsOldChatComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/user/settings/UserSettingsRoomInvitesComposer.ts b/packages/communication/src/messages/outgoing/user/settings/UserSettingsRoomInvitesComposer.ts new file mode 100644 index 0000000..1f14a15 --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/settings/UserSettingsRoomInvitesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/user/settings/UserSettingsSoundComposer.ts b/packages/communication/src/messages/outgoing/user/settings/UserSettingsSoundComposer.ts new file mode 100644 index 0000000..c71c34d --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/settings/UserSettingsSoundComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +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/packages/communication/src/messages/outgoing/user/settings/index.ts b/packages/communication/src/messages/outgoing/user/settings/index.ts new file mode 100644 index 0000000..fefcdbc --- /dev/null +++ b/packages/communication/src/messages/outgoing/user/settings/index.ts @@ -0,0 +1,4 @@ +export * from './UserSettingsCameraFollowComposer'; +export * from './UserSettingsOldChatComposer'; +export * from './UserSettingsRoomInvitesComposer'; +export * from './UserSettingsSoundComposer'; diff --git a/packages/communication/src/messages/outgoing/userclassification/PeerUsersClassificationMessageComposer.ts b/packages/communication/src/messages/outgoing/userclassification/PeerUsersClassificationMessageComposer.ts new file mode 100644 index 0000000..0b3f092 --- /dev/null +++ b/packages/communication/src/messages/outgoing/userclassification/PeerUsersClassificationMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class PeerUsersClassificationMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userClassType: string) + { + this._data = [userClassType]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/userclassification/RoomUsersClassificationMessageComposer.ts b/packages/communication/src/messages/outgoing/userclassification/RoomUsersClassificationMessageComposer.ts new file mode 100644 index 0000000..525db35 --- /dev/null +++ b/packages/communication/src/messages/outgoing/userclassification/RoomUsersClassificationMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '@nitrots/api'; + +export class RoomUsersClassificationMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userClassType: string) + { + this._data = [userClassType]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/packages/communication/src/messages/outgoing/userclassification/index.ts b/packages/communication/src/messages/outgoing/userclassification/index.ts new file mode 100644 index 0000000..0dc5c96 --- /dev/null +++ b/packages/communication/src/messages/outgoing/userclassification/index.ts @@ -0,0 +1,2 @@ +export * from './PeerUsersClassificationMessageComposer'; +export * from './RoomUsersClassificationMessageComposer'; diff --git a/packages/communication/src/messages/parser/advertisement/InterstitialMessageParser.ts b/packages/communication/src/messages/parser/advertisement/InterstitialMessageParser.ts new file mode 100644 index 0000000..86f7fae --- /dev/null +++ b/packages/communication/src/messages/parser/advertisement/InterstitialMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class InterstitialMessageParser implements IMessageParser +{ + private _canShowInterstitial: boolean; + + public flush(): boolean + { + this._canShowInterstitial = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._canShowInterstitial = wrapper.readBoolean(); + + return true; + } + + public get canShowInterstitial(): boolean + { + return this._canShowInterstitial; + } +} diff --git a/packages/communication/src/messages/parser/advertisement/RoomAdErrorMessageParser.ts b/packages/communication/src/messages/parser/advertisement/RoomAdErrorMessageParser.ts new file mode 100644 index 0000000..83d816f --- /dev/null +++ b/packages/communication/src/messages/parser/advertisement/RoomAdErrorMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomAdErrorMessageParser implements IMessageParser +{ + private _errorCode: number; + private _filteredText: string; + + public flush(): boolean + { + this._errorCode = 0; + this._filteredText = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._errorCode = wrapper.readInt(); + this._filteredText = wrapper.readString(); + + return true; + } + + public get errorCode(): number + { + return this._errorCode; + } + + public get filteredText(): string + { + return this._filteredText; + } +} diff --git a/packages/communication/src/messages/parser/advertisement/index.ts b/packages/communication/src/messages/parser/advertisement/index.ts new file mode 100644 index 0000000..d7b6995 --- /dev/null +++ b/packages/communication/src/messages/parser/advertisement/index.ts @@ -0,0 +1,2 @@ +export * from './InterstitialMessageParser'; +export * from './RoomAdErrorMessageParser'; diff --git a/packages/communication/src/messages/parser/availability/AvailabilityStatusMessageParser.ts b/packages/communication/src/messages/parser/availability/AvailabilityStatusMessageParser.ts new file mode 100644 index 0000000..793a0bc --- /dev/null +++ b/packages/communication/src/messages/parser/availability/AvailabilityStatusMessageParser.ts @@ -0,0 +1,47 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/availability/AvailabilityTimeMessageParser.ts b/packages/communication/src/messages/parser/availability/AvailabilityTimeMessageParser.ts new file mode 100644 index 0000000..ffb7007 --- /dev/null +++ b/packages/communication/src/messages/parser/availability/AvailabilityTimeMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class AvailabilityTimeMessageParser implements IMessageParser +{ + private _isOpen: boolean; + private _minutesUntilChange: number; + + public flush(): boolean + { + this._isOpen = false; + this._minutesUntilChange = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._isOpen = (wrapper.readInt() > 0); + this._minutesUntilChange = wrapper.readInt(); + + return true; + } + + public get isOpen(): boolean + { + return this._isOpen; + } + + public get minutesUntilChange(): number + { + return this._minutesUntilChange; + } +} diff --git a/packages/communication/src/messages/parser/availability/HotelClosedAndOpensMessageParser.ts b/packages/communication/src/messages/parser/availability/HotelClosedAndOpensMessageParser.ts new file mode 100644 index 0000000..6bdbace --- /dev/null +++ b/packages/communication/src/messages/parser/availability/HotelClosedAndOpensMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class HotelClosedAndOpensMessageParser implements IMessageParser +{ + private _openHour: number; + private _openMinute: number; + + public flush(): boolean + { + this._openHour = 0; + this._openMinute = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._openHour = wrapper.readInt(); + this._openMinute = wrapper.readInt(); + + return true; + } + + public get openHour(): number + { + return this._openHour; + } + + public get openMinute(): number + { + return this._openMinute; + } +} diff --git a/packages/communication/src/messages/parser/availability/HotelClosesAndWillOpenAtMessageParser.ts b/packages/communication/src/messages/parser/availability/HotelClosesAndWillOpenAtMessageParser.ts new file mode 100644 index 0000000..cf0ac90 --- /dev/null +++ b/packages/communication/src/messages/parser/availability/HotelClosesAndWillOpenAtMessageParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class HotelClosesAndWillOpenAtMessageParser implements IMessageParser +{ + private _openHour: number; + private _openMinute: number; + private _userThrownOutAtClose: boolean; + + public flush(): boolean + { + this._openHour = 0; + this._openMinute = 0; + this._userThrownOutAtClose = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._openHour = wrapper.readInt(); + this._openMinute = wrapper.readInt(); + this._userThrownOutAtClose = wrapper.readBoolean(); + + return true; + } + + public get openHour(): number + { + return this._openHour; + } + + public get openMinute(): number + { + return this._openMinute; + } + + public get userThrowOutAtClose(): boolean + { + return this._userThrownOutAtClose; + } +} diff --git a/packages/communication/src/messages/parser/availability/HotelWillCloseInMinutesMessageParser.ts b/packages/communication/src/messages/parser/availability/HotelWillCloseInMinutesMessageParser.ts new file mode 100644 index 0000000..a67cd31 --- /dev/null +++ b/packages/communication/src/messages/parser/availability/HotelWillCloseInMinutesMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class HotelWillCloseInMinutesMessageParser implements IMessageParser +{ + private _minutes: number; + + public flush(): boolean + { + this._minutes = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._minutes = wrapper.readInt(); + + return true; + } + + public get openMinute(): number + { + return this._minutes; + } +} diff --git a/packages/communication/src/messages/parser/availability/MaintenanceStatusMessageParser.ts b/packages/communication/src/messages/parser/availability/MaintenanceStatusMessageParser.ts new file mode 100644 index 0000000..7168910 --- /dev/null +++ b/packages/communication/src/messages/parser/availability/MaintenanceStatusMessageParser.ts @@ -0,0 +1,47 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class MaintenanceStatusMessageParser implements IMessageParser +{ + private _isInMaintenance: boolean; + private _minutesUntilMaintenance: number; + private _duration: number; + + public flush(): boolean + { + this._isInMaintenance = false; + this._minutesUntilMaintenance = 0; + this._duration = 15; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._isInMaintenance = wrapper.readBoolean(); + this._minutesUntilMaintenance = wrapper.readInt(); + + if(wrapper.bytesAvailable) + { + this._duration = wrapper.readInt(); + } + + return true; + } + + public get isInMaintenance(): boolean + { + return this._isInMaintenance; + } + + public get minutesUntilMaintenance(): number + { + return this._minutesUntilMaintenance; + } + + public get duration(): number + { + return this._duration; + } +} diff --git a/packages/communication/src/messages/parser/availability/index.ts b/packages/communication/src/messages/parser/availability/index.ts new file mode 100644 index 0000000..4f61945 --- /dev/null +++ b/packages/communication/src/messages/parser/availability/index.ts @@ -0,0 +1,6 @@ +export * from './AvailabilityStatusMessageParser'; +export * from './AvailabilityTimeMessageParser'; +export * from './HotelClosedAndOpensMessageParser'; +export * from './HotelClosesAndWillOpenAtMessageParser'; +export * from './HotelWillCloseInMinutesMessageParser'; +export * from './MaintenanceStatusMessageParser'; diff --git a/packages/communication/src/messages/parser/avatar/ChangeUserNameResultMessageParser.ts b/packages/communication/src/messages/parser/avatar/ChangeUserNameResultMessageParser.ts new file mode 100644 index 0000000..0c261e7 --- /dev/null +++ b/packages/communication/src/messages/parser/avatar/ChangeUserNameResultMessageParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ChangeUserNameResultMessageParser implements IMessageParser +{ + private _resultCode: number; + private _name: string; + private _nameSuggestions: string[]; + + 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; + } +} diff --git a/packages/communication/src/messages/parser/avatar/CheckUserNameResultMessageParser.ts b/packages/communication/src/messages/parser/avatar/CheckUserNameResultMessageParser.ts new file mode 100644 index 0000000..649220d --- /dev/null +++ b/packages/communication/src/messages/parser/avatar/CheckUserNameResultMessageParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CheckUserNameResultMessageParser implements IMessageParser +{ + private _resultCode: number; + private _name: string; + private _nameSuggestions: string[]; + + 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; + } +} diff --git a/packages/communication/src/messages/parser/avatar/FigureUpdateParser.ts b/packages/communication/src/messages/parser/avatar/FigureUpdateParser.ts new file mode 100644 index 0000000..952375f --- /dev/null +++ b/packages/communication/src/messages/parser/avatar/FigureUpdateParser.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FigureUpdateParser implements IMessageParser +{ + private _figure: string; + private _gender: string; + + public flush(): boolean + { + this._figure = ''; + this._gender = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._figure = wrapper.readString(); + this._gender = wrapper.readString(); + + if(this._gender) this._gender = this._gender.toUpperCase(); + + return true; + } + + public get figure(): string + { + return this._figure; + } + + public get gender(): string + { + return this._gender; + } +} diff --git a/packages/communication/src/messages/parser/avatar/OutfitData.ts b/packages/communication/src/messages/parser/avatar/OutfitData.ts new file mode 100644 index 0000000..de24fb9 --- /dev/null +++ b/packages/communication/src/messages/parser/avatar/OutfitData.ts @@ -0,0 +1,30 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class OutfitData +{ + private _slotId: number; + private _figureString: string; + private _gender: string; + + constructor(wrapper: IMessageDataWrapper) + { + this._slotId = wrapper.readInt(); + this._figureString = wrapper.readString(); + this._gender = wrapper.readString(); + } + + public get slotId(): number + { + return this._slotId; + } + + public get figureString(): string + { + return this._figureString; + } + + public get gender(): string + { + return this._gender; + } +} diff --git a/packages/communication/src/messages/parser/avatar/WardrobeMessageParser.ts b/packages/communication/src/messages/parser/avatar/WardrobeMessageParser.ts new file mode 100644 index 0000000..67551e2 --- /dev/null +++ b/packages/communication/src/messages/parser/avatar/WardrobeMessageParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { OutfitData } from './OutfitData'; + +export class WardrobeMessageParser implements IMessageParser +{ + private _state: number; + private _outfits: OutfitData[]; + + public flush(): boolean + { + this._state = 0; + this._outfits = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._state = wrapper.readInt(); + + let count = wrapper.readInt(); + + while(count > 0) + { + this._outfits.push(new OutfitData(wrapper)); + + count--; + } + + return true; + } + + public get state(): number + { + return this._state; + } + + public get outfits(): OutfitData[] + { + return this._outfits; + } +} diff --git a/packages/communication/src/messages/parser/avatar/index.ts b/packages/communication/src/messages/parser/avatar/index.ts new file mode 100644 index 0000000..ca0d335 --- /dev/null +++ b/packages/communication/src/messages/parser/avatar/index.ts @@ -0,0 +1,5 @@ +export * from './ChangeUserNameResultMessageParser'; +export * from './CheckUserNameResultMessageParser'; +export * from './FigureUpdateParser'; +export * from './OutfitData'; +export * from './WardrobeMessageParser'; diff --git a/packages/communication/src/messages/parser/bots/BotAddedToInventoryParser.ts b/packages/communication/src/messages/parser/bots/BotAddedToInventoryParser.ts new file mode 100644 index 0000000..62a74b1 --- /dev/null +++ b/packages/communication/src/messages/parser/bots/BotAddedToInventoryParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/bots/BotData.ts b/packages/communication/src/messages/parser/bots/BotData.ts new file mode 100644 index 0000000..0254732 --- /dev/null +++ b/packages/communication/src/messages/parser/bots/BotData.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/bots/BotInventoryMessageParser.ts b/packages/communication/src/messages/parser/bots/BotInventoryMessageParser.ts new file mode 100644 index 0000000..a4e8585 --- /dev/null +++ b/packages/communication/src/messages/parser/bots/BotInventoryMessageParser.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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/packages/communication/src/messages/parser/bots/BotReceivedMessageParser.ts b/packages/communication/src/messages/parser/bots/BotReceivedMessageParser.ts new file mode 100644 index 0000000..1d9abdb --- /dev/null +++ b/packages/communication/src/messages/parser/bots/BotReceivedMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { BotData } from './BotData'; + +export class BotReceivedMessageParser 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/packages/communication/src/messages/parser/bots/BotRemovedFromInventoryParser.ts b/packages/communication/src/messages/parser/bots/BotRemovedFromInventoryParser.ts new file mode 100644 index 0000000..4a9e0ea --- /dev/null +++ b/packages/communication/src/messages/parser/bots/BotRemovedFromInventoryParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/bots/index.ts b/packages/communication/src/messages/parser/bots/index.ts new file mode 100644 index 0000000..1224c4e --- /dev/null +++ b/packages/communication/src/messages/parser/bots/index.ts @@ -0,0 +1,5 @@ +export * from './BotAddedToInventoryParser'; +export * from './BotData'; +export * from './BotInventoryMessageParser'; +export * from './BotReceivedMessageParser'; +export * from './BotRemovedFromInventoryParser'; diff --git a/packages/communication/src/messages/parser/callforhelp/CallForHelpCategoryData.ts b/packages/communication/src/messages/parser/callforhelp/CallForHelpCategoryData.ts new file mode 100644 index 0000000..be7e98d --- /dev/null +++ b/packages/communication/src/messages/parser/callforhelp/CallForHelpCategoryData.ts @@ -0,0 +1,48 @@ +import { IDisposable, IMessageDataWrapper } from '@nitrots/api'; +import { INamed } from '../moderation'; +import { CallForHelpTopicData } from './CallForHelpTopicData'; + +export class CallForHelpCategoryData implements INamed, IDisposable +{ + private _name: string; + private _topics: CallForHelpTopicData[]; + private _disposed: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + this._topics = []; + this._name = wrapper.readString(); + + let count = wrapper.readInt(); + + while(count > 0) + { + this._topics.push(new CallForHelpTopicData(wrapper)); + + count--; + } + } + + public dispose(): void + { + if(this._disposed) return; + + this._disposed = true; + this._topics = null; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public get name(): string + { + return this._name; + } + + public get topics(): CallForHelpTopicData[] + { + return this._topics; + } +} diff --git a/packages/communication/src/messages/parser/callforhelp/CallForHelpTopicData.ts b/packages/communication/src/messages/parser/callforhelp/CallForHelpTopicData.ts new file mode 100644 index 0000000..9171f2b --- /dev/null +++ b/packages/communication/src/messages/parser/callforhelp/CallForHelpTopicData.ts @@ -0,0 +1,31 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { INamed } from '../moderation'; + +export class CallForHelpTopicData implements INamed +{ + private _name: string; + private _id: number; + private _consequence: string; + + constructor(wrapper: IMessageDataWrapper) + { + this._name = wrapper.readString(); + this._id = wrapper.readInt(); + this._consequence = wrapper.readString(); + } + + public get name(): string + { + return this._name; + } + + public get id(): number + { + return this._id; + } + + public get consequence(): string + { + return this._consequence; + } +} diff --git a/packages/communication/src/messages/parser/callforhelp/CfhSanctionMessageParser.ts b/packages/communication/src/messages/parser/callforhelp/CfhSanctionMessageParser.ts new file mode 100644 index 0000000..aea9d0c --- /dev/null +++ b/packages/communication/src/messages/parser/callforhelp/CfhSanctionMessageParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CfhSanctionTypeData } from './CfhSanctionTypeData'; + +export class CfhSanctionMessageParser implements IMessageParser +{ + private _issueId: number; + private _accountId: number; + private _sanctionType: CfhSanctionTypeData; + + public flush(): boolean + { + this._issueId = -1; + this._accountId = 1; + this._sanctionType = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._issueId = wrapper.readInt(); + this._accountId = wrapper.readInt(); + this._sanctionType = new CfhSanctionTypeData(wrapper); + + return true; + } + + public get issueId(): number + { + return this._issueId; + } + + public get accountId(): number + { + return this._accountId; + } + + public get sanctionType(): CfhSanctionTypeData + { + return this._sanctionType; + } +} diff --git a/packages/communication/src/messages/parser/callforhelp/CfhSanctionTypeData.ts b/packages/communication/src/messages/parser/callforhelp/CfhSanctionTypeData.ts new file mode 100644 index 0000000..d205414 --- /dev/null +++ b/packages/communication/src/messages/parser/callforhelp/CfhSanctionTypeData.ts @@ -0,0 +1,49 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { INamed } from '../moderation'; + +export class CfhSanctionTypeData implements INamed +{ + private _name: string; + private _sanctionLengthInHours: number; + private _probationDays: number; + private _avatarOnly: boolean; + private _tradeLockInfo: string = ''; + private _machineBanInfo: string = ''; + + constructor(wrapper: IMessageDataWrapper) + { + this._name = wrapper.readString(); + this._sanctionLengthInHours = wrapper.readInt(); + this._probationDays = wrapper.readInt(); + this._avatarOnly = wrapper.readBoolean(); + + if(wrapper.bytesAvailable) this._tradeLockInfo = wrapper.readString(); + + if(wrapper.bytesAvailable) this._machineBanInfo = wrapper.readString(); + } + + public get name(): string + { + return this._name; + } + + public get sanctionLengthInHours(): number + { + return this._sanctionLengthInHours; + } + + public get avatarOnly(): boolean + { + return this._avatarOnly; + } + + public get tradeLockInfo(): string + { + return this._tradeLockInfo; + } + + public get machineBanInfo(): string + { + return this._machineBanInfo; + } +} diff --git a/packages/communication/src/messages/parser/callforhelp/CfhTopicsInitMessageParser.ts b/packages/communication/src/messages/parser/callforhelp/CfhTopicsInitMessageParser.ts new file mode 100644 index 0000000..6d6abd8 --- /dev/null +++ b/packages/communication/src/messages/parser/callforhelp/CfhTopicsInitMessageParser.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CallForHelpCategoryData } from './CallForHelpCategoryData'; + +export class CfhTopicsInitMessageParser implements IMessageParser +{ + private _callForHelpCategories: CallForHelpCategoryData[]; + + public flush(): boolean + { + this._callForHelpCategories = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._callForHelpCategories = []; + + let count = wrapper.readInt(); + + while(count > 0) + { + this._callForHelpCategories.push(new CallForHelpCategoryData(wrapper)); + + count--; + } + + return true; + } + + public get callForHelpCategories(): CallForHelpCategoryData[] + { + return this._callForHelpCategories; + } +} diff --git a/packages/communication/src/messages/parser/callforhelp/SanctionStatusMessageParser.ts b/packages/communication/src/messages/parser/callforhelp/SanctionStatusMessageParser.ts new file mode 100644 index 0000000..2585034 --- /dev/null +++ b/packages/communication/src/messages/parser/callforhelp/SanctionStatusMessageParser.ts @@ -0,0 +1,114 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class SanctionStatusMessageParser implements IMessageParser +{ + private _isSanctionNew: boolean; + private _isSanctionActive: boolean; + private _sanctionName: string; + private _sanctionLengthHours: number; + private _sanctionReason: string; + private _sanctionCreationTime: string; + private _probationHoursLeft: number; + private _nextSanctionName: string; + private _nextSanctionLengthHours: number; + private _hasCustomMute: boolean; + private _tradeLockExpiryTime: string; + + public flush(): boolean + { + this._isSanctionNew = false; + this._isSanctionActive = false; + this._sanctionName = null; + this._sanctionLengthHours = 0; + this._sanctionReason = null; + this._sanctionCreationTime = null; + this._probationHoursLeft = 0; + this._nextSanctionName = null; + this._nextSanctionLengthHours = 0; + this._hasCustomMute = false; + this._tradeLockExpiryTime = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._isSanctionNew = wrapper.readBoolean(); + this._isSanctionActive = wrapper.readBoolean(); + this._sanctionName = wrapper.readString(); + this._sanctionLengthHours = wrapper.readInt(); + + wrapper.readInt(); + + this._sanctionReason = wrapper.readString(); + this._sanctionCreationTime = wrapper.readString(); + this._probationHoursLeft = wrapper.readInt(); + this._nextSanctionName = wrapper.readString(); + this._nextSanctionLengthHours = wrapper.readInt(); + + wrapper.readInt(); + + this._hasCustomMute = wrapper.readBoolean(); + + if(wrapper.bytesAvailable) this._tradeLockExpiryTime = wrapper.readString(); + + return true; + } + + public get isSanctionNew(): boolean + { + return this._isSanctionNew; + } + + public get isSanctionActive(): boolean + { + return this._isSanctionActive; + } + + public get sanctionName(): string + { + return this._sanctionName; + } + + public get sanctionLengthHours(): number + { + return this._sanctionLengthHours; + } + + public get sanctionReason(): string + { + return this._sanctionReason; + } + + public get sanctionCreationTime(): string + { + return this._sanctionCreationTime; + } + + public get probationHoursLeft(): number + { + return this._probationHoursLeft; + } + + public get nextSanctionName(): string + { + return this._nextSanctionName; + } + + public get nextSanctionLengthHours(): number + { + return this._nextSanctionLengthHours; + } + + public get hasCustomMute(): boolean + { + return this._hasCustomMute; + } + + public get tradeLockExpiryTime(): string + { + return this._tradeLockExpiryTime; + } +} diff --git a/packages/communication/src/messages/parser/callforhelp/index.ts b/packages/communication/src/messages/parser/callforhelp/index.ts new file mode 100644 index 0000000..578158f --- /dev/null +++ b/packages/communication/src/messages/parser/callforhelp/index.ts @@ -0,0 +1,6 @@ +export * from './CallForHelpCategoryData'; +export * from './CallForHelpTopicData'; +export * from './CfhSanctionMessageParser'; +export * from './CfhSanctionTypeData'; +export * from './CfhTopicsInitMessageParser'; +export * from './SanctionStatusMessageParser'; diff --git a/packages/communication/src/messages/parser/camera/CameraPublishStatusMessageParser.ts b/packages/communication/src/messages/parser/camera/CameraPublishStatusMessageParser.ts new file mode 100644 index 0000000..65d6223 --- /dev/null +++ b/packages/communication/src/messages/parser/camera/CameraPublishStatusMessageParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CameraPublishStatusMessageParser implements IMessageParser +{ + private _ok: boolean = false; + private _secondsToWait: number = 0; + private _extraDataId: string; + + public flush(): boolean + { + this._ok = false; + this._secondsToWait = 0; + this._extraDataId = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._ok = wrapper.readBoolean(); + this._secondsToWait = wrapper.readInt(); + + if(this._ok && wrapper.bytesAvailable) this._extraDataId = wrapper.readString(); + + return true; + } + + public get ok(): boolean + { + return this._ok; + } + + public get secondsToWait(): number + { + return this._secondsToWait; + } + + public get extraDataId(): string + { + return this._extraDataId; + } +} diff --git a/packages/communication/src/messages/parser/camera/CameraPurchaseOKMessageParser.ts b/packages/communication/src/messages/parser/camera/CameraPurchaseOKMessageParser.ts new file mode 100644 index 0000000..f35b516 --- /dev/null +++ b/packages/communication/src/messages/parser/camera/CameraPurchaseOKMessageParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CameraPurchaseOKMessageParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/camera/CameraSnapshotMessageParser.ts b/packages/communication/src/messages/parser/camera/CameraSnapshotMessageParser.ts new file mode 100644 index 0000000..93467f9 --- /dev/null +++ b/packages/communication/src/messages/parser/camera/CameraSnapshotMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CameraSnapshotMessageParser implements IMessageParser +{ + private _roomType: string; + private _roomId: number; + + public flush(): boolean + { + this._roomType = null; + this._roomId = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomType = wrapper.readString(); + this._roomId = wrapper.readInt(); + + return true; + } + + public get roomType(): string + { + return this._roomType; + } + + public get roomId(): number + { + return this._roomId; + } +} diff --git a/packages/communication/src/messages/parser/camera/CameraStorageUrlMessageParser.ts b/packages/communication/src/messages/parser/camera/CameraStorageUrlMessageParser.ts new file mode 100644 index 0000000..e9e94b3 --- /dev/null +++ b/packages/communication/src/messages/parser/camera/CameraStorageUrlMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CameraStorageUrlMessageParser implements IMessageParser +{ + private _url: string; + + public flush(): boolean + { + this._url = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._url = wrapper.readString(); + + return true; + } + + public get url(): string + { + return this._url; + } +} diff --git a/packages/communication/src/messages/parser/camera/CompetitionStatusMessageParser.ts b/packages/communication/src/messages/parser/camera/CompetitionStatusMessageParser.ts new file mode 100644 index 0000000..b9f69e7 --- /dev/null +++ b/packages/communication/src/messages/parser/camera/CompetitionStatusMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CompetitionStatusMessageParser implements IMessageParser +{ + private _ok: boolean = false; + private _errorReason: string = null; + + public flush(): boolean + { + this._ok = false; + this._errorReason = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._ok = wrapper.readBoolean(); + this._errorReason = wrapper.readString(); + + return true; + } + + public get ok(): boolean + { + return this._ok; + } + + public get errorReason(): string + { + return this._errorReason; + } +} diff --git a/packages/communication/src/messages/parser/camera/InitCameraMessageParser.ts b/packages/communication/src/messages/parser/camera/InitCameraMessageParser.ts new file mode 100644 index 0000000..2f12198 --- /dev/null +++ b/packages/communication/src/messages/parser/camera/InitCameraMessageParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class InitCameraMessageParser implements IMessageParser +{ + private _creditPrice: number = 0; + private _ducketPrice: number = 0; + private _publishDucketPrice: number = 0; + + public flush(): boolean + { + this._creditPrice = 0; + this._ducketPrice = 0; + this._publishDucketPrice = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._creditPrice = wrapper.readInt(); + this._ducketPrice = wrapper.readInt(); + + if(wrapper.bytesAvailable) this._publishDucketPrice = wrapper.readInt(); + + return true; + } + + public get creditPrice(): number + { + return this._creditPrice; + } + + public get ducketPrice(): number + { + return this._ducketPrice; + } + + public get publishDucketPrice(): number + { + return this._publishDucketPrice; + } +} diff --git a/packages/communication/src/messages/parser/camera/ThumbnailStatusMessageParser.ts b/packages/communication/src/messages/parser/camera/ThumbnailStatusMessageParser.ts new file mode 100644 index 0000000..60d0d0d --- /dev/null +++ b/packages/communication/src/messages/parser/camera/ThumbnailStatusMessageParser.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ThumbnailStatusMessageParser implements IMessageParser +{ + private _ok: boolean = true; + private _renderLimitHit: boolean = false; + + public flush(): boolean + { + this._ok = true; + this._renderLimitHit = false; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + if(wrapper.bytesAvailable) + { + this._ok = wrapper.readBoolean(); + this._renderLimitHit = wrapper.readBoolean(); + } + + return true; + } + + public get ok(): boolean + { + return this._ok; + } + + public get isRenderLimitHit(): boolean + { + return this._renderLimitHit; + } +} diff --git a/packages/communication/src/messages/parser/camera/index.ts b/packages/communication/src/messages/parser/camera/index.ts new file mode 100644 index 0000000..8215d77 --- /dev/null +++ b/packages/communication/src/messages/parser/camera/index.ts @@ -0,0 +1,7 @@ +export * from './CameraPublishStatusMessageParser'; +export * from './CameraPurchaseOKMessageParser'; +export * from './CameraSnapshotMessageParser'; +export * from './CameraStorageUrlMessageParser'; +export * from './CompetitionStatusMessageParser'; +export * from './InitCameraMessageParser'; +export * from './ThumbnailStatusMessageParser'; diff --git a/packages/communication/src/messages/parser/campaign/CampaignCalendarData.ts b/packages/communication/src/messages/parser/campaign/CampaignCalendarData.ts new file mode 100644 index 0000000..2dda0f2 --- /dev/null +++ b/packages/communication/src/messages/parser/campaign/CampaignCalendarData.ts @@ -0,0 +1,114 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class CampaignCalendarData +{ + private _campaignName: string; + private _campaignImage: string; + private _currentDay: number; + private _campaignDays: number; + private _openedDays: number[]; + private _missedDays: number[]; + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._campaignName = wrapper.readString(); + this._campaignImage = wrapper.readString(); + this._currentDay = wrapper.readInt(); + this._campaignDays = wrapper.readInt(); + this._openedDays = []; + + let count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._openedDays.push(wrapper.readInt()); + } + + this._missedDays = []; + + count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._missedDays.push(wrapper.readInt()); + } + + return true; + } + + public clone(): CampaignCalendarData + { + const data = new CampaignCalendarData(); + + data.campaignDays = this._campaignDays; + data.campaignImage = this._campaignImage; + data.campaignName = this._campaignName; + data.currentDay = this._currentDay; + data.missedDays = this._missedDays; + data.openedDays = this._openedDays; + + return data; + } + + public get campaignName(): string + { + return this._campaignName; + } + + public set campaignName(name: string) + { + this._campaignName = name; + } + + public get campaignImage(): string + { + return this._campaignImage; + } + + public set campaignImage(image: string) + { + this._campaignImage = image; + } + + public get currentDay(): number + { + return this._currentDay; + } + + public set currentDay(day: number) + { + this._currentDay = day; + } + + public get campaignDays(): number + { + return this._campaignDays; + } + + public set campaignDays(days: number) + { + this._campaignDays = days; + } + + public get openedDays(): number[] + { + return this._openedDays; + } + + public set openedDays(days: number[]) + { + this._openedDays = days; + } + + public get missedDays(): number[] + { + return this._missedDays; + } + + public set missedDays(days: number[]) + { + this._missedDays = days; + } +} diff --git a/packages/communication/src/messages/parser/campaign/CampaignCalendarDataMessageParser.ts b/packages/communication/src/messages/parser/campaign/CampaignCalendarDataMessageParser.ts new file mode 100644 index 0000000..8d887de --- /dev/null +++ b/packages/communication/src/messages/parser/campaign/CampaignCalendarDataMessageParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CampaignCalendarData } from './CampaignCalendarData'; + +export class CampaignCalendarDataMessageParser implements IMessageParser +{ + private _calendarData: CampaignCalendarData; + + public flush(): boolean + { + this._calendarData = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._calendarData = new CampaignCalendarData(); + this._calendarData.parse(wrapper); + + return true; + } + + public get calendarData(): CampaignCalendarData + { + return this._calendarData; + } +} diff --git a/packages/communication/src/messages/parser/campaign/CampaignCalendarDoorOpenedMessageParser.ts b/packages/communication/src/messages/parser/campaign/CampaignCalendarDoorOpenedMessageParser.ts new file mode 100644 index 0000000..1a834fa --- /dev/null +++ b/packages/communication/src/messages/parser/campaign/CampaignCalendarDoorOpenedMessageParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CampaignCalendarDoorOpenedMessageParser implements IMessageParser +{ + private _doorOpened: boolean; + private _productName: string; + private _customImage: string; + private _furnitureClassName: string; + + public flush(): boolean + { + this._doorOpened = false; + this._productName = null; + this._customImage = null; + this._furnitureClassName = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._doorOpened = wrapper.readBoolean(); + this._productName = wrapper.readString(); + this._customImage = wrapper.readString(); + this._furnitureClassName = wrapper.readString(); + + return true; + } + + public get doorOpened(): boolean + { + return this._doorOpened; + } + + public get productName(): string + { + return this._productName; + } + + public get customImage(): string + { + return this._customImage; + } + + public get furnitureClassName(): string + { + return this._furnitureClassName; + } +} diff --git a/packages/communication/src/messages/parser/campaign/index.ts b/packages/communication/src/messages/parser/campaign/index.ts new file mode 100644 index 0000000..bb30603 --- /dev/null +++ b/packages/communication/src/messages/parser/campaign/index.ts @@ -0,0 +1,3 @@ +export * from './CampaignCalendarData'; +export * from './CampaignCalendarDataMessageParser'; +export * from './CampaignCalendarDoorOpenedMessageParser'; diff --git a/packages/communication/src/messages/parser/catalog/BonusRareInfoMessageParser.ts b/packages/communication/src/messages/parser/catalog/BonusRareInfoMessageParser.ts new file mode 100644 index 0000000..83fbd39 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/BonusRareInfoMessageParser.ts @@ -0,0 +1,49 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class BonusRareInfoMessageParser implements IMessageParser +{ + private _productType: string; + private _productClassId: number; + private _totalCoinsForBonus: number; + private _coinsStillRequiredToBuy: number; + + public flush(): boolean + { + this._totalCoinsForBonus = -1; + this._coinsStillRequiredToBuy = -1; + this._productType = ''; + this._productClassId = -1; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._productType = wrapper.readString(); + this._productClassId = wrapper.readInt(); + this._totalCoinsForBonus = wrapper.readInt(); + this._coinsStillRequiredToBuy = wrapper.readInt(); + return true; + } + + public get totalCoinsForBonus(): number + { + return this._totalCoinsForBonus; + } + + public get coinsStillRequiredToBuy(): number + { + return this._coinsStillRequiredToBuy; + } + + public get productType(): string + { + return this._productType; + } + + public get productClassId(): number + { + return this._productClassId; + } +} diff --git a/packages/communication/src/messages/parser/catalog/BuildersClubFurniCountMessageParser.ts b/packages/communication/src/messages/parser/catalog/BuildersClubFurniCountMessageParser.ts new file mode 100644 index 0000000..d380d10 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/BuildersClubFurniCountMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class BuildersClubFurniCountMessageParser implements IMessageParser +{ + private _furniCount: number; + + public flush(): boolean + { + this._furniCount = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._furniCount = wrapper.readInt(); + + return true; + } + + public get furniCount(): number + { + return this._furniCount; + } +} diff --git a/packages/communication/src/messages/parser/catalog/BuildersClubSubscriptionStatusMessageParser.ts b/packages/communication/src/messages/parser/catalog/BuildersClubSubscriptionStatusMessageParser.ts new file mode 100644 index 0000000..a4a64dd --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/BuildersClubSubscriptionStatusMessageParser.ts @@ -0,0 +1,53 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class BuildersClubSubscriptionStatusMessageParser implements IMessageParser +{ + private _secondsLeft: number; + private _furniLimit: number; + private _maxFurniLimit: number; + private _secondsLeftWithGrace: number; + + public flush(): boolean + { + this._secondsLeft = 0; + this._furniLimit = 0; + this._maxFurniLimit = 0; + this._secondsLeftWithGrace = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._secondsLeft = wrapper.readInt(); + this._furniLimit = wrapper.readInt(); + this._maxFurniLimit = wrapper.readInt(); + + if(wrapper.bytesAvailable) this._secondsLeftWithGrace = wrapper.readInt(); + else this._secondsLeftWithGrace = this._secondsLeft; + + return true; + } + + public get secondsLeft(): number + { + return this._secondsLeft; + } + + public get furniLimit(): number + { + return this._furniLimit; + } + + public get maxFurniLimit(): number + { + return this._maxFurniLimit; + } + + public get secondsLeftWithGrace(): number + { + return this._secondsLeftWithGrace; + } +} diff --git a/packages/communication/src/messages/parser/catalog/BundleDiscountRuleset.ts b/packages/communication/src/messages/parser/catalog/BundleDiscountRuleset.ts new file mode 100644 index 0000000..94b6e40 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/BundleDiscountRuleset.ts @@ -0,0 +1,53 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class BundleDiscountRuleset +{ + private _maxPurchaseSize: number; + private _bundleSize: number; + private _bundleDiscountSize: number; + private _bonusThreshold: number; + private _additionalBonusDiscountThresholdQuantities: number[]; + + constructor(wrapper: IMessageDataWrapper) + { + this._maxPurchaseSize = wrapper.readInt(); + this._bundleSize = wrapper.readInt(); + this._bundleDiscountSize = wrapper.readInt(); + this._bonusThreshold = wrapper.readInt(); + this._additionalBonusDiscountThresholdQuantities = []; + + let count = wrapper.readInt(); + + while(count > 0) + { + this._additionalBonusDiscountThresholdQuantities.push(wrapper.readInt()); + + count--; + } + } + + public get maxPurchaseSize(): number + { + return this._maxPurchaseSize; + } + + public get bundleSize(): number + { + return this._bundleSize; + } + + public get bundleDiscountSize(): number + { + return this._bundleDiscountSize; + } + + public get bonusThreshold(): number + { + return this._bonusThreshold; + } + + public get additionalBonusDiscountThresholdQuantities(): number[] + { + return this._additionalBonusDiscountThresholdQuantities; + } +} diff --git a/packages/communication/src/messages/parser/catalog/BundleDiscountRulesetMessageParser.ts b/packages/communication/src/messages/parser/catalog/BundleDiscountRulesetMessageParser.ts new file mode 100644 index 0000000..e954fd5 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/BundleDiscountRulesetMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { BundleDiscountRuleset } from './BundleDiscountRuleset'; + +export class BundleDiscountRulesetMessageParser implements IMessageParser +{ + private _bundleDiscountRuleset: BundleDiscountRuleset; + + public flush(): boolean + { + this._bundleDiscountRuleset = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._bundleDiscountRuleset = new BundleDiscountRuleset(wrapper); + + return true; + } + + public get bundleDiscountRuleset(): BundleDiscountRuleset + { + return this._bundleDiscountRuleset; + } +} diff --git a/packages/communication/src/messages/parser/catalog/CatalogIndexMessageParser.ts b/packages/communication/src/messages/parser/catalog/CatalogIndexMessageParser.ts new file mode 100644 index 0000000..1acf356 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/CatalogIndexMessageParser.ts @@ -0,0 +1,42 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { NodeData } from './NodeData'; + +export class CatalogIndexMessageParser implements IMessageParser +{ + private _root: NodeData; + 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 NodeData(wrapper); + this._newAdditionsAvailable = wrapper.readBoolean(); + this._catalogType = wrapper.readString(); + + return true; + } + + public get root(): NodeData + { + return this._root; + } + + public get newAdditionsAvailable(): boolean + { + return this._newAdditionsAvailable; + } + + public get catalogType(): string + { + return this._catalogType; + } +} diff --git a/packages/communication/src/messages/parser/catalog/CatalogLocalizationData.ts b/packages/communication/src/messages/parser/catalog/CatalogLocalizationData.ts new file mode 100644 index 0000000..c6bfce5 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/CatalogLocalizationData.ts @@ -0,0 +1,41 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class CatalogLocalizationData +{ + private _images: string[]; + private _texts: string[]; + + constructor(wrapper: IMessageDataWrapper) + { + this._images = []; + this._texts = []; + + 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--; + } + } + + public get images(): string[] + { + return this._images; + } + + public get texts(): string[] + { + return this._texts; + } +} diff --git a/packages/communication/src/messages/parser/catalog/CatalogPageExpirationParser.ts b/packages/communication/src/messages/parser/catalog/CatalogPageExpirationParser.ts new file mode 100644 index 0000000..73e0b0f --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/CatalogPageExpirationParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CatalogPageExpirationParser implements IMessageParser +{ + private _pageName: string; + private _pageId: number; + private _secondsToExpiry: number; + private _image: string; + + public flush(): boolean + { + this._pageName = null; + this._pageId = 0; + this._secondsToExpiry = 0; + this._image = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._pageId = wrapper.readInt(); + this._pageName = wrapper.readString(); + this._secondsToExpiry = wrapper.readInt(); + this._image = wrapper.readString(); + + return true; + } + + public get pageName(): string + { + return this._pageName; + } + + public get pageId(): number + { + return this._pageId; + } + + public get secondsToExpiry(): number + { + return this._secondsToExpiry; + } + + public get image(): string + { + return this._image; + } +} diff --git a/packages/communication/src/messages/parser/catalog/CatalogPageMessageOfferData.ts b/packages/communication/src/messages/parser/catalog/CatalogPageMessageOfferData.ts new file mode 100644 index 0000000..4ac4bf2 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/CatalogPageMessageOfferData.ts @@ -0,0 +1,105 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { CatalogPageMessageProductData } from './CatalogPageMessageProductData'; + +export class CatalogPageMessageOfferData +{ + 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: CatalogPageMessageProductData[]; + + constructor(wrapper: IMessageDataWrapper) + { + 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(); + + this._products = []; + + let totalProducts = wrapper.readInt(); + + while(totalProducts > 0) + { + this._products.push(new CatalogPageMessageProductData(wrapper)); + + totalProducts--; + } + + this._clubLevel = wrapper.readInt(); + this._bundlePurchaseAllowed = wrapper.readBoolean(); + this._isPet = wrapper.readBoolean(); + this._previewImage = wrapper.readString(); + } + + 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(): CatalogPageMessageProductData[] + { + return this._products; + } +} diff --git a/packages/communication/src/messages/parser/catalog/CatalogPageMessageParser.ts b/packages/communication/src/messages/parser/catalog/CatalogPageMessageParser.ts new file mode 100644 index 0000000..58b5e0e --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/CatalogPageMessageParser.ts @@ -0,0 +1,106 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CatalogLocalizationData } from './CatalogLocalizationData'; +import { CatalogPageMessageOfferData } from './CatalogPageMessageOfferData'; +import { FrontPageItem } from './FrontPageItem'; + +export class CatalogPageMessageParser implements IMessageParser +{ + private _pageId: number; + private _catalogType: string; + private _layoutCode: string; + private _localization: CatalogLocalizationData; + private _offers: CatalogPageMessageOfferData[]; + private _offerId: number; + private _acceptSeasonCurrencyAsCredits: boolean; + private _frontPageItems: FrontPageItem[]; + + 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 CatalogPageMessageOfferData(wrapper)); + + totalOffers--; + } + + this._offerId = wrapper.readInt(); + this._acceptSeasonCurrencyAsCredits = wrapper.readBoolean(); + + if(wrapper.bytesAvailable) + { + let totalFrontPageItems = wrapper.readInt(); + + while(totalFrontPageItems > 0) + { + this._frontPageItems.push(new FrontPageItem(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(): CatalogPageMessageOfferData[] + { + return this._offers; + } + + public get offerId(): number + { + return this._offerId; + } + + public get acceptSeasonCurrencyAsCredits(): boolean + { + return this._acceptSeasonCurrencyAsCredits; + } + + public get frontPageItems(): FrontPageItem[] + { + return this._frontPageItems; + } +} diff --git a/packages/communication/src/messages/parser/catalog/CatalogPageMessageProductData.ts b/packages/communication/src/messages/parser/catalog/CatalogPageMessageProductData.ts new file mode 100644 index 0000000..7225e10 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/CatalogPageMessageProductData.ts @@ -0,0 +1,98 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class CatalogPageMessageProductData +{ + 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 CatalogPageMessageProductData.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/packages/communication/src/messages/parser/catalog/CatalogPageWithEarliestExpiryMessageParser.ts b/packages/communication/src/messages/parser/catalog/CatalogPageWithEarliestExpiryMessageParser.ts new file mode 100644 index 0000000..116ed4c --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/CatalogPageWithEarliestExpiryMessageParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CatalogPageWithEarliestExpiryMessageParser implements IMessageParser +{ + private _pageName: string; + private _secondsToExpiry: number; + private _image: string; + + public flush(): boolean + { + this._pageName = null; + this._secondsToExpiry = 0; + this._image = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._pageName = wrapper.readString(); + this._secondsToExpiry = wrapper.readInt(); + this._image = wrapper.readString(); + + return true; + } + + public get pageName(): string + { + return this._pageName; + } + + public get secondsToExpiry(): number + { + return this._secondsToExpiry; + } + + public get image(): string + { + return this._image; + } +} diff --git a/packages/communication/src/messages/parser/catalog/CatalogPublishedMessageParser.ts b/packages/communication/src/messages/parser/catalog/CatalogPublishedMessageParser.ts new file mode 100644 index 0000000..faf816d --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/CatalogPublishedMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CatalogPublishedMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/catalog/ClubGiftData.ts b/packages/communication/src/messages/parser/catalog/ClubGiftData.ts new file mode 100644 index 0000000..1ab4f2c --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/ClubGiftData.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class ClubGiftData +{ + private _offerId: number; + private _isVip: boolean; + private _isSelectable: boolean; + private _daysRequired: number; + + constructor(wrapper: IMessageDataWrapper) + { + this._offerId = wrapper.readInt(); + this._isVip = wrapper.readBoolean(); + this._daysRequired = wrapper.readInt(); + this._isSelectable = wrapper.readBoolean(); + } + + public get offerId(): number + { + return this._offerId; + } + + public get isVip(): boolean + { + return this._isVip; + } + + public get isSelectable(): boolean + { + return this._isSelectable; + } + + public get daysRequired(): number + { + return this._daysRequired; + } +} diff --git a/packages/communication/src/messages/parser/catalog/ClubGiftInfoParser.ts b/packages/communication/src/messages/parser/catalog/ClubGiftInfoParser.ts new file mode 100644 index 0000000..b6938ad --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/ClubGiftInfoParser.ts @@ -0,0 +1,77 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CatalogPageMessageOfferData } from './CatalogPageMessageOfferData'; +import { ClubGiftData } from './ClubGiftData'; + +export class ClubGiftInfoParser implements IMessageParser +{ + private _daysUntilNextGift: number; + private _giftsAvailable: number; + private _offers: CatalogPageMessageOfferData[]; + private _giftData: Map; + + public flush(): boolean + { + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offers = []; + this._giftData = new Map(); + this._daysUntilNextGift = wrapper.readInt(); + this._giftsAvailable = wrapper.readInt(); + + const offerCount = wrapper.readInt(); + + for(let i = 0; i < offerCount; i++) + { + this._offers.push(new CatalogPageMessageOfferData(wrapper)); + } + + const giftDataCount = wrapper.readInt(); + + for(let i = 0; i < giftDataCount; i++) + { + const item = new ClubGiftData(wrapper); + this._giftData.set(item.offerId, item); + } + + return true; + } + + public get offers(): CatalogPageMessageOfferData[] + { + 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): ClubGiftData + { + if(!offerId) return null; + + return this._giftData.get(offerId); + } + + + public get giftData(): Map + { + return this._giftData; + } +} diff --git a/packages/communication/src/messages/parser/catalog/ClubGiftSelectedParser.ts b/packages/communication/src/messages/parser/catalog/ClubGiftSelectedParser.ts new file mode 100644 index 0000000..625f28d --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/ClubGiftSelectedParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CatalogPageMessageProductData } from './CatalogPageMessageProductData'; + +export class ClubGiftSelectedParser implements IMessageParser +{ + private _productCode: string; + private _products: CatalogPageMessageProductData[]; + + public flush(): boolean + { + this._productCode = null; + this._products = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._productCode = wrapper.readString(); + + let count = wrapper.readInt(); + + while(count > 0) + { + this._products.push(new CatalogPageMessageProductData(wrapper)); + + count--; + } + + return true; + } + + public get productCode(): string + { + return this._productCode; + } + + public get products(): CatalogPageMessageProductData[] + { + return this._products; + } +} diff --git a/packages/communication/src/messages/parser/catalog/ClubOfferData.ts b/packages/communication/src/messages/parser/catalog/ClubOfferData.ts new file mode 100644 index 0000000..44126ed --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/ClubOfferData.ts @@ -0,0 +1,105 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class ClubOfferData +{ + 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._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(); + } + + 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; + } +} diff --git a/packages/communication/src/messages/parser/catalog/ClubOfferExtendData.ts b/packages/communication/src/messages/parser/catalog/ClubOfferExtendData.ts new file mode 100644 index 0000000..1bfaf16 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/ClubOfferExtendData.ts @@ -0,0 +1,50 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { ClubOfferData } from './ClubOfferData'; + +export class ClubOfferExtendData extends ClubOfferData +{ + private _originalPrice: number; + private _originalActivityPointPrice: number; + private _originalActivityPointType: number; + private _subscriptionDaysLeft: number; + + constructor(wrapper: IMessageDataWrapper) + { + super(wrapper); + + this._originalPrice = wrapper.readInt(); + this._originalActivityPointPrice = wrapper.readInt(); + this._originalActivityPointType = wrapper.readInt(); + this._subscriptionDaysLeft = wrapper.readInt(); + } + + public get originalPrice(): number + { + return this._originalPrice * this.months; + } + + public get originalActivityPointPrice(): number + { + return this._originalActivityPointPrice * this.months; + } + + public get originalActivityPointType(): number + { + return this._originalActivityPointType; + } + + public get discountCreditAmount(): number + { + return (this._originalPrice * this.months) - this.priceCredits; + } + + public get discountActivityPointAmount(): number + { + return (this.originalActivityPointPrice * this.months) - this.priceActivityPoints; + } + + public get subscriptionDaysLeft(): number + { + return this._subscriptionDaysLeft; + } +} diff --git a/packages/communication/src/messages/parser/catalog/DirectSMSClubBuyAvailableMessageParser.ts b/packages/communication/src/messages/parser/catalog/DirectSMSClubBuyAvailableMessageParser.ts new file mode 100644 index 0000000..8318c7b --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/DirectSMSClubBuyAvailableMessageParser.ts @@ -0,0 +1,53 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class DirectSMSClubBuyAvailableMessageParser implements IMessageParser +{ + private _available: boolean; + private _pricePointUrl: string; + private _market: string; + private _lengthInDays: number; + + public flush(): boolean + { + this._available = false; + this._pricePointUrl = null; + this._market = null; + this._lengthInDays = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._pricePointUrl = wrapper.readString(); + + if(this._pricePointUrl !== '') this._available = true; + + this._market = wrapper.readString(); + this._lengthInDays = wrapper.readInt(); + + return true; + } + + public get available(): boolean + { + return this._available; + } + + public get pricePointUrl(): string + { + return this._pricePointUrl; + } + + public get market(): string + { + return this._market; + } + + public get lengthInDays(): number + { + return this._lengthInDays; + } +} diff --git a/packages/communication/src/messages/parser/catalog/FireworkChargeData.ts b/packages/communication/src/messages/parser/catalog/FireworkChargeData.ts new file mode 100644 index 0000000..dfa5981 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/FireworkChargeData.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class FireworkChargeData +{ + private _stuffId: number; + private _charges: number; + private _SafeStr_6935: number; + private _SafeStr_6936: number; + private _SafeStr_6518: number; + private _SafeStr_7875: number; + + constructor(wrapper: IMessageDataWrapper) + { + this._stuffId = wrapper.readInt(); + this._charges = wrapper.readInt(); + this._SafeStr_6935 = wrapper.readInt(); + this._SafeStr_6936 = wrapper.readInt(); + this._SafeStr_6518 = wrapper.readInt(); + this._SafeStr_7875 = wrapper.readInt(); + } + + public get stuffId(): number + { + return this._stuffId; + } + + public get charges(): number + { + return this._charges; + } + + public get _SafeStr_5946(): number + { + return this._SafeStr_6935; + } + + public get _SafeStr_5944(): number + { + return this._SafeStr_6936; + } + + public get _SafeStr_7876(): number + { + return this._SafeStr_7875; + } + + public get _SafeStr_5945(): number + { + return this._SafeStr_6518; + } +} diff --git a/packages/communication/src/messages/parser/catalog/FireworkChargeDataParser.ts b/packages/communication/src/messages/parser/catalog/FireworkChargeDataParser.ts new file mode 100644 index 0000000..cde0977 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/FireworkChargeDataParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { FireworkChargeData } from './FireworkChargeData'; + +export class FireworkChargeDataParser implements IMessageParser +{ + private _fireworkChargeData: FireworkChargeData; + + public flush(): boolean + { + this._fireworkChargeData = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._fireworkChargeData = new FireworkChargeData(wrapper); + + return true; + } + + public get fireworkChargeData(): FireworkChargeData + { + return this._fireworkChargeData; + } +} diff --git a/packages/communication/src/messages/parser/catalog/FrontPageItem.ts b/packages/communication/src/messages/parser/catalog/FrontPageItem.ts new file mode 100644 index 0000000..7e7ffa7 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/FrontPageItem.ts @@ -0,0 +1,108 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class FrontPageItem +{ + 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 FrontPageItem.ITEM_CATALOGUE_PAGE: + this._catalogPageLocation = wrapper.readString(); + break; + case FrontPageItem.ITEM_PRODUCT_OFFER: + this._productOfferId = wrapper.readInt(); + break; + case FrontPageItem.ITEM_IAP: + this._productCode = wrapper.readString(); + break; + } + + const time = wrapper.readInt(); + + this._expirationTime = ((time > 0) ? ((time * 1000) + 0) : 0); //GetTickerTime + + 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/packages/communication/src/messages/parser/catalog/GiftReceiverNotFoundParser.ts b/packages/communication/src/messages/parser/catalog/GiftReceiverNotFoundParser.ts new file mode 100644 index 0000000..34f64f9 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/GiftReceiverNotFoundParser.ts @@ -0,0 +1,20 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GiftReceiverNotFoundParser implements IMessageParser +{ + + public flush(): boolean + { + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } + + +} diff --git a/packages/communication/src/messages/parser/catalog/GiftWrappingConfigurationParser.ts b/packages/communication/src/messages/parser/catalog/GiftWrappingConfigurationParser.ts new file mode 100644 index 0000000..252070b --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/GiftWrappingConfigurationParser.ts @@ -0,0 +1,105 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GiftWrappingConfigurationParser 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/packages/communication/src/messages/parser/catalog/HabboClubExtendOfferMessageParser.ts b/packages/communication/src/messages/parser/catalog/HabboClubExtendOfferMessageParser.ts new file mode 100644 index 0000000..7d5b586 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/HabboClubExtendOfferMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { ClubOfferExtendData } from './ClubOfferExtendData'; + +export class HabboClubExtendOfferMessageParser implements IMessageParser +{ + private _offer: ClubOfferExtendData; + + public flush(): boolean + { + this._offer = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offer = new ClubOfferExtendData(wrapper); + + return true; + } + + public get offer(): ClubOfferExtendData + { + return this._offer; + } +} diff --git a/packages/communication/src/messages/parser/catalog/HabboClubOffersMessageParser.ts b/packages/communication/src/messages/parser/catalog/HabboClubOffersMessageParser.ts new file mode 100644 index 0000000..c87ea4f --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/HabboClubOffersMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { ClubOfferData } from './ClubOfferData'; + +export class HabboClubOffersMessageParser implements IMessageParser +{ + private _offers: ClubOfferData[]; + + 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 ClubOfferData(wrapper)); + + totalOffers--; + } + + return true; + } + + public get offers(): ClubOfferData[] + { + return this._offers; + } +} diff --git a/packages/communication/src/messages/parser/catalog/INodeData.ts b/packages/communication/src/messages/parser/catalog/INodeData.ts new file mode 100644 index 0000000..2c201e9 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/INodeData.ts @@ -0,0 +1,10 @@ +export interface INodeData +{ + visible: boolean; + icon: number; + pageId: number; + pageName: string; + localization: string; + children: INodeData[]; + offerIds: number[]; +} diff --git a/packages/communication/src/messages/parser/catalog/IsOfferGiftableMessageParser.ts b/packages/communication/src/messages/parser/catalog/IsOfferGiftableMessageParser.ts new file mode 100644 index 0000000..45bdefe --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/IsOfferGiftableMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class IsOfferGiftableMessageParser implements IMessageParser +{ + private _offerId: number; + private _isGiftable: boolean; + + public flush(): boolean + { + this._offerId = 0; + this._isGiftable = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offerId = wrapper.readInt(); + this._isGiftable = wrapper.readBoolean(); + + return true; + } + + public get offerId(): number + { + return this._offerId; + } + + public get isGiftable(): boolean + { + return this._isGiftable; + } +} diff --git a/packages/communication/src/messages/parser/catalog/LimitedEditionSoldOutParser.ts b/packages/communication/src/messages/parser/catalog/LimitedEditionSoldOutParser.ts new file mode 100644 index 0000000..c641602 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/LimitedEditionSoldOutParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class LimitedEditionSoldOutParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/catalog/LimitedOfferAppearingNextMessageParser.ts b/packages/communication/src/messages/parser/catalog/LimitedOfferAppearingNextMessageParser.ts new file mode 100644 index 0000000..7fef6ce --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/LimitedOfferAppearingNextMessageParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class LimitedOfferAppearingNextMessageParser implements IMessageParser +{ + private _appearsInSeconds: number; + private _pageId: number; + private _offerId: number; + private _productType: string; + + public flush(): boolean + { + this._appearsInSeconds = -1; + this._pageId = -1; + this._offerId = -1; + this._productType = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._appearsInSeconds = wrapper.readInt(); + this._pageId = wrapper.readInt(); + this._offerId = wrapper.readInt(); + this._productType = wrapper.readString(); + + return true; + } + + public get appearsInSeconds(): number + { + return this._appearsInSeconds; + } + + public get pageId(): number + { + return this._pageId; + } + + public get offerId(): number + { + return this._offerId; + } + + public get productType(): string + { + return this._productType; + } +} diff --git a/packages/communication/src/messages/parser/catalog/NodeData.ts b/packages/communication/src/messages/parser/catalog/NodeData.ts new file mode 100644 index 0000000..7cd7b9a --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/NodeData.ts @@ -0,0 +1,99 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class NodeData +{ + private _visible: boolean; + private _icon: number; + private _pageId: number; + private _pageName: string; + private _localization: string; + private _children: NodeData[]; + 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 NodeData(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(): NodeData[] + { + return this._children; + } + + public get offerIds(): number[] + { + return this._offerIds; + } +} diff --git a/packages/communication/src/messages/parser/catalog/NotEnoughBalanceMessageParser.ts b/packages/communication/src/messages/parser/catalog/NotEnoughBalanceMessageParser.ts new file mode 100644 index 0000000..65c5833 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/NotEnoughBalanceMessageParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class NotEnoughBalanceMessageParser implements IMessageParser +{ + private _notEnoughCredits: boolean = false; + private _notEnoughActivityPoints: boolean = false; + private _activityPointType: number = 0; + + public flush(): boolean + { + this._notEnoughCredits = false; + this._notEnoughActivityPoints = false; + this._activityPointType = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._notEnoughCredits = wrapper.readBoolean(); + this._notEnoughActivityPoints = wrapper.readBoolean(); + + if(wrapper.bytesAvailable) this._activityPointType = wrapper.readInt(); + + return true; + } + + public get notEnoughCredits(): boolean + { + return this._notEnoughCredits; + } + + public get notEnoughActivityPoints(): boolean + { + return this._notEnoughActivityPoints; + } + + public get activityPointType(): number + { + return this._activityPointType; + } +} diff --git a/packages/communication/src/messages/parser/catalog/ProductOfferMessageParser.ts b/packages/communication/src/messages/parser/catalog/ProductOfferMessageParser.ts new file mode 100644 index 0000000..93072c1 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/ProductOfferMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CatalogPageMessageOfferData } from './CatalogPageMessageOfferData'; + +export class ProductOfferMessageParser implements IMessageParser +{ + private _offer: CatalogPageMessageOfferData; + + public flush(): boolean + { + this._offer = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offer = new CatalogPageMessageOfferData(wrapper); + + return true; + } + + public get offer(): CatalogPageMessageOfferData + { + return this._offer; + } +} diff --git a/packages/communication/src/messages/parser/catalog/PurchaseErrorMessageParser.ts b/packages/communication/src/messages/parser/catalog/PurchaseErrorMessageParser.ts new file mode 100644 index 0000000..5c70a8e --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/PurchaseErrorMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PurchaseErrorMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/catalog/PurchaseNotAllowedMessageParser.ts b/packages/communication/src/messages/parser/catalog/PurchaseNotAllowedMessageParser.ts new file mode 100644 index 0000000..4c17ee8 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/PurchaseNotAllowedMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PurchaseNotAllowedMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/catalog/PurchaseOKMessageOfferData.ts b/packages/communication/src/messages/parser/catalog/PurchaseOKMessageOfferData.ts new file mode 100644 index 0000000..b32f0c9 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/PurchaseOKMessageOfferData.ts @@ -0,0 +1,117 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { CatalogPageMessageProductData } from './CatalogPageMessageProductData'; + +export class PurchaseOKMessageOfferData +{ + 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: CatalogPageMessageProductData[]; + + 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 CatalogPageMessageProductData(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(): CatalogPageMessageProductData[] + { + return this._products; + } +} diff --git a/packages/communication/src/messages/parser/catalog/PurchaseOKMessageParser.ts b/packages/communication/src/messages/parser/catalog/PurchaseOKMessageParser.ts new file mode 100644 index 0000000..2988c78 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/PurchaseOKMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PurchaseOKMessageOfferData } from './PurchaseOKMessageOfferData'; + +export class PurchaseOKMessageParser implements IMessageParser +{ + private _offer: PurchaseOKMessageOfferData; + + public flush(): boolean + { + this._offer = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offer = new PurchaseOKMessageOfferData(wrapper); + + return true; + } + + public get offer(): PurchaseOKMessageOfferData + { + return this._offer; + } +} diff --git a/packages/communication/src/messages/parser/catalog/RoomAdPurchaseInfoEventParser.ts b/packages/communication/src/messages/parser/catalog/RoomAdPurchaseInfoEventParser.ts new file mode 100644 index 0000000..06d84fc --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/RoomAdPurchaseInfoEventParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { RoomEntryData } from '../user'; + +export class RoomAdPurchaseInfoEventParser implements IMessageParser +{ + private _isVip: boolean; + private _rooms: RoomEntryData[]; + + public flush(): boolean + { + this._isVip = false; + this._rooms = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._isVip = wrapper.readBoolean(); + + let count = wrapper.readInt(); + + while(count > 0) + { + this._rooms.push(new RoomEntryData(wrapper.readInt(), wrapper.readString(), wrapper.readBoolean())); + + count--; + } + + return true; + } + + public get isVip(): boolean + { + return this._isVip; + } + + public get rooms(): RoomEntryData[] + { + return this._rooms; + } +} diff --git a/packages/communication/src/messages/parser/catalog/SeasonalCalendarDailyOfferMessageParser.ts b/packages/communication/src/messages/parser/catalog/SeasonalCalendarDailyOfferMessageParser.ts new file mode 100644 index 0000000..01a6141 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/SeasonalCalendarDailyOfferMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CatalogPageMessageOfferData } from './CatalogPageMessageOfferData'; + +export class SeasonalCalendarDailyOfferMessageParser implements IMessageParser +{ + private _pageId: number; + private _data: CatalogPageMessageOfferData; + + public flush(): boolean + { + this._pageId = -1; + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._pageId = wrapper.readInt(); + this._data = new CatalogPageMessageOfferData(wrapper); + + return true; + } + + public get pageId(): number + { + return this._pageId; + } + + public get data(): CatalogPageMessageOfferData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/catalog/SellablePetPaletteData.ts b/packages/communication/src/messages/parser/catalog/SellablePetPaletteData.ts new file mode 100644 index 0000000..2674267 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/SellablePetPaletteData.ts @@ -0,0 +1,67 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class SellablePetPaletteData +{ + private _type: number; + private _breedId: number; + private _paletteId: number; + private _sellable: boolean; + private _rare: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._type = -1; + this._breedId = -1; + this._paletteId = -1; + this._sellable = false; + this._rare = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._type = wrapper.readInt(); + this._breedId = wrapper.readInt(); + this._paletteId = wrapper.readInt(); + this._sellable = wrapper.readBoolean(); + this._rare = wrapper.readBoolean(); + + return true; + } + + public get type(): number + { + return this._type; + } + + public get breedId(): number + { + return this._breedId; + } + + public get paletteId(): number + { + return this._paletteId; + } + + public get sellable(): boolean + { + return this._sellable; + } + + public get rare(): boolean + { + return this._rare; + } +} diff --git a/packages/communication/src/messages/parser/catalog/SellablePetPalettesParser.ts b/packages/communication/src/messages/parser/catalog/SellablePetPalettesParser.ts new file mode 100644 index 0000000..f960aec --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/SellablePetPalettesParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { SellablePetPaletteData } from './SellablePetPaletteData'; + +export class SellablePetPalettesParser implements IMessageParser +{ + private _productCode: string; + private _palettes: SellablePetPaletteData[]; + + public flush(): boolean + { + this._productCode = ''; + this._palettes = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._productCode = wrapper.readString(); + + let totalPalettes = wrapper.readInt(); + + while(totalPalettes > 0) + { + this._palettes.push(new SellablePetPaletteData(wrapper)); + + totalPalettes--; + } + + return true; + } + + public get productCode(): string + { + return this._productCode; + } + + public get palettes(): SellablePetPaletteData[] + { + return this._palettes; + } +} diff --git a/packages/communication/src/messages/parser/catalog/TargetedOfferData.ts b/packages/communication/src/messages/parser/catalog/TargetedOfferData.ts new file mode 100644 index 0000000..68e602a --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/TargetedOfferData.ts @@ -0,0 +1,153 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class TargetedOfferData +{ + protected _id: number; + protected _identifier: string; + protected _type: number; + protected _title: string; + protected _description: string; + protected _imageUrl: string; + protected _iconImageUrl: string; + protected _productCode: string; + protected _purchaseLimit: number; + protected _expirationTime: number; + protected _priceInCredits: number; + protected _priceInActivityPoints: number; + protected _activityPointType: number; + protected _subProductCodes: string[]; + protected _trackingState: number; + + constructor(wrapper: IMessageDataWrapper) + { + this._trackingState = wrapper.readInt(); + this._id = wrapper.readInt(); + this._identifier = wrapper.readString(); + this._productCode = wrapper.readString(); + this._priceInCredits = wrapper.readInt(); + this._priceInActivityPoints = wrapper.readInt(); + this._activityPointType = wrapper.readInt(); + this._purchaseLimit = wrapper.readInt(); + + const time = wrapper.readInt(); + this._expirationTime = ((time > 0) ? ((time * 1000) + Date.now()) : 0); + + this._title = wrapper.readString(); + this._description = wrapper.readString(); + this._imageUrl = wrapper.readString(); + this._iconImageUrl = wrapper.readString(); + this._type = wrapper.readInt(); + this._subProductCodes = []; + + let count = wrapper.readInt(); + + while(count > 0) + { + this._subProductCodes.push(wrapper.readString()); + + count--; + } + return this; + } + + public populate(offerData: TargetedOfferData) + { + if(!offerData) return; + + this._id = offerData.id; + this._identifier = offerData.identifier; + this._type = offerData.type; + this._title = offerData.title; + this._description = offerData.description; + this._imageUrl = offerData.imageUrl; + this._iconImageUrl = offerData.iconImageUrl; + this._productCode = offerData.productCode; + this._purchaseLimit = offerData.purchaseLimit; + this._expirationTime = offerData.expirationTime; + this._priceInCredits = offerData.priceInCredits; + this._priceInActivityPoints = offerData.priceInActivityPoints; + this._activityPointType = offerData.activityPointType; + this._subProductCodes = offerData.subProductCodes; + this._trackingState = offerData.trackingState; + } + + public purchase(k: number): void + { + this._purchaseLimit = (this._purchaseLimit - k); + } + + public get id(): number + { + return this._id; + } + + public get identifier(): string + { + return this._identifier; + } + + public get type(): number + { + return this._type; + } + + public get title(): string + { + return this._title; + } + + public get description(): string + { + return this._description; + } + + public get imageUrl(): string + { + return this._imageUrl; + } + + public get iconImageUrl(): string + { + return this._iconImageUrl; + } + + public get productCode(): string + { + return this._productCode; + } + + public get purchaseLimit(): number + { + return this._purchaseLimit; + } + + public get expirationTime(): number + { + return this._expirationTime; + } + + public get priceInCredits(): number + { + return this._priceInCredits; + } + + public get priceInActivityPoints(): number + { + return this._priceInActivityPoints; + } + + public get activityPointType(): number + { + return this._activityPointType; + } + + public get subProductCodes(): string[] + { + return this._subProductCodes; + } + + public get trackingState(): number + { + return this._trackingState; + } +} diff --git a/packages/communication/src/messages/parser/catalog/TargetedOfferNotFoundParser.ts b/packages/communication/src/messages/parser/catalog/TargetedOfferNotFoundParser.ts new file mode 100644 index 0000000..8f103ea --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/TargetedOfferNotFoundParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TargetedOfferNotFoundParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/catalog/TargetedOfferParser.ts b/packages/communication/src/messages/parser/catalog/TargetedOfferParser.ts new file mode 100644 index 0000000..8191e15 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/TargetedOfferParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { TargetedOfferData } from './TargetedOfferData'; + +export class TargetedOfferParser implements IMessageParser +{ + private _data: TargetedOfferData; + + public flush(): boolean + { + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new TargetedOfferData(wrapper); + + return true; + } + + public get data(): TargetedOfferData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/catalog/VoucherRedeemErrorMessageParser.ts b/packages/communication/src/messages/parser/catalog/VoucherRedeemErrorMessageParser.ts new file mode 100644 index 0000000..200f0f2 --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/VoucherRedeemErrorMessageParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class VoucherRedeemErrorMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/catalog/VoucherRedeemOkMessageParser.ts b/packages/communication/src/messages/parser/catalog/VoucherRedeemOkMessageParser.ts new file mode 100644 index 0000000..55ea51f --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/VoucherRedeemOkMessageParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class VoucherRedeemOkMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/catalog/index.ts b/packages/communication/src/messages/parser/catalog/index.ts new file mode 100644 index 0000000..6225fef --- /dev/null +++ b/packages/communication/src/messages/parser/catalog/index.ts @@ -0,0 +1,46 @@ +export * from './BonusRareInfoMessageParser'; +export * from './BuildersClubFurniCountMessageParser'; +export * from './BuildersClubSubscriptionStatusMessageParser'; +export * from './BundleDiscountRuleset'; +export * from './BundleDiscountRulesetMessageParser'; +export * from './CatalogIndexMessageParser'; +export * from './CatalogLocalizationData'; +export * from './CatalogPageExpirationParser'; +export * from './CatalogPageMessageOfferData'; +export * from './CatalogPageMessageParser'; +export * from './CatalogPageMessageProductData'; +export * from './CatalogPageWithEarliestExpiryMessageParser'; +export * from './CatalogPublishedMessageParser'; +export * from './ClubGiftData'; +export * from './ClubGiftInfoParser'; +export * from './ClubGiftSelectedParser'; +export * from './ClubOfferData'; +export * from './ClubOfferExtendData'; +export * from './DirectSMSClubBuyAvailableMessageParser'; +export * from './FireworkChargeData'; +export * from './FireworkChargeDataParser'; +export * from './FrontPageItem'; +export * from './GiftReceiverNotFoundParser'; +export * from './GiftWrappingConfigurationParser'; +export * from './HabboClubExtendOfferMessageParser'; +export * from './HabboClubOffersMessageParser'; +export * from './INodeData'; +export * from './IsOfferGiftableMessageParser'; +export * from './LimitedEditionSoldOutParser'; +export * from './LimitedOfferAppearingNextMessageParser'; +export * from './NodeData'; +export * from './NotEnoughBalanceMessageParser'; +export * from './ProductOfferMessageParser'; +export * from './PurchaseErrorMessageParser'; +export * from './PurchaseNotAllowedMessageParser'; +export * from './PurchaseOKMessageOfferData'; +export * from './PurchaseOKMessageParser'; +export * from './RoomAdPurchaseInfoEventParser'; +export * from './SeasonalCalendarDailyOfferMessageParser'; +export * from './SellablePetPaletteData'; +export * from './SellablePetPalettesParser'; +export * from './TargetedOfferData'; +export * from './TargetedOfferNotFoundParser'; +export * from './TargetedOfferParser'; +export * from './VoucherRedeemErrorMessageParser'; +export * from './VoucherRedeemOkMessageParser'; diff --git a/packages/communication/src/messages/parser/client/ClientPingParser.ts b/packages/communication/src/messages/parser/client/ClientPingParser.ts new file mode 100644 index 0000000..156534e --- /dev/null +++ b/packages/communication/src/messages/parser/client/ClientPingParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ClientPingParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/client/index.ts b/packages/communication/src/messages/parser/client/index.ts new file mode 100644 index 0000000..129f672 --- /dev/null +++ b/packages/communication/src/messages/parser/client/index.ts @@ -0,0 +1 @@ +export * from './ClientPingParser'; diff --git a/packages/communication/src/messages/parser/competition/CompetitionEntrySubmitResultMessageParser.ts b/packages/communication/src/messages/parser/competition/CompetitionEntrySubmitResultMessageParser.ts new file mode 100644 index 0000000..590d91e --- /dev/null +++ b/packages/communication/src/messages/parser/competition/CompetitionEntrySubmitResultMessageParser.ts @@ -0,0 +1,83 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CompetitionEntrySubmitResultMessageParser implements IMessageParser +{ + public static SUBMITTED: number = 0; + public static ASK_FOR_SUBMIT: number = 1; + public static ASK_FOR_CONFIRM: number = 2; + public static PREREQUISITES_NOT_MET: number = 3; + public static ROOM_DOOR_NOT_OPEN: number = 4; + public static ROOM_TOO_OLD: number = 5; + public static ASK_FOR_ACCEPT_RULES: number = 6; + + private _goalId: number; + private _goalCode: string; + private _result: number; + private _requiredFurnis: string[]; + private _missingFurnis: { [index: string]: string }; + + public flush(): boolean + { + this._goalId = 0; + this._goalCode = null; + this._result = 0; + this._requiredFurnis = null; + this._missingFurnis = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._goalId = wrapper.readInt(); + this._goalCode = wrapper.readString(); + this._result = wrapper.readInt(); + this._requiredFurnis = []; + + let count = wrapper.readInt(); + + while(count > 0) + { + this._requiredFurnis.push(wrapper.readString()); + + count--; + } + + + count = wrapper.readInt(); + + while(count > 0) + { + this._missingFurnis[wrapper.readString()] = ''; + + count--; + } + + return true; + } + + public get goalId(): number + { + return this._goalId; + } + + public get goalCode(): string + { + return this._goalCode; + } + + public get result(): number + { + return this._result; + } + + public get requiredFurnis(): string[] + { + return this._requiredFurnis; + } + + public isMissing(name: string): boolean + { + return !!this._missingFurnis[name]; + } +} diff --git a/packages/communication/src/messages/parser/competition/CompetitionVotingInfoMessageParser.ts b/packages/communication/src/messages/parser/competition/CompetitionVotingInfoMessageParser.ts new file mode 100644 index 0000000..9012c1f --- /dev/null +++ b/packages/communication/src/messages/parser/competition/CompetitionVotingInfoMessageParser.ts @@ -0,0 +1,55 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CompetitionVotingInfoResult } from './CompetitionVotingInfoResult'; + +export class CompetitionVotingInfoMessageParser implements IMessageParser +{ + private _goalId: number; + private _goalCode: string; + private _resultCode: number; + private _votesRemaining: number; + + public flush(): boolean + { + this._goalId = 0; + this._goalCode = null; + this._resultCode = 0; + this._votesRemaining = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._goalId = wrapper.readInt(); + this._goalCode = wrapper.readString(); + this._resultCode = wrapper.readInt(); + this._votesRemaining = wrapper.readInt(); + + return true; + } + + public get goalId(): number + { + return this._goalId; + } + + public get goalCode(): string + { + return this._goalCode; + } + + public get isVotingAllowedForUser(): boolean + { + return (this._resultCode === CompetitionVotingInfoResult.ALLOWED); + } + + public get votesRemaining(): number + { + return this._votesRemaining; + } + + public get resultCode(): number + { + return this._resultCode; + } +} diff --git a/packages/communication/src/messages/parser/competition/CompetitionVotingInfoResult.ts b/packages/communication/src/messages/parser/competition/CompetitionVotingInfoResult.ts new file mode 100644 index 0000000..119f9b5 --- /dev/null +++ b/packages/communication/src/messages/parser/competition/CompetitionVotingInfoResult.ts @@ -0,0 +1,6 @@ +export class CompetitionVotingInfoResult +{ + public static ALLOWED: number = 0; + public static REQUIRED_PERK_MISSING: number = 1; + public static REQUIRED_BADGE_MISSING: number = 2; +} diff --git a/packages/communication/src/messages/parser/competition/CurrentTimingCodeMessageParser.ts b/packages/communication/src/messages/parser/competition/CurrentTimingCodeMessageParser.ts new file mode 100644 index 0000000..7719f3b --- /dev/null +++ b/packages/communication/src/messages/parser/competition/CurrentTimingCodeMessageParser.ts @@ -0,0 +1,33 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CurrentTimingCodeMessageParser implements IMessageParser +{ + private _schedulingStr: string; + private _code: string; + + public flush(): boolean + { + this._schedulingStr = null; + this._code = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._schedulingStr = wrapper.readString(); + this._code = wrapper.readString(); + + return true; + } + + public get schedulingStr(): string + { + return this._schedulingStr; + } + + public get code(): string + { + return this._code; + } +} diff --git a/packages/communication/src/messages/parser/competition/IsUserPartOfCompetitionMessageParser.ts b/packages/communication/src/messages/parser/competition/IsUserPartOfCompetitionMessageParser.ts new file mode 100644 index 0000000..1fb1b83 --- /dev/null +++ b/packages/communication/src/messages/parser/competition/IsUserPartOfCompetitionMessageParser.ts @@ -0,0 +1,33 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class IsUserPartOfCompetitionMessageParser implements IMessageParser +{ + private _isPartOf: boolean; + private _targetId: number; + + public flush(): boolean + { + this._isPartOf = false; + this._targetId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._isPartOf = wrapper.readBoolean(); + this._targetId = wrapper.readInt(); + + return true; + } + + public get isPartOf(): boolean + { + return this._isPartOf; + } + + public get targetId(): number + { + return this._targetId; + } +} diff --git a/packages/communication/src/messages/parser/competition/NoOwnedRoomsAlertMessageParser.ts b/packages/communication/src/messages/parser/competition/NoOwnedRoomsAlertMessageParser.ts new file mode 100644 index 0000000..b1e2101 --- /dev/null +++ b/packages/communication/src/messages/parser/competition/NoOwnedRoomsAlertMessageParser.ts @@ -0,0 +1,14 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class NoOwnedRoomsAlertMessageParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + return true; + } +} diff --git a/packages/communication/src/messages/parser/competition/SecondsUntilMessageParser.ts b/packages/communication/src/messages/parser/competition/SecondsUntilMessageParser.ts new file mode 100644 index 0000000..9c507bc --- /dev/null +++ b/packages/communication/src/messages/parser/competition/SecondsUntilMessageParser.ts @@ -0,0 +1,33 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class SecondsUntilMessageParser implements IMessageParser +{ + private _timeStr: string; + private _secondsUntil: number; + + public flush(): boolean + { + this._timeStr = null; + this._secondsUntil = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._timeStr = wrapper.readString(); + this._secondsUntil = wrapper.readInt(); + + return true; + } + + public get timeStr(): string + { + return this._timeStr; + } + + public get secondsUntil(): number + { + return this._secondsUntil; + } +} diff --git a/packages/communication/src/messages/parser/competition/index.ts b/packages/communication/src/messages/parser/competition/index.ts new file mode 100644 index 0000000..674fda0 --- /dev/null +++ b/packages/communication/src/messages/parser/competition/index.ts @@ -0,0 +1,7 @@ +export * from './CompetitionEntrySubmitResultMessageParser'; +export * from './CompetitionVotingInfoMessageParser'; +export * from './CompetitionVotingInfoResult'; +export * from './CurrentTimingCodeMessageParser'; +export * from './IsUserPartOfCompetitionMessageParser'; +export * from './NoOwnedRoomsAlertMessageParser'; +export * from './SecondsUntilMessageParser'; diff --git a/packages/communication/src/messages/parser/crafting/CraftableProductsMessageParser.ts b/packages/communication/src/messages/parser/crafting/CraftableProductsMessageParser.ts new file mode 100644 index 0000000..bae6f58 --- /dev/null +++ b/packages/communication/src/messages/parser/crafting/CraftableProductsMessageParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CraftingResultObjectParser } from './CraftingResultObjectParser'; + +export class CraftableProductsMessageParser implements IMessageParser +{ + private _recipes: CraftingResultObjectParser[]; + private _ingredients: string[]; + + constructor() + { + this._recipes = []; + this._ingredients = []; + } + + public flush(): boolean + { + this._recipes = []; + this._ingredients = []; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + const craftingResultCount = wrapper.readInt(); + for(let i = 0; i < craftingResultCount; i++) + { + this._recipes.push(new CraftingResultObjectParser(wrapper)); + } + const ingredientCount = wrapper.readInt(); + for(let i = 0; i < ingredientCount; i++) + { + this._ingredients.push(wrapper.readString()); + } + return true; + } + + public get recipes(): CraftingResultObjectParser[] + { + return this._recipes; + } + + public get ingredients(): string[] + { + return this._ingredients; + } + + public isActive(): boolean + { + return (this._recipes.length > 0) || (this._ingredients.length > 0); + } +} diff --git a/packages/communication/src/messages/parser/crafting/CraftingRecipeIngredientParser.ts b/packages/communication/src/messages/parser/crafting/CraftingRecipeIngredientParser.ts new file mode 100644 index 0000000..a9d61f3 --- /dev/null +++ b/packages/communication/src/messages/parser/crafting/CraftingRecipeIngredientParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class CraftingRecipeIngredientParser +{ + private _count: number; + private _itemName: string; + + constructor(wrapper: IMessageDataWrapper) + { + this._count = wrapper.readInt(); + this._itemName = wrapper.readString(); + } + + public get count(): number + { + return this._count; + } + + public get itemName(): string + { + return this._itemName; + } +} diff --git a/packages/communication/src/messages/parser/crafting/CraftingRecipeMessageParser.ts b/packages/communication/src/messages/parser/crafting/CraftingRecipeMessageParser.ts new file mode 100644 index 0000000..1fe9f8a --- /dev/null +++ b/packages/communication/src/messages/parser/crafting/CraftingRecipeMessageParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CraftingRecipeIngredientParser } from './CraftingRecipeIngredientParser'; + +export class CraftingRecipeMessageParser implements IMessageParser +{ + private _ingredients: CraftingRecipeIngredientParser[]; + + constructor() + { + this._ingredients = []; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + const ingredientCount = wrapper.readInt(); + for(let i = 0; i < ingredientCount; i++) + { + this._ingredients.push(new CraftingRecipeIngredientParser(wrapper)); + } + return true; + } + + public flush(): boolean + { + this._ingredients = []; + return true; + } + + public get ingredients(): CraftingRecipeIngredientParser[] + { + return this._ingredients; + } +} diff --git a/packages/communication/src/messages/parser/crafting/CraftingRecipesAvailableMessageParser.ts b/packages/communication/src/messages/parser/crafting/CraftingRecipesAvailableMessageParser.ts new file mode 100644 index 0000000..bd214d5 --- /dev/null +++ b/packages/communication/src/messages/parser/crafting/CraftingRecipesAvailableMessageParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CraftingRecipesAvailableMessageParser implements IMessageParser +{ + private _hasRecipes: boolean; + private _count: number; + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + this._count = wrapper.readInt(); + this._hasRecipes = wrapper.readBoolean(); + return true; + } + + public flush(): boolean + { + this._count = 0; + this._hasRecipes = false; + return true; + } + + public get count(): number + { + return this._count; + } + + public get hasRecipes(): boolean + { + return this._hasRecipes; + } +} diff --git a/packages/communication/src/messages/parser/crafting/CraftingResultMessageParser.ts b/packages/communication/src/messages/parser/crafting/CraftingResultMessageParser.ts new file mode 100644 index 0000000..d050532 --- /dev/null +++ b/packages/communication/src/messages/parser/crafting/CraftingResultMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CraftingResultObjectParser } from './CraftingResultObjectParser'; + +export class CraftingResultMessageParser implements IMessageParser +{ + private _success: boolean; + private _result: CraftingResultObjectParser; + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + this._success = wrapper.readBoolean(); + if(this._success) + { + this._result = new CraftingResultObjectParser(wrapper); + } + return true; + } + + public flush(): boolean + { + this._success = false; + return true; + } + + public get success(): boolean + { + return this._success; + } + + public get result(): CraftingResultObjectParser + { + return this._result; + } +} diff --git a/packages/communication/src/messages/parser/crafting/CraftingResultObjectParser.ts b/packages/communication/src/messages/parser/crafting/CraftingResultObjectParser.ts new file mode 100644 index 0000000..f03eb69 --- /dev/null +++ b/packages/communication/src/messages/parser/crafting/CraftingResultObjectParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class CraftingResultObjectParser +{ + private _recipeName: string; + private _itemName: string; + + constructor(wrapper: IMessageDataWrapper) + { + this._recipeName = wrapper.readString(); + this._itemName = wrapper.readString(); + } + + public get recipeName(): string + { + return this._recipeName; + } + + public get itemName(): string + { + return this._itemName; + } +} diff --git a/packages/communication/src/messages/parser/crafting/index.ts b/packages/communication/src/messages/parser/crafting/index.ts new file mode 100644 index 0000000..d0dc5ee --- /dev/null +++ b/packages/communication/src/messages/parser/crafting/index.ts @@ -0,0 +1,6 @@ +export * from './CraftableProductsMessageParser'; +export * from './CraftingRecipeIngredientParser'; +export * from './CraftingRecipeMessageParser'; +export * from './CraftingRecipesAvailableMessageParser'; +export * from './CraftingResultMessageParser'; +export * from './CraftingResultObjectParser'; diff --git a/packages/communication/src/messages/parser/desktop/DesktopViewParser.ts b/packages/communication/src/messages/parser/desktop/DesktopViewParser.ts new file mode 100644 index 0000000..577fb04 --- /dev/null +++ b/packages/communication/src/messages/parser/desktop/DesktopViewParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class DesktopViewParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/desktop/index.ts b/packages/communication/src/messages/parser/desktop/index.ts new file mode 100644 index 0000000..442a303 --- /dev/null +++ b/packages/communication/src/messages/parser/desktop/index.ts @@ -0,0 +1 @@ +export * from './DesktopViewParser'; diff --git a/packages/communication/src/messages/parser/friendlist/AcceptFriendFailureData.ts b/packages/communication/src/messages/parser/friendlist/AcceptFriendFailureData.ts new file mode 100644 index 0000000..ecf4bb2 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/AcceptFriendFailureData.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/AcceptFriendResultParser.ts b/packages/communication/src/messages/parser/friendlist/AcceptFriendResultParser.ts new file mode 100644 index 0000000..8dff4d1 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/AcceptFriendResultParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AcceptFriendFailerData } from './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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/FindFriendsProcessResultParser.ts b/packages/communication/src/messages/parser/friendlist/FindFriendsProcessResultParser.ts new file mode 100644 index 0000000..7ee7862 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/FindFriendsProcessResultParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/FollowFriendFailedParser.ts b/packages/communication/src/messages/parser/friendlist/FollowFriendFailedParser.ts new file mode 100644 index 0000000..ca212de --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/FollowFriendFailedParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/FriendCategoryData.ts b/packages/communication/src/messages/parser/friendlist/FriendCategoryData.ts new file mode 100644 index 0000000..a6165fe --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/FriendCategoryData.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/FriendListFragmentMessageParser.ts b/packages/communication/src/messages/parser/friendlist/FriendListFragmentMessageParser.ts new file mode 100644 index 0000000..8186ce8 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/FriendListFragmentMessageParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { FriendParser } from './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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/FriendListUpdateParser.ts b/packages/communication/src/messages/parser/friendlist/FriendListUpdateParser.ts new file mode 100644 index 0000000..d8ef91d --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/FriendListUpdateParser.ts @@ -0,0 +1,81 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { FriendCategoryData } from './FriendCategoryData'; +import { FriendParser } from './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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/FriendNotificationParser.ts b/packages/communication/src/messages/parser/friendlist/FriendNotificationParser.ts new file mode 100644 index 0000000..aee22ee --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/FriendNotificationParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/FriendParser.ts b/packages/communication/src/messages/parser/friendlist/FriendParser.ts new file mode 100644 index 0000000..3f2042e --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/FriendParser.ts @@ -0,0 +1,109 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/FriendRequestData.ts b/packages/communication/src/messages/parser/friendlist/FriendRequestData.ts new file mode 100644 index 0000000..47ddfc5 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/FriendRequestData.ts @@ -0,0 +1,39 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/FriendRequestsParser.ts b/packages/communication/src/messages/parser/friendlist/FriendRequestsParser.ts new file mode 100644 index 0000000..3e591cf --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/FriendRequestsParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { FriendRequestData } from './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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/HabboSearchResultData.ts b/packages/communication/src/messages/parser/friendlist/HabboSearchResultData.ts new file mode 100644 index 0000000..8b2f8c4 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/HabboSearchResultData.ts @@ -0,0 +1,76 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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._lastOnlineData = wrapper.readString(); // this was not assigned to anything on original packet + + this._avatarGender = wrapper.readInt(); + this._avatarFigure = 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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/HabboSearchResultParser.ts b/packages/communication/src/messages/parser/friendlist/HabboSearchResultParser.ts new file mode 100644 index 0000000..6e5d655 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/HabboSearchResultParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { HabboSearchResultData } from './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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/InstantMessageErrorParser.ts b/packages/communication/src/messages/parser/friendlist/InstantMessageErrorParser.ts new file mode 100644 index 0000000..bb74211 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/InstantMessageErrorParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/MessageErrorParser.ts b/packages/communication/src/messages/parser/friendlist/MessageErrorParser.ts new file mode 100644 index 0000000..4821bbf --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/MessageErrorParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/MessengerInitParser.ts b/packages/communication/src/messages/parser/friendlist/MessengerInitParser.ts new file mode 100644 index 0000000..4a3a856 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/MessengerInitParser.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { FriendCategoryData } from './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/packages/communication/src/messages/parser/friendlist/MiniMailNewMessageParser.ts b/packages/communication/src/messages/parser/friendlist/MiniMailNewMessageParser.ts new file mode 100644 index 0000000..c43f538 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/MiniMailNewMessageParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class MiniMailNewMessageParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/MiniMailUnreadCountParser.ts b/packages/communication/src/messages/parser/friendlist/MiniMailUnreadCountParser.ts new file mode 100644 index 0000000..2afe79a --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/MiniMailUnreadCountParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/NewConsoleMessageParser.ts b/packages/communication/src/messages/parser/friendlist/NewConsoleMessageParser.ts new file mode 100644 index 0000000..623f83f --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/NewConsoleMessageParser.ts @@ -0,0 +1,55 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/NewFriendRequestMessageParser.ts b/packages/communication/src/messages/parser/friendlist/NewFriendRequestMessageParser.ts new file mode 100644 index 0000000..8764657 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/NewFriendRequestMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { FriendRequestData } from './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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/RoomInviteErrorParser.ts b/packages/communication/src/messages/parser/friendlist/RoomInviteErrorParser.ts new file mode 100644 index 0000000..fa658e8 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/RoomInviteErrorParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/RoomInviteMessageParser.ts b/packages/communication/src/messages/parser/friendlist/RoomInviteMessageParser.ts new file mode 100644 index 0000000..671da95 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/RoomInviteMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/friendlist/index.ts b/packages/communication/src/messages/parser/friendlist/index.ts new file mode 100644 index 0000000..6542588 --- /dev/null +++ b/packages/communication/src/messages/parser/friendlist/index.ts @@ -0,0 +1,22 @@ +export * from './AcceptFriendFailureData'; +export * from './AcceptFriendResultParser'; +export * from './FindFriendsProcessResultParser'; +export * from './FollowFriendFailedParser'; +export * from './FriendCategoryData'; +export * from './FriendListFragmentMessageParser'; +export * from './FriendListUpdateParser'; +export * from './FriendNotificationParser'; +export * from './FriendParser'; +export * from './FriendRequestData'; +export * from './FriendRequestsParser'; +export * from './HabboSearchResultData'; +export * from './HabboSearchResultParser'; +export * from './InstantMessageErrorParser'; +export * from './MessageErrorParser'; +export * from './MessengerInitParser'; +export * from './MiniMailNewMessageParser'; +export * from './MiniMailUnreadCountParser'; +export * from './NewConsoleMessageParser'; +export * from './NewFriendRequestMessageParser'; +export * from './RoomInviteErrorParser'; +export * from './RoomInviteMessageParser'; diff --git a/packages/communication/src/messages/parser/game/directory/Game2AccountGameStatusMessageParser.ts b/packages/communication/src/messages/parser/game/directory/Game2AccountGameStatusMessageParser.ts new file mode 100644 index 0000000..fdd7675 --- /dev/null +++ b/packages/communication/src/messages/parser/game/directory/Game2AccountGameStatusMessageParser.ts @@ -0,0 +1,45 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class Game2AccountGameStatusMessageParser implements IMessageParser +{ + private _gameTypeId:number; + private _freeGamesLeft:number; + private _gamesPlayedTotal:number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + this._freeGamesLeft = wrapper.readInt(); + this._gamesPlayedTotal = wrapper.readInt(); + + return true; + } + + public get gameTypeId():number + { + return this._gameTypeId; + } + + public get freeGamesLeft():number + { + return this._freeGamesLeft; + } + + public get gamesPlayedTotal():number + { + return this._gamesPlayedTotal; + } + + public get hasUnlimitedGames():boolean + { + return this._freeGamesLeft == -1; + } + +} diff --git a/packages/communication/src/messages/parser/game/directory/Game2GameDirectoryStatusMessageParser.ts b/packages/communication/src/messages/parser/game/directory/Game2GameDirectoryStatusMessageParser.ts new file mode 100644 index 0000000..b758fbb --- /dev/null +++ b/packages/communication/src/messages/parser/game/directory/Game2GameDirectoryStatusMessageParser.ts @@ -0,0 +1,61 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class Game2GameDirectoryStatusMessageParser implements IMessageParser +{ + public static readonly STATUS_OK: number = 0; + public static readonly STATUS_FAILED_REASON_UNKNOWN: number = 1; + public static readonly STATUS_FAILED_REASON_GAME_DIRECTORY_IS_NOT_AVAILABLE: number = 2; + public static readonly STATUS_FAILED_REASON_HOTEL_IS_CLOSED: number = 3; + + private _status: number; + private _blockLength: number; + private _gamesPlayed: number; + private _freeGamesLeft: number; + + public flush(): boolean + { + this._status = -1; + this._blockLength = -1; + this._gamesPlayed = -1; + this._freeGamesLeft = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._status = wrapper.readInt(); + this._blockLength = wrapper.readInt(); + this._gamesPlayed = wrapper.readInt(); + this._freeGamesLeft = wrapper.readInt(); + + return true; + } + + public get status(): number + { + return this._status; + } + + public get blockLength(): number + { + return this._blockLength; + } + + public get gamesPlayed(): number + { + return this._gamesPlayed; + } + + public get freeGamesLeft(): number + { + return this._freeGamesLeft; + } + + public get hasUnlimitedGames(): boolean + { + return this._freeGamesLeft == -1; + } +} diff --git a/packages/communication/src/messages/parser/game/directory/Game2InArenaQueueMessageParser.ts b/packages/communication/src/messages/parser/game/directory/Game2InArenaQueueMessageParser.ts new file mode 100644 index 0000000..8e09846 --- /dev/null +++ b/packages/communication/src/messages/parser/game/directory/Game2InArenaQueueMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class Game2InArenaQueueMessageParser implements IMessageParser +{ + private _position: number; + + public flush(): boolean + { + this._position = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._position = wrapper.readInt(); + + return true; + } + + public get position(): number + { + return this._position; + } +} diff --git a/packages/communication/src/messages/parser/game/directory/Game2JoiningGameFailedMessageParser.ts b/packages/communication/src/messages/parser/game/directory/Game2JoiningGameFailedMessageParser.ts new file mode 100644 index 0000000..c00f08b --- /dev/null +++ b/packages/communication/src/messages/parser/game/directory/Game2JoiningGameFailedMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class Game2JoiningGameFailedMessageParser implements IMessageParser +{ + public static readonly KICKED: number = 1; + public static readonly DUPLICATE_MACHINEID: number = 2; + public static readonly INVITATION_REQUIRED: number = 3; + public static readonly NO_SPACE_IN_TEAM: number = 4; + public static readonly TEAM_NOT_FOUND: number = 5; + public static readonly USER_HAS_ACTIVE_INSTANCE: number = 6; + public static readonly USER_HAS_PENDING_INSTANCE_REQUEST: number = 7; + public static readonly USER_HAS_NO_FREE_GAMES_LEFT: number = 8; + + private _reason: number; + + public flush(): boolean + { + this._reason = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._reason = wrapper.readInt(); + + return true; + } + + public get reason(): number + { + return this._reason; + } +} diff --git a/packages/communication/src/messages/parser/game/directory/Game2StartingGameFailedMessageParser.ts b/packages/communication/src/messages/parser/game/directory/Game2StartingGameFailedMessageParser.ts new file mode 100644 index 0000000..2c94785 --- /dev/null +++ b/packages/communication/src/messages/parser/game/directory/Game2StartingGameFailedMessageParser.ts @@ -0,0 +1,30 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class Game2StartingGameFailedMessageParser implements IMessageParser +{ + public static readonly NOT_ENOUGH_PLAYERS: number = 1; + public static readonly GAME_HAS_NO_OWNER: number = 2; + + private _reason: number; + + public flush(): boolean + { + this._reason = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._reason = wrapper.readInt(); + + return true; + } + + public get reason(): number + { + return this._reason; + } +} diff --git a/packages/communication/src/messages/parser/game/directory/Game2StopCounterMessageParser.ts b/packages/communication/src/messages/parser/game/directory/Game2StopCounterMessageParser.ts new file mode 100644 index 0000000..51bf9cf --- /dev/null +++ b/packages/communication/src/messages/parser/game/directory/Game2StopCounterMessageParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class Game2StopCounterMessageParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/game/directory/Game2UserLeftGameMessageParser.ts b/packages/communication/src/messages/parser/game/directory/Game2UserLeftGameMessageParser.ts new file mode 100644 index 0000000..a12f7f1 --- /dev/null +++ b/packages/communication/src/messages/parser/game/directory/Game2UserLeftGameMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class Game2UserLeftGameMessageParser implements IMessageParser +{ + private _userId: number; + + public flush(): boolean + { + this._userId = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userId = wrapper.readInt(); + + return true; + } + + public get userId():number + { + return this._userId; + } +} diff --git a/packages/communication/src/messages/parser/game/directory/index.ts b/packages/communication/src/messages/parser/game/directory/index.ts new file mode 100644 index 0000000..917ffbb --- /dev/null +++ b/packages/communication/src/messages/parser/game/directory/index.ts @@ -0,0 +1,7 @@ +export * from './Game2AccountGameStatusMessageParser'; +export * from './Game2GameDirectoryStatusMessageParser'; +export * from './Game2InArenaQueueMessageParser'; +export * from './Game2JoiningGameFailedMessageParser'; +export * from './Game2StartingGameFailedMessageParser'; +export * from './Game2StopCounterMessageParser'; +export * from './Game2UserLeftGameMessageParser'; diff --git a/packages/communication/src/messages/parser/game/index.ts b/packages/communication/src/messages/parser/game/index.ts new file mode 100644 index 0000000..779f388 --- /dev/null +++ b/packages/communication/src/messages/parser/game/index.ts @@ -0,0 +1,3 @@ +export * from './directory'; +export * from './lobby'; +export * from './score'; diff --git a/packages/communication/src/messages/parser/game/lobby/AchievementResolutionCompletedMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/AchievementResolutionCompletedMessageParser.ts new file mode 100644 index 0000000..65764c5 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/AchievementResolutionCompletedMessageParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class AchievementResolutionCompletedMessageParser implements IMessageParser +{ + private _stuffCode:string; + private _badgeCode:string; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._stuffCode = wrapper.readString(); + this._badgeCode = wrapper.readString(); + + return true; + } + + public get stuffCode():string + { + return this._stuffCode; + } + + public get badgeCode():string + { + return this._badgeCode; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/AchievementResolutionProgressMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/AchievementResolutionProgressMessageParser.ts new file mode 100644 index 0000000..b1c7b77 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/AchievementResolutionProgressMessageParser.ts @@ -0,0 +1,66 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class AchievementResolutionProgressMessageParser implements IMessageParser +{ + private _stuffId:number; + private _achievementId:number; + private _requiredLevelBadgeCode:string; + private _userProgress:number; + private _totalProgress:number; + private _endTime:number; + + public flush(): boolean + { + this._stuffId = -1; + this._achievementId = 0; + this._requiredLevelBadgeCode = ''; + this._userProgress = 0; + this._totalProgress = 0; + this._endTime = 0; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._stuffId = wrapper.readInt(); + this._achievementId = wrapper.readInt(); + this._requiredLevelBadgeCode = wrapper.readString(); + this._userProgress = wrapper.readInt(); + this._totalProgress = wrapper.readInt(); + this._endTime = wrapper.readInt(); + + return true; + } + + public get stuffId():number + { + return this._stuffId; + } + + public get achievementId():number + { + return this._achievementId; + } + + public get requiredLevelBadgeCode():string + { + return this._requiredLevelBadgeCode; + } + + public get userProgress():number + { + return this._userProgress; + } + + public get totalProgress():number + { + return this._totalProgress; + } + + public get endTime():number + { + return this._endTime; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/AchievementResolutionsMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/AchievementResolutionsMessageParser.ts new file mode 100644 index 0000000..bc40f66 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/AchievementResolutionsMessageParser.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AchievementResolutionData } from '../../inventory'; + +export class AchievementResolutionsMessageParser implements IMessageParser +{ + private _stuffId:number; + private _achievements:AchievementResolutionData[]; + private _endTime:number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._stuffId = wrapper.readInt(); + const count = wrapper.readInt(); + let _local_3 = 0; + while(_local_3 < count) + { + this._achievements.push(new AchievementResolutionData(wrapper)); + _local_3++; + } + this._endTime = wrapper.readInt(); + + return true; + } + + public get stuffId():number + { + return this._stuffId; + } + + public get achievements():AchievementResolutionData[] + { + return this._achievements; + } + + public get endTime():number + { + return this._endTime; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/GameAchievementData.ts b/packages/communication/src/messages/parser/game/lobby/GameAchievementData.ts new file mode 100644 index 0000000..6fbd040 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/GameAchievementData.ts @@ -0,0 +1,35 @@ +export class GameAchievementData +{ + private _gameTypeId:number; + private _achievementId:number; + private _achievementName:string; + private _levels:number; + + constructor(gameTypeId:number, achievementId:number, achievementName:string, levels:number) + { + this._gameTypeId = gameTypeId; + this._achievementId = achievementId; + this._achievementName = achievementName; + this._levels = levels; + } + + public get gameTypeId():number + { + return this._gameTypeId; + } + + public get achievementId():number + { + return this._achievementId; + } + + public get achievementName():string + { + return this._achievementName; + } + + public get levels():number + { + return this._levels; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/GameAchievementsMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/GameAchievementsMessageParser.ts new file mode 100644 index 0000000..f74a433 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/GameAchievementsMessageParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { GameAchievementData } from './GameAchievementData'; + +export class GameAchievementsMessageParser implements IMessageParser +{ + private _achievements:GameAchievementData[]; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._achievements = []; + const count = wrapper.readInt(); + let _local_3 = 0; + while(_local_3 < count) + { + const gameTypeId = wrapper.readInt(); + const achievementCount = wrapper.readInt(); + let _local_6 = 0; + while(_local_6 < achievementCount) + { + const achievementId = wrapper.readInt(); + const achievementName = wrapper.readString(); + const levels = wrapper.readInt(); + this._achievements.push(new GameAchievementData(gameTypeId, achievementId, achievementName, levels)); + _local_6++; + } + _local_3++; + } + + return true; + } + + public get achievements():GameAchievementData[] + { + return this._achievements; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/GameConfigurationData.ts b/packages/communication/src/messages/parser/game/lobby/GameConfigurationData.ts new file mode 100644 index 0000000..4bf7e87 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/GameConfigurationData.ts @@ -0,0 +1,49 @@ +export class GameConfigurationData +{ + private _gameId:number; + private _gameNameId:string; + private _bgColor:number; + private _textColor:number; + private _assetUrl:string; + private _supportUrl:string; + + constructor(gameId:number, gameNameId:string, bgColor:number, textColor:number, assetUrl:string, supportUrl:string) + { + this._gameId = gameId; + this._gameNameId = gameNameId; + this._bgColor = bgColor; + this._textColor = textColor; + this._assetUrl = assetUrl; + this._supportUrl = supportUrl; + } + + public get gameId():number + { + return this._gameId; + } + + public get gameNameId():string + { + return this._gameNameId; + } + + public get bgColor():number + { + return this._bgColor; + } + + public get textColor():number + { + return this._textColor; + } + + public get assetUrl():string + { + return this._assetUrl; + } + + public get supportUrl():string + { + return this._supportUrl; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/GameInviteMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/GameInviteMessageParser.ts new file mode 100644 index 0000000..94dcc10 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/GameInviteMessageParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GameInviteMessageParser implements IMessageParser +{ + private _gameTypeId:number; + private _inviterId:number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + this._inviterId = wrapper.readInt(); + + return true; + } + + public get gameTypeId():number + { + return this._gameTypeId; + } + + public get inviterId():number + { + return this._inviterId; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/GameListMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/GameListMessageParser.ts new file mode 100644 index 0000000..6414e06 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/GameListMessageParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { GameConfigurationData } from './GameConfigurationData'; + +export class GameListMessageParser implements IMessageParser +{ + private _games:GameConfigurationData[]; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._games = []; + + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + const gameId = wrapper.readInt(); + const gameNameId = wrapper.readString(); + const _local_6 = wrapper.readString(); + let bgColor = parseInt(_local_6, 16); + bgColor = (bgColor | 0xFF000000); + const _local_8 = wrapper.readString(); + let textColor = parseInt(_local_8, 16); + textColor = (textColor | 0xFF000000); + const assetUrl = wrapper.readString(); + const supportUrl = wrapper.readString(); + this._games.push(new GameConfigurationData(gameId, gameNameId, bgColor, textColor, assetUrl, supportUrl)); + } + + return true; + } + + public get games(): GameConfigurationData[] + { + return this._games; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/GameStatusMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/GameStatusMessageParser.ts new file mode 100644 index 0000000..8ac106e --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/GameStatusMessageParser.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GameStatusMessageParser implements IMessageParser +{ + private static readonly OK = 0; + private static readonly MAINTENANCE = 1; + + private _gameTypeId:number; + private _status:number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + this._status = wrapper.readInt(); + + return true; + } + + public get gameTypeId():number + { + return this._gameTypeId; + } + + public get isOk():boolean + { + return this._status == GameStatusMessageParser.OK; + } + + public get isInMaintenance():boolean + { + return this._status == GameStatusMessageParser.MAINTENANCE; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/JoinedQueueMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/JoinedQueueMessageParser.ts new file mode 100644 index 0000000..6826dfa --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/JoinedQueueMessageParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class JoinedQueueMessageParser implements IMessageParser +{ + private _gameTypeId:number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + + return true; + } + + public get gameTypeId():number + { + return this._gameTypeId; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/JoiningQueueFailedMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/JoiningQueueFailedMessageParser.ts new file mode 100644 index 0000000..9ca821f --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/JoiningQueueFailedMessageParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class JoiningQueueFailedMessageParser implements IMessageParser +{ + public static readonly DUPLICATE_MACHINEID = 1; + + private _gameTypeId:number; + private _reason:number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + this._reason = wrapper.readInt(); + + return true; + } + + public get gameTypeId():number + { + return this._gameTypeId; + } + + public get reason():number + { + return this._reason; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/LeftQueueMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/LeftQueueMessageParser.ts new file mode 100644 index 0000000..a65bbc4 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/LeftQueueMessageParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class LeftQueueMessageParser implements IMessageParser +{ + private _gameTypeId:number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + + return true; + } + + public get gameTypeId():number + { + return this._gameTypeId; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/LoadGameMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/LoadGameMessageParser.ts new file mode 100644 index 0000000..5b6f834 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/LoadGameMessageParser.ts @@ -0,0 +1,88 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class LoadGameMessageParser implements IMessageParser +{ + private _gameTypeId:number; + private _url:string; + private _quality:string; + private _scaleMode:string; + private _frameRate:number; + private _minMajorVersion:number; + private _minMinorVersion:number; + private _params:Map; + private _gameClientId:string; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + this._gameClientId = wrapper.readString(); + this._url = wrapper.readString(); + this._quality = wrapper.readString(); + this._scaleMode = wrapper.readString(); + this._frameRate = wrapper.readInt(); + this._minMajorVersion = wrapper.readInt(); + this._minMinorVersion = wrapper.readInt(); + this._params = new Map(); + const count = wrapper.readInt(); + let _local_3 = 0; + while(_local_3 < count) + { + this._params.set(wrapper.readString(), wrapper.readString()); + _local_3++; + } + + return true; + } + + public get gameTypeId():number + { + return this._gameTypeId; + } + + public get url():string + { + return this._url; + } + + public get quality():string + { + return this._quality; + } + + public get scaleMode():string + { + return this._scaleMode; + } + + public get frameRate():number + { + return this._frameRate; + } + + public get minMajorVersion():number + { + return this._minMajorVersion; + } + + public get minMinorVersion():number + { + return this._minMinorVersion; + } + + public get params():Map + { + return this._params; + } + + public get gameClientId():string + { + return this._gameClientId; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/LoadGameUrlParser.ts b/packages/communication/src/messages/parser/game/lobby/LoadGameUrlParser.ts new file mode 100644 index 0000000..f06ce45 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/LoadGameUrlParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/UnloadGameMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/UnloadGameMessageParser.ts new file mode 100644 index 0000000..d53244b --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/UnloadGameMessageParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class UnloadGameMessageParser implements IMessageParser +{ + private _gameTypeId:number; + private _gameClientId:string; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + this._gameClientId = wrapper.readString(); + + return true; + } + + public get gameTypeId():number + { + return this._gameTypeId; + } + + public get gameClientId():string + { + return this._gameClientId; + } +} diff --git a/packages/communication/src/messages/parser/game/lobby/UserGameAchievementsMessageParser.ts b/packages/communication/src/messages/parser/game/lobby/UserGameAchievementsMessageParser.ts new file mode 100644 index 0000000..f53f0cb --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/UserGameAchievementsMessageParser.ts @@ -0,0 +1,21 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class UserGameAchievementsMessageParser implements IMessageParser +{ + + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + + + return true; + } + +} diff --git a/packages/communication/src/messages/parser/game/lobby/index.ts b/packages/communication/src/messages/parser/game/lobby/index.ts new file mode 100644 index 0000000..847d309 --- /dev/null +++ b/packages/communication/src/messages/parser/game/lobby/index.ts @@ -0,0 +1,16 @@ +export * from './AchievementResolutionCompletedMessageParser'; +export * from './AchievementResolutionProgressMessageParser'; +export * from './AchievementResolutionsMessageParser'; +export * from './GameAchievementData'; +export * from './GameAchievementsMessageParser'; +export * from './GameConfigurationData'; +export * from './GameInviteMessageParser'; +export * from './GameListMessageParser'; +export * from './GameStatusMessageParser'; +export * from './JoinedQueueMessageParser'; +export * from './JoiningQueueFailedMessageParser'; +export * from './LeftQueueMessageParser'; +export * from './LoadGameMessageParser'; +export * from './LoadGameUrlParser'; +export * from './UnloadGameMessageParser'; +export * from './UserGameAchievementsMessageParser'; diff --git a/packages/communication/src/messages/parser/game/score/Game2WeeklyLeaderboardParser.ts b/packages/communication/src/messages/parser/game/score/Game2WeeklyLeaderboardParser.ts new file mode 100644 index 0000000..6f330fe --- /dev/null +++ b/packages/communication/src/messages/parser/game/score/Game2WeeklyLeaderboardParser.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class Game2WeeklyLeaderboardParser implements IMessageParser +{ + private _year: number; + private _week: number; + private _maxOffset: number; + private _currentOffset: number; + private _minutesUntilReset: number; + + public flush(): boolean + { + this._year = -1; + this._week = -1; + this._maxOffset = -1; + this._currentOffset = -1; + this._minutesUntilReset = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._year = wrapper.readInt(); + this._week = wrapper.readInt(); + this._maxOffset = wrapper.readInt(); + this._currentOffset = wrapper.readInt(); + this._minutesUntilReset = wrapper.readInt(); + + return true; + } + + public get year(): number + { + return this._year; + } + + public get week(): number + { + return this._week; + } + + public get maxOffset(): number + { + return this._maxOffset; + } + + public get currentOffset(): number + { + return this._currentOffset; + } + + public get minutesUntilReset(): number + { + return this._minutesUntilReset; + } +} diff --git a/packages/communication/src/messages/parser/game/score/GameRewardWinnerEntry.ts b/packages/communication/src/messages/parser/game/score/GameRewardWinnerEntry.ts new file mode 100644 index 0000000..2604dce --- /dev/null +++ b/packages/communication/src/messages/parser/game/score/GameRewardWinnerEntry.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class GameRewardWinnerEntry +{ + private _name: string; + private _figure: string; + private _gender: string; + private _rank: number; + private _score: number; + + constructor(wrapper: IMessageDataWrapper) + { + this._name = wrapper.readString(); + this._figure = wrapper.readString(); + this._gender = wrapper.readString(); + this._rank = wrapper.readInt(); + this._score = wrapper.readInt(); + } + + public get name(): string + { + return this._name; + } + + public get figure(): string + { + return this._figure; + } + + public get gender(): string + { + return this._gender; + } + + public get rank(): number + { + return this._rank; + } + + public get score(): number + { + return this._score; + } +} diff --git a/packages/communication/src/messages/parser/game/score/LeaderboardEntry.ts b/packages/communication/src/messages/parser/game/score/LeaderboardEntry.ts new file mode 100644 index 0000000..fcf11d9 --- /dev/null +++ b/packages/communication/src/messages/parser/game/score/LeaderboardEntry.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class LeaderboardEntry +{ + private _userId:number; + private _score:number; + private _rank:number; + private _name:string; + private _figure:string; + private _gender:string; + + constructor(k:IMessageDataWrapper) + { + this._userId = k.readInt(); + this._score = k.readInt(); + this._rank = k.readInt(); + this._name = k.readString(); + this._figure = k.readString(); + this._gender = k.readString(); + } + + public get userId():number + { + return this._userId; + } + + public get score():number + { + return this._score; + } + + public get rank():number + { + return this._rank; + } + + public get figure():string + { + return this._figure; + } + + public get gender():string + { + return this._gender; + } + + public get name():string + { + return this._name; + } +} diff --git a/packages/communication/src/messages/parser/game/score/WeeklyGameRewardParser.ts b/packages/communication/src/messages/parser/game/score/WeeklyGameRewardParser.ts new file mode 100644 index 0000000..11ad73c --- /dev/null +++ b/packages/communication/src/messages/parser/game/score/WeeklyGameRewardParser.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CatalogPageMessageProductData } from '../../catalog'; + +export class WeeklyGameRewardParser implements IMessageParser +{ + private _gameTypeId: number; + private _products: CatalogPageMessageProductData[]; + private _minutesUntilNextWeek: number; + private _rewardingOn: boolean; + + public flush(): boolean + { + this._gameTypeId = -1; + this._products = []; + this._minutesUntilNextWeek = 0; + this._rewardingOn = true; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + let totalProducts: number = wrapper.readInt(); + + while(totalProducts > 0) + { + this._products.push(new CatalogPageMessageProductData(wrapper)); + totalProducts--; + } + + this._minutesUntilNextWeek = wrapper.readInt(); + this._rewardingOn = wrapper.readBoolean(); + + return true; + } + + public get gameTypeId(): number + { + return this._gameTypeId; + } + + public get products(): CatalogPageMessageProductData[] + { + return this._products; + } + + public get minutesUntilNextWeek(): number + { + return this._minutesUntilNextWeek; + } + + public get rewardingOn(): boolean + { + return this._rewardingOn; + } +} diff --git a/packages/communication/src/messages/parser/game/score/WeeklyGameRewardWinnersParser.ts b/packages/communication/src/messages/parser/game/score/WeeklyGameRewardWinnersParser.ts new file mode 100644 index 0000000..6b5cc30 --- /dev/null +++ b/packages/communication/src/messages/parser/game/score/WeeklyGameRewardWinnersParser.ts @@ -0,0 +1,42 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { GameRewardWinnerEntry } from './GameRewardWinnerEntry'; + +export class WeeklyGameRewardWinnersParser implements IMessageParser +{ + private _gameTypeId: number; + private _winners: GameRewardWinnerEntry[]; + + public flush(): boolean + { + this._gameTypeId = -1; + this._winners = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + let totalWinners: number = wrapper.readInt(); + + while(totalWinners > 0) + { + this._winners.push(new GameRewardWinnerEntry(wrapper)); + totalWinners--; + } + + return true; + } + + public get gameTypeId(): number + { + return this._gameTypeId; + } + + public get winners(): GameRewardWinnerEntry[] + { + return this._winners; + } +} diff --git a/packages/communication/src/messages/parser/game/score/index.ts b/packages/communication/src/messages/parser/game/score/index.ts new file mode 100644 index 0000000..1ba2ce8 --- /dev/null +++ b/packages/communication/src/messages/parser/game/score/index.ts @@ -0,0 +1,5 @@ +export * from './Game2WeeklyLeaderboardParser'; +export * from './GameRewardWinnerEntry'; +export * from './LeaderboardEntry'; +export * from './WeeklyGameRewardParser'; +export * from './WeeklyGameRewardWinnersParser'; diff --git a/packages/communication/src/messages/parser/generic/GenericErrorParser.ts b/packages/communication/src/messages/parser/generic/GenericErrorParser.ts new file mode 100644 index 0000000..8c43363 --- /dev/null +++ b/packages/communication/src/messages/parser/generic/GenericErrorParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/generic/index.ts b/packages/communication/src/messages/parser/generic/index.ts new file mode 100644 index 0000000..4e395b3 --- /dev/null +++ b/packages/communication/src/messages/parser/generic/index.ts @@ -0,0 +1 @@ +export * from './GenericErrorParser'; diff --git a/packages/communication/src/messages/parser/gifts/PhoneCollectionStateParser.ts b/packages/communication/src/messages/parser/gifts/PhoneCollectionStateParser.ts new file mode 100644 index 0000000..46b1209 --- /dev/null +++ b/packages/communication/src/messages/parser/gifts/PhoneCollectionStateParser.ts @@ -0,0 +1,41 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PhoneCollectionStateParser implements IMessageParser +{ + private _phoneStatusCode: number; + private _collectionStatusCode: number; + private _millisecondsToAllowProcessReset: number; + + public flush(): boolean + { + this._phoneStatusCode = -1; + this._millisecondsToAllowProcessReset = -1; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._phoneStatusCode = wrapper.readInt(); + this._collectionStatusCode = wrapper.readInt(); + this._millisecondsToAllowProcessReset = wrapper.readInt(); + + return true; + } + + public get phoneStatusCode(): number + { + return this._phoneStatusCode; + } + + public get collectionStatusCode(): number + { + return this._collectionStatusCode; + } + + public get millisecondsToAllowProcessReset(): number + { + return this._millisecondsToAllowProcessReset; + } +} diff --git a/packages/communication/src/messages/parser/gifts/TryPhoneNumberResultParser.ts b/packages/communication/src/messages/parser/gifts/TryPhoneNumberResultParser.ts new file mode 100644 index 0000000..4fe8d46 --- /dev/null +++ b/packages/communication/src/messages/parser/gifts/TryPhoneNumberResultParser.ts @@ -0,0 +1,33 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TryPhoneNumberResultParser implements IMessageParser +{ + private _resultCode: number; + private _millisToAllowProcessReset: number; + + public flush(): boolean + { + this._resultCode = -1; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._resultCode = wrapper.readInt(); + this._millisToAllowProcessReset = wrapper.readInt(); + + return true; + } + + public get resultCode(): number + { + return this._resultCode; + } + + public get millisToAllowProcessReset(): number + { + return this._millisToAllowProcessReset; + } +} diff --git a/packages/communication/src/messages/parser/gifts/TryVerificationCodeResultParser.ts b/packages/communication/src/messages/parser/gifts/TryVerificationCodeResultParser.ts new file mode 100644 index 0000000..4a32bbb --- /dev/null +++ b/packages/communication/src/messages/parser/gifts/TryVerificationCodeResultParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TryVerificationCodeResultParser implements IMessageParser +{ + private _resultCode: number; + private _millisecondsToAllowProcessReset: number; + + public flush(): boolean + { + this._resultCode = -1; + this._millisecondsToAllowProcessReset = -1; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._resultCode = wrapper.readInt(); + this._millisecondsToAllowProcessReset = wrapper.readInt(); + + return true; + } + + public get resultCode(): number + { + return this._resultCode; + } + + public get millisToAllowProcessReset(): number + { + return this._millisecondsToAllowProcessReset; + } +} diff --git a/packages/communication/src/messages/parser/gifts/index.ts b/packages/communication/src/messages/parser/gifts/index.ts new file mode 100644 index 0000000..19357a7 --- /dev/null +++ b/packages/communication/src/messages/parser/gifts/index.ts @@ -0,0 +1,3 @@ +export * from './PhoneCollectionStateParser'; +export * from './TryPhoneNumberResultParser'; +export * from './TryVerificationCodeResultParser'; diff --git a/packages/communication/src/messages/parser/group/GroupBadgePartsParser.ts b/packages/communication/src/messages/parser/group/GroupBadgePartsParser.ts new file mode 100644 index 0000000..73f1696 --- /dev/null +++ b/packages/communication/src/messages/parser/group/GroupBadgePartsParser.ts @@ -0,0 +1,109 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/group/GroupBuyDataParser.ts b/packages/communication/src/messages/parser/group/GroupBuyDataParser.ts new file mode 100644 index 0000000..c667691 --- /dev/null +++ b/packages/communication/src/messages/parser/group/GroupBuyDataParser.ts @@ -0,0 +1,45 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/group/GroupConfirmMemberRemoveParser.ts b/packages/communication/src/messages/parser/group/GroupConfirmMemberRemoveParser.ts new file mode 100644 index 0000000..4240708 --- /dev/null +++ b/packages/communication/src/messages/parser/group/GroupConfirmMemberRemoveParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/group/GroupInformationParser.ts b/packages/communication/src/messages/parser/group/GroupInformationParser.ts new file mode 100644 index 0000000..c73706b --- /dev/null +++ b/packages/communication/src/messages/parser/group/GroupInformationParser.ts @@ -0,0 +1,156 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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 _isFavorite: boolean; + 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._isFavorite = false; + 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(); + this._isFavorite = 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 isFavorite(): boolean + { + return this._isFavorite; + } + + 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; + } +} diff --git a/packages/communication/src/messages/parser/group/GroupMembersParser.ts b/packages/communication/src/messages/parser/group/GroupMembersParser.ts new file mode 100644 index 0000000..ab5e9b8 --- /dev/null +++ b/packages/communication/src/messages/parser/group/GroupMembersParser.ts @@ -0,0 +1,116 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { GroupMemberParser } from './utils'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/group/GroupPurchasedParser.ts b/packages/communication/src/messages/parser/group/GroupPurchasedParser.ts new file mode 100644 index 0000000..ce3c88d --- /dev/null +++ b/packages/communication/src/messages/parser/group/GroupPurchasedParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GroupPurchasedParser implements IMessageParser +{ + private _roomId: number; + private _groupId: number; + + flush(): boolean + { + this._roomId = 0; + this._groupId = 0; + + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._groupId = wrapper.readInt(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get guildId(): number + { + return this._groupId; + } +} diff --git a/packages/communication/src/messages/parser/group/GroupSettingsParser.ts b/packages/communication/src/messages/parser/group/GroupSettingsParser.ts new file mode 100644 index 0000000..964f9b1 --- /dev/null +++ b/packages/communication/src/messages/parser/group/GroupSettingsParser.ts @@ -0,0 +1,149 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { GroupDataBadgePart } from './utils'; + +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 GroupDataBadgePart(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/packages/communication/src/messages/parser/group/HabboGroupDeactivatedMessageParser.ts b/packages/communication/src/messages/parser/group/HabboGroupDeactivatedMessageParser.ts new file mode 100644 index 0000000..0f08897 --- /dev/null +++ b/packages/communication/src/messages/parser/group/HabboGroupDeactivatedMessageParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class HabboGroupDeactivatedMessageParser implements IMessageParser +{ + private _groupId: number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._groupId = wrapper.readInt(); + + return true; + } + + public get groupId(): number + { + return this._groupId; + } +} diff --git a/packages/communication/src/messages/parser/group/index.ts b/packages/communication/src/messages/parser/group/index.ts new file mode 100644 index 0000000..1b24da1 --- /dev/null +++ b/packages/communication/src/messages/parser/group/index.ts @@ -0,0 +1,9 @@ +export * from './GroupBadgePartsParser'; +export * from './GroupBuyDataParser'; +export * from './GroupConfirmMemberRemoveParser'; +export * from './GroupInformationParser'; +export * from './GroupMembersParser'; +export * from './GroupPurchasedParser'; +export * from './GroupSettingsParser'; +export * from './HabboGroupDeactivatedMessageParser'; +export * from './utils'; diff --git a/packages/communication/src/messages/parser/group/utils/GroupDataBadgePart.ts b/packages/communication/src/messages/parser/group/utils/GroupDataBadgePart.ts new file mode 100644 index 0000000..7ebdb58 --- /dev/null +++ b/packages/communication/src/messages/parser/group/utils/GroupDataBadgePart.ts @@ -0,0 +1,22 @@ +export class GroupDataBadgePart +{ + 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/packages/communication/src/messages/parser/group/utils/GroupMemberParser.ts b/packages/communication/src/messages/parser/group/utils/GroupMemberParser.ts new file mode 100644 index 0000000..8bb4cc5 --- /dev/null +++ b/packages/communication/src/messages/parser/group/utils/GroupMemberParser.ts @@ -0,0 +1,76 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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 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; + } +} diff --git a/packages/communication/src/messages/parser/group/utils/index.ts b/packages/communication/src/messages/parser/group/utils/index.ts new file mode 100644 index 0000000..62a121b --- /dev/null +++ b/packages/communication/src/messages/parser/group/utils/index.ts @@ -0,0 +1,2 @@ +export * from './GroupDataBadgePart'; +export * from './GroupMemberParser'; diff --git a/packages/communication/src/messages/parser/groupforums/ExtendedForumData.ts b/packages/communication/src/messages/parser/groupforums/ExtendedForumData.ts new file mode 100644 index 0000000..0bed98c --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/ExtendedForumData.ts @@ -0,0 +1,118 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { ForumData } from './ForumData'; + +export class ExtendedForumData extends ForumData +{ + private _readPermissions: number; + private _postMessagePermissions: number; + private _postThreadPermissions: number; + private _moderatePermissions: number; + private _readPermissionError: string; + private _postMessagePermissionError: string; + private _postThreadPermissionError: string; + private _moderatePermissionError: string; + private _reportPermissionError: string; + private _canChangeSettings: boolean; + private _isStaff: boolean; + + public static parse(wrapper: IMessageDataWrapper): ExtendedForumData + { + const extendedForumData: ExtendedForumData = new ExtendedForumData(); + + ForumData.fillFromMessage(extendedForumData, wrapper); + + extendedForumData._readPermissions = wrapper.readInt(); + extendedForumData._postMessagePermissions = wrapper.readInt(); + extendedForumData._postThreadPermissions = wrapper.readInt(); + extendedForumData._moderatePermissions = wrapper.readInt(); + extendedForumData._readPermissionError = wrapper.readString(); + extendedForumData._postMessagePermissionError = wrapper.readString(); + extendedForumData._postThreadPermissionError = wrapper.readString(); + extendedForumData._moderatePermissionError = wrapper.readString(); + extendedForumData._reportPermissionError = wrapper.readString(); + extendedForumData._canChangeSettings = wrapper.readBoolean(); + extendedForumData._isStaff = wrapper.readBoolean(); + + return extendedForumData; + } + + public get readPermissions(): number + { + return this._readPermissions; + } + + public get postMessagePermissions(): number + { + return this._postMessagePermissions; + } + + public get postThreadPermissions(): number + { + return this._postThreadPermissions; + } + + public get moderatePermissions(): number + { + return this._moderatePermissions; + } + + public get hasReadPermissionError(): boolean + { + return (this._readPermissionError.length === 0); + } + + public get canReport(): boolean + { + return true; + } + + public get hasPostMessagePermissionError(): boolean + { + return (this._postMessagePermissionError.length === 0); + } + + public get hasPostThreadPermissionError(): boolean + { + return (this._postThreadPermissionError.length === 0); + } + + public get hasModeratePermissionError(): boolean + { + return (this._moderatePermissionError.length === 0); + } + + public get canChangeSettings(): boolean + { + return this._canChangeSettings; + } + + public get isStaf(): boolean + { + return this._isStaff; + } + + public get readPermissionError(): string + { + return this._readPermissionError; + } + + public get postMessagePermissionError(): string + { + return this._postMessagePermissionError; + } + + public get postThreadPermissionError(): string + { + return this._postThreadPermissionError; + } + + public get moderatePermissionError(): string + { + return this._moderatePermissionError; + } + + public get reportPermissionError(): string + { + return this._reportPermissionError; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/ForumData.ts b/packages/communication/src/messages/parser/groupforums/ForumData.ts new file mode 100644 index 0000000..1b40a7a --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/ForumData.ts @@ -0,0 +1,135 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { GuildForumThread } from './GuildForumThread'; + +export class ForumData +{ + private _groupId: number; + private _name: string; + private _description: string; + private _icon: string; + private _totalThreads: number; + private _leaderboardScore: number; + private _totalMessages: number; + private _unreadMessages: number; + private _lastMessageId: number; + private _lastMessageAuthorId: number; + private _lastMessageAuthorName: string; + private _lastMessageTimeAsSecondsAgo: number; + + public static parse(wrapper: IMessageDataWrapper): ForumData + { + return this.fillFromMessage(new ForumData(), wrapper); + } + + protected static fillFromMessage(data: ForumData, wrapper: IMessageDataWrapper): ForumData + { + data._groupId = wrapper.readInt(); + data._name = wrapper.readString(); + data._description = wrapper.readString(); + data._icon = wrapper.readString(); + data._totalThreads = wrapper.readInt(); + data._leaderboardScore = wrapper.readInt(); + data._totalMessages = wrapper.readInt(); + data._unreadMessages = wrapper.readInt(); + data._lastMessageId = wrapper.readInt(); + data._lastMessageAuthorId = wrapper.readInt(); + data._lastMessageAuthorName = wrapper.readString(); + data._lastMessageTimeAsSecondsAgo = wrapper.readInt(); + + return data; + } + + public get groupId(): number + { + return this._groupId; + } + + public get name(): string + { + return this._name; + } + + public get description(): string + { + return this._description; + } + + public get icon(): string + { + return this._icon; + } + + public get totalThreads(): number + { + return this._totalThreads; + } + + public get leaderboardScore(): number + { + return this._leaderboardScore; + } + + public get totalMessages(): number + { + return this._totalMessages; + } + + public get unreadMessages(): number + { + return this._unreadMessages; + } + + public get lastMessageId(): number + { + return this._lastMessageId; + } + + public get lastMessageAuthorId(): number + { + return this._lastMessageAuthorId; + } + + public get lastMessageAuthorName(): string + { + return this._lastMessageAuthorName; + } + + public get lastMessageTimeAsSecondsAgo(): number + { + return this._lastMessageTimeAsSecondsAgo; + } + + public updateFrom(forum: ForumData): void + { + this._totalThreads = forum._totalThreads; + this._totalMessages = forum._totalMessages; + this._unreadMessages = forum._unreadMessages; + this._lastMessageAuthorId = forum._lastMessageAuthorId; + this._lastMessageAuthorName = forum._lastMessageAuthorName; + this._lastMessageId = forum._lastMessageId; + this._lastMessageTimeAsSecondsAgo = forum._lastMessageTimeAsSecondsAgo; + } + + public get lastReadMessageId(): number + { + return (this._totalMessages - this._unreadMessages); + } + + public set lastReadMessageId(k: number) + { + this._unreadMessages = (this._totalMessages - k); + + if(this._unreadMessages < 0) this._unreadMessages = 0; + } + + public addNewThread(thread: GuildForumThread): void + { + this._lastMessageAuthorId = thread.lastUserId; + this._lastMessageAuthorName = thread.lastUserName; + this._lastMessageId = thread.lastMessageId; + this._lastMessageTimeAsSecondsAgo = thread.lastCommentTime; + this._totalThreads++; + this._totalMessages++; + this._unreadMessages = 0; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/ForumDataMessageParser.ts b/packages/communication/src/messages/parser/groupforums/ForumDataMessageParser.ts new file mode 100644 index 0000000..9ddccae --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/ForumDataMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { ExtendedForumData } from './ExtendedForumData'; + +export class ForumDataMessageParser implements IMessageParser +{ + private _extendedForumData: ExtendedForumData; + + public flush(): boolean + { + this._extendedForumData = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._extendedForumData = ExtendedForumData.parse(wrapper); + + return true; + } + + public get extendedForumData(): ExtendedForumData + { + return this._extendedForumData; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/GetForumsListMessageParser.ts b/packages/communication/src/messages/parser/groupforums/GetForumsListMessageParser.ts new file mode 100644 index 0000000..7c13abc --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/GetForumsListMessageParser.ts @@ -0,0 +1,69 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { ForumData } from './ForumData'; + +export class GetForumsListMessageParser implements IMessageParser +{ + private _listCode: number; + private _totalAmount: number; + private _startIndex: number; + private _amount: number; + private _forums: ForumData[]; + + public flush(): boolean + { + this._listCode = -1; + this._totalAmount = 0; + this._startIndex = -1; + this._amount = 0; + this._forums = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._listCode = wrapper.readInt(); + this._totalAmount = wrapper.readInt(); + this._startIndex = wrapper.readInt(); + this._amount = wrapper.readInt(); + this._forums = []; + + let i = 0; + + while(i < this._amount) + { + this._forums.push(ForumData.parse(wrapper)); + + i++; + } + + return true; + } + + public get listCode(): number + { + return this._listCode; + } + + public get totalAmount(): number + { + return this._totalAmount; + } + + public get startIndex(): number + { + return this._startIndex; + } + + public get amount(): number + { + return this._amount; + } + + public get forums(): ForumData[] + { + return this._forums; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/GuildForumThread.ts b/packages/communication/src/messages/parser/groupforums/GuildForumThread.ts new file mode 100644 index 0000000..ba07d45 --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/GuildForumThread.ts @@ -0,0 +1,217 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class GuildForumThread +{ + private _threadId: number; + private _authorId: number; + private _authorName: string; + private _creationTimeAsSecondsAgo: number; + private _header: string; + private _totalMessages: number; + private _unreadMessagesCount: number; + private _lastMessageId: number; + private _lastUserId: number; + private _lastUserName: string; + private _lastCommentTime: number; + private _state: number; + private _adminId: number; + private _adminName: string; + private _adminOperationTimeAsSecondsAgo: number; + private _isPinned: boolean; + private _isLocked: boolean; + + public static parse(wrapper: IMessageDataWrapper): GuildForumThread + { + const thread = new GuildForumThread(); + + thread._threadId = wrapper.readInt(); + thread._authorId = wrapper.readInt(); + thread._authorName = wrapper.readString(); + thread._header = wrapper.readString(); + thread._isPinned = wrapper.readBoolean(); + thread._isLocked = wrapper.readBoolean(); + thread._creationTimeAsSecondsAgo = wrapper.readInt(); + thread._totalMessages = wrapper.readInt(); + thread._unreadMessagesCount = wrapper.readInt(); + thread._lastMessageId = wrapper.readInt(); + thread._lastUserId = wrapper.readInt(); + thread._lastUserName = wrapper.readString(); + thread._lastCommentTime = wrapper.readInt(); + thread._state = wrapper.readByte(); + thread._adminId = wrapper.readInt(); + thread._adminName = wrapper.readString(); + thread._adminOperationTimeAsSecondsAgo = wrapper.readInt(); + + return thread; + } + + public get adminOperationTimeAsSecondsAgo(): number + { + return this._adminOperationTimeAsSecondsAgo; + } + + public set adminOperationTimeAsSecondsAgo(k: number) + { + this._adminOperationTimeAsSecondsAgo = k; + } + + public get lastCommentTime(): number + { + return this._lastCommentTime; + } + + public set lastCommentTime(time: number) + { + this._lastCommentTime = time; + } + + public get threadId(): number + { + return this._threadId; + } + + public set threadId(id: number) + { + this._threadId = id; + } + + public get authorId(): number + { + return this._authorId; + } + + public set authorId(id: number) + { + this._authorId = id; + } + + public get authorName(): string + { + return this._authorName; + } + + public set authorName(name: string) + { + this._authorName = name; + } + + public get creationTimeAsSecondsAgo(): number + { + return this._creationTimeAsSecondsAgo; + } + + public set creationTimeAsSecondsAgo(time: number) + { + this._creationTimeAsSecondsAgo = time; + } + + public get header(): string + { + return this._header; + } + + public set header(header: string) + { + this._header = header; + } + + public get lastMessageId(): number + { + return this._lastMessageId; + } + + public set lastMessageId(id: number) + { + this._lastMessageId = id; + } + + public get lastUserId(): number + { + return this._lastUserId; + } + + public set lastUserId(id: number) + { + this._lastUserId = id; + } + + public get lastUserName(): string + { + return this._lastUserName; + } + + public set lastUserName(name: string) + { + this._lastUserName = name; + } + + public get totalMessages(): number + { + return this._totalMessages; + } + + public set totalMessages(total: number) + { + this._totalMessages = total; + } + + public get unreadMessagesCount(): number + { + return this._unreadMessagesCount; + } + + public set unreadMessagesCount(count: number) + { + this._unreadMessagesCount = count; + } + + public get state(): number + { + return this._state; + } + + public set state(state: number) + { + this._state = state; + } + + public get adminId(): number + { + return this._adminId; + } + + public set adminId(id: number) + { + this._adminId = id; + } + + public get adminName(): string + { + return this._adminName; + } + + public set adminName(name: string) + { + this._adminName = name; + } + + public get isPinned(): boolean + { + return this._isPinned; + } + + public set isPinned(k: boolean) + { + this._isPinned = k; + } + + public get isLocked(): boolean + { + return this._isLocked; + } + + public set isLocked(flag: boolean) + { + this._isLocked = flag; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/GuildForumThreadsParser.ts b/packages/communication/src/messages/parser/groupforums/GuildForumThreadsParser.ts new file mode 100644 index 0000000..5b1207d --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/GuildForumThreadsParser.ts @@ -0,0 +1,61 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { GuildForumThread } from './GuildForumThread'; + +export class GuildForumThreadsParser implements IMessageParser +{ + private _groupId: number; + private _startIndex: number; + private _amount: number; + private _threads: GuildForumThread[]; + + public flush(): boolean + { + this._groupId = -1; + this._startIndex = -1; + this._amount = 0; + this._threads = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._groupId = wrapper.readInt(); + this._startIndex = wrapper.readInt(); + this._amount = wrapper.readInt(); + this._threads = []; + + let i = 0; + + while(i < this._amount) + { + this._threads.push(GuildForumThread.parse(wrapper)); + + i++; + } + + return true; + } + + public get groupId(): number + { + return this._groupId; + } + + public get startIndex(): number + { + return this._startIndex; + } + + public get amount(): number + { + return this._amount; + } + + public get threads(): GuildForumThread[] + { + return this._threads; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/MessageData.ts b/packages/communication/src/messages/parser/groupforums/MessageData.ts new file mode 100644 index 0000000..0fdf03c --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/MessageData.ts @@ -0,0 +1,179 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class MessageData +{ + private _groupId: number; + private _messageId: number; + private _messageIndex: number; + private _authorId: number; + private _threadId: number; + private _creationTime: number; + private _messageText: string; + private _authorName: string; + private _authorFigure: string; + private _state: number; + private _adminId: number; + private _adminName: string; + private _adminOperationTimeAsSeccondsAgo: number; + private _authorPostCount: number; + + public static parse(wrapper: IMessageDataWrapper): MessageData + { + const messageData = new MessageData(); + + messageData._messageId = wrapper.readInt(); + messageData._messageIndex = wrapper.readInt(); + messageData._authorId = wrapper.readInt(); + messageData._authorName = wrapper.readString(); + messageData._authorFigure = wrapper.readString(); + messageData._creationTime = wrapper.readInt(); + messageData._messageText = wrapper.readString(); + messageData._state = wrapper.readByte(); + messageData._adminId = wrapper.readInt(); + messageData._adminName = wrapper.readString(); + messageData._adminOperationTimeAsSeccondsAgo = wrapper.readInt(); + messageData._authorPostCount = wrapper.readInt(); + + return messageData; + } + + public get state(): number + { + return this._state; + } + + public set state(state: number) + { + this._state = state; + } + + public get adminId(): number + { + return this._adminId; + } + + public set adminId(id: number) + { + this._adminId = id; + } + + public get adminName(): string + { + return this._adminName; + } + + public set adminName(name: string) + { + this._adminName = name; + } + + public get adminOperationTimeAsSeccondsAgo(): number + { + return this._adminOperationTimeAsSeccondsAgo; + } + + public set adminOperationTimeAsSeccondsAgo(time: number) + { + this._adminOperationTimeAsSeccondsAgo = time; + } + + public get messageId(): number + { + return this._messageId; + } + + public set messageId(id: number) + { + this._messageId = id; + } + + public get creationTime(): number + { + return this._creationTime; + } + + public set creationTime(time: number) + { + this._creationTime = time; + } + + public get authorName(): string + { + return this._authorName; + } + + public set authorName(name: string) + { + this._authorName = name; + } + + public get authorFigure(): string + { + return this._authorFigure; + } + + public set authorFigure(figure: string) + { + this._authorFigure = figure; + } + + public get threadId(): number + { + return this._threadId; + } + + public set threadId(id: number) + { + this._threadId = id; + } + + public get messageIndex(): number + { + return this._messageIndex; + } + + public set messageIndex(index: number) + { + this._messageIndex = index; + } + + public set groupID(id: number) + { + this._groupId = id; + } + + public get groupId(): number + { + return this._groupId; + } + + public get authorId(): number + { + return this._authorId; + } + + public set authorId(id: number) + { + this._authorId = id; + } + + public get messageText(): string + { + return this._messageText; + } + + public set messageText(text: string) + { + this._messageText = text; + } + + public get authorPostCount(): number + { + return this._authorPostCount; + } + + public set authorPostCount(count: number) + { + this._authorPostCount = count; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/PostMessageMessageParser.ts b/packages/communication/src/messages/parser/groupforums/PostMessageMessageParser.ts new file mode 100644 index 0000000..d973204 --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/PostMessageMessageParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { MessageData } from './MessageData'; + +export class PostMessageMessageParser implements IMessageParser +{ + private _groupId: number; + private _threadId: number; + private _message: MessageData; + + public flush(): boolean + { + this._groupId = -1; + this._threadId = -1; + this._message = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._groupId = wrapper.readInt(); + this._threadId = wrapper.readInt(); + this._message = MessageData.parse(wrapper); + + return true; + } + + public get groupId(): number + { + return this._groupId; + } + + public get threadId(): number + { + return this._threadId; + } + + public get message(): MessageData + { + return this._message; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/PostThreadMessageParser.ts b/packages/communication/src/messages/parser/groupforums/PostThreadMessageParser.ts new file mode 100644 index 0000000..3f65cc6 --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/PostThreadMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { GuildForumThread } from './GuildForumThread'; + +export class PostThreadMessageParser implements IMessageParser +{ + private _groupId: number; + private _thread: GuildForumThread; + + public flush(): boolean + { + this._groupId = -1; + this._thread = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._groupId = wrapper.readInt(); + this._thread = GuildForumThread.parse(wrapper); + + return true; + } + + public get groupId(): number + { + return this._groupId; + } + + public get thread(): GuildForumThread + { + return this._thread; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/ThreadMessagesMessageParser.ts b/packages/communication/src/messages/parser/groupforums/ThreadMessagesMessageParser.ts new file mode 100644 index 0000000..5d0e1ee --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/ThreadMessagesMessageParser.ts @@ -0,0 +1,74 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { MessageData } from './MessageData'; + +export class ThreadMessagesMessageParser implements IMessageParser +{ + private _groupId: number; + private _threadId: number; + private _startIndex: number; + private _amount: number; + private _messages: MessageData[]; + + public flush(): boolean + { + this._groupId = -1; + this._threadId = -1; + this._startIndex = -1; + this._amount = 0; + this._messages = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._groupId = wrapper.readInt(); + this._threadId = wrapper.readInt(); + this._startIndex = wrapper.readInt(); + this._amount = wrapper.readInt(); + this._messages = []; + + let i = 0; + + while(i < this._amount) + { + const message = MessageData.parse(wrapper); + + message.groupID = this._groupId; + message.threadId = this._threadId; + + this._messages.push(message); + + i++; + } + + return true; + } + + public get groupId(): number + { + return this._groupId; + } + + public get threadId(): number + { + return this._threadId; + } + + public get startIndex(): number + { + return this._startIndex; + } + + public get amount(): number + { + return this._amount; + } + + public get messages(): MessageData[] + { + return this._messages; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/UnreadForumsCountMessageParser.ts b/packages/communication/src/messages/parser/groupforums/UnreadForumsCountMessageParser.ts new file mode 100644 index 0000000..a8616d9 --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/UnreadForumsCountMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class UnreadForumsCountMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/UpdateMessageMessageParser.ts b/packages/communication/src/messages/parser/groupforums/UpdateMessageMessageParser.ts new file mode 100644 index 0000000..6fce331 --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/UpdateMessageMessageParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { MessageData } from './MessageData'; + +export class UpdateMessageMessageParser implements IMessageParser +{ + private _groupId: number; + private _threadId: number; + private _message: MessageData; + + public flush(): boolean + { + this._groupId = -1; + this._threadId = -1; + this._message = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._groupId = wrapper.readInt(); + this._threadId = wrapper.readInt(); + this._message = MessageData.parse(wrapper); + + return true; + } + + public get groupId(): number + { + return this._groupId; + } + + public get threadId(): number + { + return this._threadId; + } + + public get message(): MessageData + { + return this._message; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/UpdateThreadMessageParser.ts b/packages/communication/src/messages/parser/groupforums/UpdateThreadMessageParser.ts new file mode 100644 index 0000000..7e6abb7 --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/UpdateThreadMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { GuildForumThread } from './GuildForumThread'; + +export class UpdateThreadMessageParser implements IMessageParser +{ + private _groupId: number; + private _thread: GuildForumThread; + + public flush(): boolean + { + this._groupId = -1; + this._thread = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._groupId = wrapper.readInt(); + this._thread = GuildForumThread.parse(wrapper); + + return true; + } + + public get groupId(): number + { + return this._groupId; + } + + public get thread(): GuildForumThread + { + return this._thread; + } +} diff --git a/packages/communication/src/messages/parser/groupforums/index.ts b/packages/communication/src/messages/parser/groupforums/index.ts new file mode 100644 index 0000000..6f07091 --- /dev/null +++ b/packages/communication/src/messages/parser/groupforums/index.ts @@ -0,0 +1,13 @@ +export * from './ExtendedForumData'; +export * from './ForumData'; +export * from './ForumDataMessageParser'; +export * from './GetForumsListMessageParser'; +export * from './GuildForumThread'; +export * from './GuildForumThreadsParser'; +export * from './MessageData'; +export * from './PostMessageMessageParser'; +export * from './PostThreadMessageParser'; +export * from './ThreadMessagesMessageParser'; +export * from './UnreadForumsCountMessageParser'; +export * from './UpdateMessageMessageParser'; +export * from './UpdateThreadMessageParser'; diff --git a/packages/communication/src/messages/parser/handshake/CompleteDiffieHandshakeParser.ts b/packages/communication/src/messages/parser/handshake/CompleteDiffieHandshakeParser.ts new file mode 100644 index 0000000..38f9226 --- /dev/null +++ b/packages/communication/src/messages/parser/handshake/CompleteDiffieHandshakeParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CompleteDiffieHandshakeParser implements IMessageParser +{ + private _encryptedPublicKey: string = null; + private _serverClientEncryption: boolean = false; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._encryptedPublicKey = wrapper.readString(); + + if(wrapper.bytesAvailable) + { + this._serverClientEncryption = wrapper.readBoolean(); + } + + return true; + } + + public get encryptedPublicKey(): string + { + return this._encryptedPublicKey; + } + + public get serverClientEncryption(): boolean + { + return this._serverClientEncryption; + } +} diff --git a/packages/communication/src/messages/parser/handshake/DisconnectReasonParser.ts b/packages/communication/src/messages/parser/handshake/DisconnectReasonParser.ts new file mode 100644 index 0000000..e7d997c --- /dev/null +++ b/packages/communication/src/messages/parser/handshake/DisconnectReasonParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class DisconnectReasonParser implements IMessageParser +{ + private _reason: number; + + public flush(): boolean + { + this._reason = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._reason = 0; + + if(wrapper.bytesAvailable) + { + this._reason = wrapper.readInt(); + } + + return true; + } + + public get reason(): number + { + return this._reason; + } +} diff --git a/packages/communication/src/messages/parser/handshake/IdentityAccountsParser.ts b/packages/communication/src/messages/parser/handshake/IdentityAccountsParser.ts new file mode 100644 index 0000000..37ec22a --- /dev/null +++ b/packages/communication/src/messages/parser/handshake/IdentityAccountsParser.ts @@ -0,0 +1,39 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class IdentityAccountsParser implements IMessageParser +{ + private _accounts: Map; + + public flush(): boolean + { + if(this._accounts) + { + this._accounts = new Map(); + } + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._accounts = new Map(); + + let totalCount = wrapper.readInt(); + + while(totalCount > 0) + { + this._accounts.set(wrapper.readInt(), wrapper.readString()); + + totalCount--; + } + + return true; + } + + public get accounts(): Map + { + return this._accounts; + } +} diff --git a/packages/communication/src/messages/parser/handshake/InitDiffieHandshakeParser.ts b/packages/communication/src/messages/parser/handshake/InitDiffieHandshakeParser.ts new file mode 100644 index 0000000..30ad728 --- /dev/null +++ b/packages/communication/src/messages/parser/handshake/InitDiffieHandshakeParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class InitDiffieHandshakeParser implements IMessageParser +{ + private _encryptedPrime: string; + private _encryptedGenerator: string; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._encryptedPrime = wrapper.readString(); + this._encryptedGenerator = wrapper.readString(); + + return true; + } + + public get encryptedPrime(): string + { + return this._encryptedPrime; + } + + public get encryptedGenerator(): string + { + return this._encryptedGenerator; + } +} diff --git a/packages/communication/src/messages/parser/handshake/NoobnessLevelMessageParser.ts b/packages/communication/src/messages/parser/handshake/NoobnessLevelMessageParser.ts new file mode 100644 index 0000000..e64919b --- /dev/null +++ b/packages/communication/src/messages/parser/handshake/NoobnessLevelMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class NoobnessLevelMessageParser implements IMessageParser +{ + private _noobnessLevel: number; + + public flush(): boolean + { + this._noobnessLevel = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._noobnessLevel = wrapper.readInt(); + + return true; + } + + public get noobnessLevel(): number + { + return this._noobnessLevel; + } +} diff --git a/packages/communication/src/messages/parser/handshake/index.ts b/packages/communication/src/messages/parser/handshake/index.ts new file mode 100644 index 0000000..786e98b --- /dev/null +++ b/packages/communication/src/messages/parser/handshake/index.ts @@ -0,0 +1,5 @@ +export * from './CompleteDiffieHandshakeParser'; +export * from './DisconnectReasonParser'; +export * from './IdentityAccountsParser'; +export * from './InitDiffieHandshakeParser'; +export * from './NoobnessLevelMessageParser'; diff --git a/packages/communication/src/messages/parser/help/CallForHelpDisabledNotifyMessageParser.ts b/packages/communication/src/messages/parser/help/CallForHelpDisabledNotifyMessageParser.ts new file mode 100644 index 0000000..1af8a2a --- /dev/null +++ b/packages/communication/src/messages/parser/help/CallForHelpDisabledNotifyMessageParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CallForHelpDisabledNotifyMessageParser implements IMessageParser +{ + private _infoUrl: string; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._infoUrl = wrapper.readString(); + + return true; + } + + public get infoUrl(): string + { + return this._infoUrl; + } +} diff --git a/packages/communication/src/messages/parser/help/CallForHelpPendingCallsDeletedMessageParser.ts b/packages/communication/src/messages/parser/help/CallForHelpPendingCallsDeletedMessageParser.ts new file mode 100644 index 0000000..a080247 --- /dev/null +++ b/packages/communication/src/messages/parser/help/CallForHelpPendingCallsDeletedMessageParser.ts @@ -0,0 +1,14 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CallForHelpPendingCallsDeletedMessageParser implements IMessageParser +{ + flush(): boolean + { + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + return true; + } +} diff --git a/packages/communication/src/messages/parser/help/CallForHelpPendingCallsMessageParser.ts b/packages/communication/src/messages/parser/help/CallForHelpPendingCallsMessageParser.ts new file mode 100644 index 0000000..d8e1e6e --- /dev/null +++ b/packages/communication/src/messages/parser/help/CallForHelpPendingCallsMessageParser.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CallForHelpPendingCallsMessageParser implements IMessageParser +{ + private _calls: ICall[]; + + flush(): boolean + { + this._calls = []; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._calls = []; + + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + const callId = wrapper.readString(); + const timestamp = wrapper.readString(); + const message = wrapper.readString(); + + this._calls.push({ callId: callId, timeStamp: timestamp, message: message }); + } + return true; + } + + public get pendingCalls(): ICall[] + { + return this._calls; + } + + public get count(): number + { + return this._calls.length; + } +} + +export interface ICall +{ + callId: string; + timeStamp: string; + message: string; +} diff --git a/packages/communication/src/messages/parser/help/CallForHelpReplyMessageParser.ts b/packages/communication/src/messages/parser/help/CallForHelpReplyMessageParser.ts new file mode 100644 index 0000000..ed8c770 --- /dev/null +++ b/packages/communication/src/messages/parser/help/CallForHelpReplyMessageParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CallForHelpReplyMessageParser implements IMessageParser +{ + private _message: string; + + flush(): boolean + { + this._message = null; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._message = wrapper.readString(); + return true; + } + + public get message(): string + { + return this._message; + } +} diff --git a/packages/communication/src/messages/parser/help/CallForHelpResultMessageParser.ts b/packages/communication/src/messages/parser/help/CallForHelpResultMessageParser.ts new file mode 100644 index 0000000..bc75465 --- /dev/null +++ b/packages/communication/src/messages/parser/help/CallForHelpResultMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/help/ChatReviewSessionDetachedMessageParser.ts b/packages/communication/src/messages/parser/help/ChatReviewSessionDetachedMessageParser.ts new file mode 100644 index 0000000..23af15d --- /dev/null +++ b/packages/communication/src/messages/parser/help/ChatReviewSessionDetachedMessageParser.ts @@ -0,0 +1,15 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ChatReviewSessionDetachedMessageParser implements IMessageParser +{ + flush(): boolean + { + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + return true; + } + +} diff --git a/packages/communication/src/messages/parser/help/ChatReviewSessionOfferedToGuideMessageParser.ts b/packages/communication/src/messages/parser/help/ChatReviewSessionOfferedToGuideMessageParser.ts new file mode 100644 index 0000000..cf2e9e7 --- /dev/null +++ b/packages/communication/src/messages/parser/help/ChatReviewSessionOfferedToGuideMessageParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ChatReviewSessionOfferedToGuideMessageParser implements IMessageParser +{ + private _acceptanceTimeout: number; + + flush(): boolean + { + this._acceptanceTimeout = -1; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._acceptanceTimeout = wrapper.readInt(); + return true; + } + + public get acceptanceTimeout(): number + { + return this._acceptanceTimeout; + } +} diff --git a/packages/communication/src/messages/parser/help/ChatReviewSessionResultsMessageParser.ts b/packages/communication/src/messages/parser/help/ChatReviewSessionResultsMessageParser.ts new file mode 100644 index 0000000..4280fea --- /dev/null +++ b/packages/communication/src/messages/parser/help/ChatReviewSessionResultsMessageParser.ts @@ -0,0 +1,47 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ChatReviewSessionResultsMessageParser implements IMessageParser +{ + private _winningVoteCode: number; + private _ownVoteCode: number; + private _finalStatus: number[]; + + flush(): boolean + { + this._winningVoteCode = -1; + this._ownVoteCode = -1; + this._finalStatus = null; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._finalStatus = []; + this._winningVoteCode = wrapper.readInt(); + this._ownVoteCode = wrapper.readInt(); + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._finalStatus.push(wrapper.readInt()); + } + + return true; + } + + public get winningVoteCode(): number + { + return this._winningVoteCode; + } + + public get ownVoteCode(): number + { + return this._ownVoteCode; + } + + public get finalStatus(): number[] + { + return this._finalStatus; + } + +} diff --git a/packages/communication/src/messages/parser/help/ChatReviewSessionStartedMessageParser.ts b/packages/communication/src/messages/parser/help/ChatReviewSessionStartedMessageParser.ts new file mode 100644 index 0000000..fea86a9 --- /dev/null +++ b/packages/communication/src/messages/parser/help/ChatReviewSessionStartedMessageParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ChatReviewSessionStartedMessageParser implements IMessageParser +{ + private _votingTimeout: number; + private _chatRecord: string; + + flush(): boolean + { + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._votingTimeout = wrapper.readInt(); + this._chatRecord = wrapper.readString(); + return true; + } + + public get votingTimeout(): number + { + return this._votingTimeout; + } + + public get chatRecord(): string + { + return this._chatRecord; + } +} diff --git a/packages/communication/src/messages/parser/help/ChatReviewSessionVotingStatusMessageParser.ts b/packages/communication/src/messages/parser/help/ChatReviewSessionVotingStatusMessageParser.ts new file mode 100644 index 0000000..1c3edb3 --- /dev/null +++ b/packages/communication/src/messages/parser/help/ChatReviewSessionVotingStatusMessageParser.ts @@ -0,0 +1,38 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ChatReviewSessionVotingStatusMessageParser implements IMessageParser +{ + public static readonly AWAITING_VOTE = 0; + public static readonly VOTED_OK = 1; + public static readonly VOTED_BAD = 2; + public static readonly VOTED_VERY_BAD = 3; + public static readonly NO_VOTE = 4; + public static readonly FINDING_NEW_VOTER = 5; + + private _status: number[]; + + flush(): boolean + { + this._status = null; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._status = []; + + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._status.push(wrapper.readInt()); + } + + return true; + } + + public get status(): number[] + { + return this._status; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideOnDutyStatusMessageParser.ts b/packages/communication/src/messages/parser/help/GuideOnDutyStatusMessageParser.ts new file mode 100644 index 0000000..920d603 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideOnDutyStatusMessageParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideOnDutyStatusMessageParser implements IMessageParser +{ + private _onDuty: boolean; + private _guidesOnDuty: number; + private _helpersOnDuty: number; + private _guardiansOnDuty: number; + + public flush(): boolean + { + this._onDuty = false; + this._guidesOnDuty = 0; + this._helpersOnDuty = 0; + this._guardiansOnDuty = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._onDuty = wrapper.readBoolean(); + this._guidesOnDuty = wrapper.readInt(); + this._helpersOnDuty = wrapper.readInt(); + this._guardiansOnDuty = wrapper.readInt(); + + return true; + } + + public get onDuty(): boolean + { + return this._onDuty; + } + + public get guidesOnDuty(): number + { + return this._guidesOnDuty; + } + + public get helpersOnDuty(): number + { + return this._helpersOnDuty; + } + + public get guardiansOnDuty(): number + { + return this._guardiansOnDuty; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideReportingStatusMessageParser.ts b/packages/communication/src/messages/parser/help/GuideReportingStatusMessageParser.ts new file mode 100644 index 0000000..e73f3e0 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideReportingStatusMessageParser.ts @@ -0,0 +1,49 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PendingGuideTicketData } from './PendingGuideTicketData'; + +export class GuideReportingStatusMessageParser implements IMessageParser +{ + public static readonly GUIDE_REPORTING_STATUS_OK: number = 0; + public static readonly GUIDE_REPORTING_STATUS_PENDING_TICKET: number = 1; + public static readonly GUIDE_REPORTING_STATUS_ABUSIVE: number = 2; + public static readonly GUIDE_REPORTING_STATUS_REPORTING_TOO_QUICKLY: number = 3; + + private _statusCode: number; + private _pendingTicket: PendingGuideTicketData; + + public flush(): boolean + { + this._statusCode = 0; + this._pendingTicket = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._statusCode = wrapper.readInt(); + this._pendingTicket = new PendingGuideTicketData( + wrapper.readInt(), + wrapper.readInt(), + wrapper.readBoolean(), + wrapper.readString(), + wrapper.readString(), + wrapper.readString(), + wrapper.readString() + ); + + return true; + } + + public get statusCode(): number + { + return this._statusCode; + } + + public get pendingTicket(): PendingGuideTicketData + { + return this._pendingTicket; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideSessionAttachedMessageParser.ts b/packages/communication/src/messages/parser/help/GuideSessionAttachedMessageParser.ts new file mode 100644 index 0000000..5ab009d --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideSessionAttachedMessageParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideSessionAttachedMessageParser implements IMessageParser +{ + private _asGuide: boolean; + private _helpRequestType: number; + private _helpRequestDescription: string; + private _roleSpecificWaitTime: number; + + public flush(): boolean + { + this._asGuide = false; + this._helpRequestType = 0; + this._helpRequestDescription = null; + this._roleSpecificWaitTime = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._asGuide = wrapper.readBoolean(); + this._helpRequestType = wrapper.readInt(); + this._helpRequestDescription = wrapper.readString(); + this._roleSpecificWaitTime = wrapper.readInt(); + + return true; + } + + public get asGuide(): boolean + { + return this._asGuide; + } + + public get helpRequestType(): number + { + return this._helpRequestType; + } + + public get helpRequestDescription(): string + { + return this._helpRequestDescription; + } + + public get roleSpecificWaitTime(): number + { + return this._roleSpecificWaitTime; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideSessionDetachedMessageParser.ts b/packages/communication/src/messages/parser/help/GuideSessionDetachedMessageParser.ts new file mode 100644 index 0000000..c4dac16 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideSessionDetachedMessageParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideSessionDetachedMessageParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideSessionEndedMessageParser.ts b/packages/communication/src/messages/parser/help/GuideSessionEndedMessageParser.ts new file mode 100644 index 0000000..0a8dcf1 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideSessionEndedMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideSessionEndedMessageParser implements IMessageParser +{ + private _endReason: number; + + public flush(): boolean + { + this._endReason = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._endReason = wrapper.readInt(); + + return true; + } + + public get endReason(): number + { + return this._endReason; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideSessionErrorMessageParser.ts b/packages/communication/src/messages/parser/help/GuideSessionErrorMessageParser.ts new file mode 100644 index 0000000..815ba14 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideSessionErrorMessageParser.ts @@ -0,0 +1,33 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideSessionErrorMessageParser implements IMessageParser +{ + public static readonly ERROR_GENERIC: number = 0; + public static readonly ERROR_GUIDES_REJECT: number = 1; + public static readonly ERROR_NOT_ENOUGH_GUIDES: number = 2; + public static readonly ERROR_NOT_ENOUGH_VOTES: number = 3; + public static readonly ERROR_NO_CHATLOG_FOUND: number = 4; + + 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/packages/communication/src/messages/parser/help/GuideSessionInvitedToGuideRoomMessageParser.ts b/packages/communication/src/messages/parser/help/GuideSessionInvitedToGuideRoomMessageParser.ts new file mode 100644 index 0000000..8810cf5 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideSessionInvitedToGuideRoomMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideSessionInvitedToGuideRoomMessageParser implements IMessageParser +{ + private _roomId: number; + private _roomName: string; + + public flush(): boolean + { + this._roomId = 0; + this._roomName = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._roomName = wrapper.readString(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get roomName(): string + { + return this._roomName; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideSessionMessageMessageParser.ts b/packages/communication/src/messages/parser/help/GuideSessionMessageMessageParser.ts new file mode 100644 index 0000000..43731e3 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideSessionMessageMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideSessionMessageMessageParser implements IMessageParser +{ + private _chatMessage: string; + private _senderId: number; + + public flush(): boolean + { + this._chatMessage = null; + this._senderId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._chatMessage = wrapper.readString(); + this._senderId = wrapper.readInt(); + + return true; + } + + public get chatMessage(): string + { + return this._chatMessage; + } + + public get senderId(): number + { + return this._senderId; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideSessionPartnerIsTypingMessageParser.ts b/packages/communication/src/messages/parser/help/GuideSessionPartnerIsTypingMessageParser.ts new file mode 100644 index 0000000..08400fb --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideSessionPartnerIsTypingMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideSessionPartnerIsTypingMessageParser implements IMessageParser +{ + private _isTyping: boolean; + + public flush(): boolean + { + this._isTyping = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._isTyping = wrapper.readBoolean(); + + return true; + } + + public get isTyping(): boolean + { + return this._isTyping; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideSessionRequesterRoomMessageParser.ts b/packages/communication/src/messages/parser/help/GuideSessionRequesterRoomMessageParser.ts new file mode 100644 index 0000000..d9dc5d1 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideSessionRequesterRoomMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideSessionRequesterRoomMessageParser implements IMessageParser +{ + private _requesterRoomId: number; + + public flush(): boolean + { + this._requesterRoomId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._requesterRoomId = wrapper.readInt(); + + return true; + } + + public get requesterRoomId(): number + { + return this._requesterRoomId; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideSessionStartedMessageParser.ts b/packages/communication/src/messages/parser/help/GuideSessionStartedMessageParser.ts new file mode 100644 index 0000000..f47bfc6 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideSessionStartedMessageParser.ts @@ -0,0 +1,67 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideSessionStartedMessageParser implements IMessageParser +{ + private _requesterUserId: number; + private _requesterName: string; + private _requesterFigure: string; + private _guideUserId: number; + private _guideName: string; + private _guideFigure: string; + + public flush(): boolean + { + this._requesterUserId = 0; + this._requesterName = null; + this._requesterFigure = null; + this._guideUserId = 0; + this._guideName = null; + this._guideFigure = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._requesterUserId = wrapper.readInt(); + this._requesterName = wrapper.readString(); + this._requesterFigure = wrapper.readString(); + this._guideUserId = wrapper.readInt(); + this._guideName = wrapper.readString(); + this._guideFigure = wrapper.readString(); + + return true; + } + + public get requesterUserId(): number + { + return this._requesterUserId; + } + + public get requesterName(): string + { + return this._requesterName; + } + + public get requesterFigure(): string + { + return this._requesterFigure; + } + + public get guideUserId(): number + { + return this._guideUserId; + } + + public get guideName(): string + { + return this._guideName; + } + + public get guideFigure(): string + { + return this._guideFigure; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideTicketCreationResultMessageParser.ts b/packages/communication/src/messages/parser/help/GuideTicketCreationResultMessageParser.ts new file mode 100644 index 0000000..fd3ba08 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideTicketCreationResultMessageParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideTicketCreationResultMessageParser implements IMessageParser +{ + public static readonly CREATION_RESULT_OK: number = 0; + public static readonly CREATION_RESULT_UNABLE_TO_REPORT: number = 1; + public static readonly CREATION_RESULT_NO_CHATLOG_FOUND: number = 2; + public static readonly CREATION_RESULT_BULLY_ALREADY_REPORTED: number = 3; + + private _result: number; + + public flush(): boolean + { + this._result = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._result = wrapper.readInt(); + + return true; + } + + public get result(): number + { + return this._result; + } +} diff --git a/packages/communication/src/messages/parser/help/GuideTicketResolutionMessageParser.ts b/packages/communication/src/messages/parser/help/GuideTicketResolutionMessageParser.ts new file mode 100644 index 0000000..33c6bd9 --- /dev/null +++ b/packages/communication/src/messages/parser/help/GuideTicketResolutionMessageParser.ts @@ -0,0 +1,31 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuideTicketResolutionMessageParser implements IMessageParser +{ + public static readonly RESOLUTION_GUARDIANS_TOOK_ACTION: number = 0; + public static readonly RESOLUTION_FORWARDED_TO_MODERATORS: number = 1; + public static readonly RESOLUTION_REPORTER_IS_ABUSIVE: number = 2; + + private _resolution: number; + + public flush(): boolean + { + this._resolution = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._resolution = wrapper.readInt(); + + return true; + } + + public get resolution(): number + { + return this._resolution; + } +} diff --git a/packages/communication/src/messages/parser/help/HotelMergeNameChangeParser.ts b/packages/communication/src/messages/parser/help/HotelMergeNameChangeParser.ts new file mode 100644 index 0000000..53d3417 --- /dev/null +++ b/packages/communication/src/messages/parser/help/HotelMergeNameChangeParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class HotelMergeNameChangeParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/help/IssueCloseNotificationMessageParser.ts b/packages/communication/src/messages/parser/help/IssueCloseNotificationMessageParser.ts new file mode 100644 index 0000000..5518d90 --- /dev/null +++ b/packages/communication/src/messages/parser/help/IssueCloseNotificationMessageParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class IssueCloseNotificationMessageParser implements IMessageParser +{ + private _closeReason: number; + private _messageText: string; + + public flush(): boolean + { + this._closeReason = 0; + this._messageText = ''; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._closeReason = wrapper.readInt(); + this._messageText = wrapper.readString(); + + return true; + } + + public get closeReason(): number + { + return this._closeReason; + } + + public get messageText(): string + { + return this._messageText; + } +} diff --git a/packages/communication/src/messages/parser/help/PendingGuideTicketData.ts b/packages/communication/src/messages/parser/help/PendingGuideTicketData.ts new file mode 100644 index 0000000..fa592e8 --- /dev/null +++ b/packages/communication/src/messages/parser/help/PendingGuideTicketData.ts @@ -0,0 +1,91 @@ +export class PendingGuideTicketData +{ + private _type: number; + private _secondsAgo: number; + private _isGuide: boolean; + private _otherPartyName: string; + private _otherPartyFigure: string; + private _description: string; + private _roomName: string; + + constructor(type: number, secondsAgo: number, isGuide: boolean, otherPartyName: string, otherPartyFigure: string, description: string, roomName: string) + { + this._type = type; + this._secondsAgo = secondsAgo; + this._isGuide = isGuide; + this._otherPartyName = otherPartyName; + this._otherPartyFigure = otherPartyFigure; + this._description = description; + this._roomName = roomName; + } + + public get type(): number + { + return this._type; + } + + public set type(value: number) + { + this._type = value; + } + + public get secondsAgo(): number + { + return this._secondsAgo; + } + + public set secondsAgo(value: number) + { + this._secondsAgo = value; + } + + public get isGuide(): boolean + { + return this._isGuide; + } + + public set isGuide(value: boolean) + { + this._isGuide = value; + } + + public get otherPartyName(): string + { + return this._otherPartyName; + } + + public set otherPartyName(value: string) + { + this._otherPartyName = value; + } + + public get otherPartyFigure(): string + { + return this._otherPartyFigure; + } + + public set otherPartyFigure(value: string) + { + this._otherPartyFigure = value; + } + + public get description(): string + { + return this._description; + } + + public set description(value: string) + { + this._description = value; + } + + public get roomName(): string + { + return this._roomName; + } + + public set roomName(value: string) + { + this._roomName = value; + } +} diff --git a/packages/communication/src/messages/parser/help/QuizDataMessageParser.ts b/packages/communication/src/messages/parser/help/QuizDataMessageParser.ts new file mode 100644 index 0000000..d78699b --- /dev/null +++ b/packages/communication/src/messages/parser/help/QuizDataMessageParser.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class QuizDataMessageParser implements IMessageParser +{ + private _quizCode: string; + private _questionIds: number[]; + + public flush(): boolean + { + this._quizCode = null; + this._questionIds = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._quizCode = wrapper.readString(); + + const size = wrapper.readInt(); + + this._questionIds = []; + + for(let i = 0; i < size; i++) this._questionIds.push(wrapper.readInt()); + + return true; + } + + public get quizCode(): string + { + return this._quizCode; + } + + public get questionIds(): number[] + { + return this._questionIds; + } +} diff --git a/packages/communication/src/messages/parser/help/QuizResultsMessageParser.ts b/packages/communication/src/messages/parser/help/QuizResultsMessageParser.ts new file mode 100644 index 0000000..e0b52da --- /dev/null +++ b/packages/communication/src/messages/parser/help/QuizResultsMessageParser.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class QuizResultsMessageParser implements IMessageParser +{ + private _quizCode: string; + private _questionIdsForWrongAnswers: number[]; + + public flush(): boolean + { + this._quizCode = null; + this._questionIdsForWrongAnswers = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._quizCode = wrapper.readString(); + + const size = wrapper.readInt(); + + this._questionIdsForWrongAnswers = []; + + for(let i = 0; i < size; i++) this._questionIdsForWrongAnswers.push(wrapper.readInt()); + + return true; + } + + public get quizCode(): string + { + return this._quizCode; + } + + public get questionIdsForWrongAnswers(): number[] + { + return this._questionIdsForWrongAnswers; + } +} diff --git a/packages/communication/src/messages/parser/help/index.ts b/packages/communication/src/messages/parser/help/index.ts new file mode 100644 index 0000000..684885f --- /dev/null +++ b/packages/communication/src/messages/parser/help/index.ts @@ -0,0 +1,28 @@ +export * from './CallForHelpDisabledNotifyMessageParser'; +export * from './CallForHelpPendingCallsDeletedMessageParser'; +export * from './CallForHelpPendingCallsMessageParser'; +export * from './CallForHelpReplyMessageParser'; +export * from './CallForHelpResultMessageParser'; +export * from './ChatReviewSessionDetachedMessageParser'; +export * from './ChatReviewSessionOfferedToGuideMessageParser'; +export * from './ChatReviewSessionResultsMessageParser'; +export * from './ChatReviewSessionStartedMessageParser'; +export * from './ChatReviewSessionVotingStatusMessageParser'; +export * from './GuideOnDutyStatusMessageParser'; +export * from './GuideReportingStatusMessageParser'; +export * from './GuideSessionAttachedMessageParser'; +export * from './GuideSessionDetachedMessageParser'; +export * from './GuideSessionEndedMessageParser'; +export * from './GuideSessionErrorMessageParser'; +export * from './GuideSessionInvitedToGuideRoomMessageParser'; +export * from './GuideSessionMessageMessageParser'; +export * from './GuideSessionPartnerIsTypingMessageParser'; +export * from './GuideSessionRequesterRoomMessageParser'; +export * from './GuideSessionStartedMessageParser'; +export * from './GuideTicketCreationResultMessageParser'; +export * from './GuideTicketResolutionMessageParser'; +export * from './HotelMergeNameChangeParser'; +export * from './IssueCloseNotificationMessageParser'; +export * from './PendingGuideTicketData'; +export * from './QuizDataMessageParser'; +export * from './QuizResultsMessageParser'; diff --git a/packages/communication/src/messages/parser/index.ts b/packages/communication/src/messages/parser/index.ts new file mode 100644 index 0000000..b807dc4 --- /dev/null +++ b/packages/communication/src/messages/parser/index.ts @@ -0,0 +1,77 @@ +export * from './advertisement'; +export * from './availability'; +export * from './avatar'; +export * from './bots'; +export * from './callforhelp'; +export * from './camera'; +export * from './campaign'; +export * from './catalog'; +export * from './client'; +export * from './competition'; +export * from './crafting'; +export * from './desktop'; +export * from './friendlist'; +export * from './game'; +export * from './game/directory'; +export * from './game/lobby'; +export * from './game/score'; +export * from './generic'; +export * from './gifts'; +export * from './group'; +export * from './group/utils'; +export * from './groupforums'; +export * from './handshake'; +export * from './help'; +export * from './inventory'; +export * from './inventory/achievements'; +export * from './inventory/avatareffect'; +export * from './inventory/badges'; +export * from './inventory/clothing'; +export * from './inventory/furniture'; +export * from './inventory/pets'; +export * from './inventory/purse'; +export * from './inventory/trading'; +export * from './landingview'; +export * from './landingview/votes'; +export * from './marketplace'; +export * from './moderation'; +export * from './mysterybox'; +export * from './navigator'; +export * from './navigator/utils'; +export * from './notifications'; +export * from './nux'; +export * from './perk'; +export * from './perk/common'; +export * from './pet'; +export * from './poll'; +export * from './quest'; +export * from './recycler'; +export * from './room'; +export * from './room/access'; +export * from './room/access/doorbell'; +export * from './room/access/rights'; +export * from './room/bots'; +export * from './room/data'; +export * from './room/engine'; +export * from './room/furniture'; +export * from './room/furniture/floor'; +export * from './room/furniture/wall'; +export * from './room/furniture/youtube'; +export * from './room/mapping'; +export * from './room/pet'; +export * from './room/session'; +export * from './room/unit'; +export * from './room/unit/chat'; +export * from './roomevents'; +export * from './roomsettings'; +export * from './security'; +export * from './sound'; +export * from './talent'; +export * from './user'; +export * from './user/access'; +export * from './user/data'; +export * from './user/inventory'; +export * from './user/inventory/currency'; +export * from './user/inventory/subscription'; +export * from './user/wardrobe'; +export * from './userclassification'; diff --git a/packages/communication/src/messages/parser/inventory/achievements/AchievementData.ts b/packages/communication/src/messages/parser/inventory/achievements/AchievementData.ts new file mode 100644 index 0000000..653d3d7 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/achievements/AchievementData.ts @@ -0,0 +1,156 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class AchievementData +{ + public static DISPLAY_METHOD_OBSOLETE: number = -1; + public static DISPLAY_METHOD_SHOW_LEVEL_PROGRESS: number = 0; + public static DISPLAY_METHOD_NEVER_SHOW_PROGRESS: number = 1; + public static DISPLAY_METHOD_SHOW_TOTAL_PROGRESS: number = 2; + + private _achievementId: number; + private _level: number; + private _badgeId: string; + private _scoreAtStartOfLevel: number; + private _scoreLimit: number; + private _levelRewardPoints: number; + private _levelRewardPointType: number; + private _currentPoints: number; + private _finalLevel: boolean; + private _category: string; + private _subCategory: string; + private _levelCount: number; + private _displayMethod: 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._scoreAtStartOfLevel = wrapper.readInt(); + this._scoreLimit = Math.max(1, wrapper.readInt()); + this._levelRewardPoints = wrapper.readInt(); + this._levelRewardPointType = wrapper.readInt(); + this._currentPoints = wrapper.readInt(); + this._finalLevel = wrapper.readBoolean(); + this._category = wrapper.readString(); + this._subCategory = wrapper.readString(); + this._levelCount = wrapper.readInt(); + this._displayMethod = 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 scoreAtStartOfLevel(): number + { + return this._scoreAtStartOfLevel; + } + + public get scoreLimit(): number + { + return (this._scoreLimit - this._scoreAtStartOfLevel); + } + + public get levelRewardPoints(): number + { + return this._levelRewardPoints; + } + + public get levelRewardPointType(): number + { + return this._levelRewardPointType; + } + + public get currentPoints(): number + { + return (this._currentPoints - this._scoreAtStartOfLevel); + } + + public get finalLevel(): boolean + { + return this._finalLevel; + } + + public get category(): string + { + return this._category; + } + + public get subCategory(): string + { + return this._subCategory; + } + + public get levelCount(): number + { + return this._levelCount; + } + + public get firstLevelAchieved(): boolean + { + return (this._level > 1) || (this._finalLevel); + } + + public setMaxProgress(): void + { + this._currentPoints = this._scoreLimit; + } + + public get displayMethod(): number + { + return this._displayMethod; + } + + public get progress(): number + { + return this._currentPoints; + } + + public get toNextProgress(): number + { + return this._scoreLimit; + } + + public set unseen(unseen: number) + { + this._unseen = unseen; + } + + public get unseen(): number + { + return this._unseen; + } + + public reset(badge: AchievementData) + { + this._achievementId = badge._achievementId; + this._level = badge._level; + this._badgeId = badge._badgeId; + this._scoreAtStartOfLevel = badge._scoreAtStartOfLevel; + this._scoreLimit = badge._scoreLimit; + this._levelRewardPoints = badge._levelRewardPoints; + this._levelRewardPointType = badge._levelRewardPointType; + this._currentPoints = badge._currentPoints; + this._finalLevel = badge._finalLevel; + this._category = badge.category; + this._subCategory = badge._subCategory; + this._levelCount = badge._levelCount; + this._displayMethod = badge._displayMethod; + } +} diff --git a/packages/communication/src/messages/parser/inventory/achievements/AchievementParser.ts b/packages/communication/src/messages/parser/inventory/achievements/AchievementParser.ts new file mode 100644 index 0000000..4d04c80 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/achievements/AchievementParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AchievementData } from './AchievementData'; + +export class AchievementParser implements IMessageParser +{ + private _achievement: AchievementData; + + public flush(): boolean + { + this._achievement = null; + + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + if(!k) return false; + + this._achievement = new AchievementData(k); + + return true; + } + + public get achievement(): AchievementData + { + return this._achievement; + } +} diff --git a/packages/communication/src/messages/parser/inventory/achievements/AchievementResolutionData.ts b/packages/communication/src/messages/parser/inventory/achievements/AchievementResolutionData.ts new file mode 100644 index 0000000..449c825 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/achievements/AchievementResolutionData.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class AchievementResolutionData +{ + public static STATE_SELECTABLE: number = 0; + + private _achievementId: number; + private _level: number; + private _badgeId: string; + private _requiredLevel: number; + private _state: number; + + constructor(wrapper: IMessageDataWrapper) + { + this._achievementId = wrapper.readInt(); + this._level = wrapper.readInt(); + this._badgeId = wrapper.readString(); + this._requiredLevel = wrapper.readInt(); + this._state = wrapper.readInt(); + } + + public dispose(): void + { + this._achievementId = 0; + this._level = 0; + this._badgeId = ''; + this._requiredLevel = 0; + } + + public get achievementId(): number + { + return this._achievementId; + } + + public get level(): number + { + return this._level; + } + + public get badgeId(): string + { + return this._badgeId; + } + + public get requiredLevel(): number + { + return this._requiredLevel; + } + + public get enabled(): boolean + { + return (this._state === AchievementResolutionData.STATE_SELECTABLE); + } + + public get state(): number + { + return this._state; + } +} diff --git a/packages/communication/src/messages/parser/inventory/achievements/AchievementsParser.ts b/packages/communication/src/messages/parser/inventory/achievements/AchievementsParser.ts new file mode 100644 index 0000000..ecce86d --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/achievements/AchievementsParser.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AchievementData } from './AchievementData'; + +export class AchievementsParser implements IMessageParser +{ + private _achievements: AchievementData[]; + private _defaultCategory: string; + + public flush(): boolean + { + this._achievements = []; + this._defaultCategory = 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 AchievementData(k)); + + totalCount--; + } + + this._defaultCategory = k.readString(); + + return true; + } + + public get achievements(): AchievementData[] + { + return this._achievements; + } + + public get defaultCategory(): string + { + return this._defaultCategory; + } +} diff --git a/packages/communication/src/messages/parser/inventory/achievements/AchievementsScoreParser.ts b/packages/communication/src/messages/parser/inventory/achievements/AchievementsScoreParser.ts new file mode 100644 index 0000000..ad15939 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/achievements/AchievementsScoreParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/achievements/index.ts b/packages/communication/src/messages/parser/inventory/achievements/index.ts new file mode 100644 index 0000000..3b5ad93 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/achievements/index.ts @@ -0,0 +1,5 @@ +export * from './AchievementData'; +export * from './AchievementParser'; +export * from './AchievementResolutionData'; +export * from './AchievementsParser'; +export * from './AchievementsScoreParser'; diff --git a/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffect.ts b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffect.ts new file mode 100644 index 0000000..e4b8f21 --- /dev/null +++ b/packages/communication/src/messages/parser/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 subType(): number + { + return this._subType; + } + + public set subType(k: number) + { + this._subType = k; + } + + public get duration(): number + { + return this._duration; + } + + public set duration(k: number) + { + this._duration = k; + } + + public get inactiveEffectsInInventory(): number + { + return this._inactiveEffectsInInventory; + } + + public set inactiveEffectsInInventory(k: number) + { + this._inactiveEffectsInInventory = k; + } + + public get secondsLeftIfActive(): number + { + return this._secondsLeftIfActive; + } + + public set secondsLeftIfActive(k: number) + { + this._secondsLeftIfActive = k; + } + + public get isPermanent(): boolean + { + return this._permanent; + } + + public set isPermanent(k: boolean) + { + this._permanent = k; + } +} diff --git a/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectActivatedParser.ts b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectActivatedParser.ts new file mode 100644 index 0000000..7d8d5e8 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectActivatedParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectAddedParser.ts b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectAddedParser.ts new file mode 100644 index 0000000..ad9d6ea --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectAddedParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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 subType(): number + { + return this._subType; + } + + public get duration(): number + { + return this._duration; + } + + public get isPermanent(): boolean + { + return this._permanent; + } +} diff --git a/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectExpiredParser.ts b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectExpiredParser.ts new file mode 100644 index 0000000..36ed079 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectExpiredParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectSelectedParser.ts b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectSelectedParser.ts new file mode 100644 index 0000000..aa2af6a --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectSelectedParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectsParser.ts b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectsParser.ts new file mode 100644 index 0000000..9f0075d --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/avatareffect/AvatarEffectsParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AvatarEffect } from './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.subType = wrapper.readInt(); + effect.duration = wrapper.readInt(); + effect.inactiveEffectsInInventory = wrapper.readInt(); + effect.secondsLeftIfActive = wrapper.readInt(); + effect.isPermanent = wrapper.readBoolean(); + + this._effects.push(effect); + + totalEffects--; + } + + return true; + } + + public get effects(): AvatarEffect[] + { + return this._effects; + } +} diff --git a/packages/communication/src/messages/parser/inventory/avatareffect/index.ts b/packages/communication/src/messages/parser/inventory/avatareffect/index.ts new file mode 100644 index 0000000..ff677c4 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/avatareffect/index.ts @@ -0,0 +1,6 @@ +export * from './AvatarEffect'; +export * from './AvatarEffectActivatedParser'; +export * from './AvatarEffectAddedParser'; +export * from './AvatarEffectExpiredParser'; +export * from './AvatarEffectSelectedParser'; +export * from './AvatarEffectsParser'; diff --git a/packages/communication/src/messages/parser/inventory/badges/BadgeAndPointLimit.ts b/packages/communication/src/messages/parser/inventory/badges/BadgeAndPointLimit.ts new file mode 100644 index 0000000..e822350 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/badges/BadgeAndPointLimit.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class BadgeAndPointLimit +{ + 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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/badges/BadgePointLimitsParser.ts b/packages/communication/src/messages/parser/inventory/badges/BadgePointLimitsParser.ts new file mode 100644 index 0000000..f08837a --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/badges/BadgePointLimitsParser.ts @@ -0,0 +1,45 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { BadgeAndPointLimit } from './BadgeAndPointLimit'; + +export class BadgePointLimitsParser implements IMessageParser +{ + private _data: BadgeAndPointLimit[]; + + 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 BadgeAndPointLimit(_local_4, wrapper)); + + _local_6++; + } + + _local_2--; + } + + return true; + } + + public get data(): BadgeAndPointLimit[] + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/inventory/badges/BadgeReceivedParser.ts b/packages/communication/src/messages/parser/inventory/badges/BadgeReceivedParser.ts new file mode 100644 index 0000000..b4b6bcd --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/badges/BadgeReceivedParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class BadgeReceivedParser implements IMessageParser +{ + private _badgeId: number; + private _badgeCode: string; + + public flush(): boolean + { + this._badgeId = 0; + this._badgeCode = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._badgeId = wrapper.readInt(); + this._badgeCode = wrapper.readString(); + + return true; + } + + public get badgeId(): number + { + return this._badgeId; + } + + public get badgeCode(): string + { + return this._badgeCode; + } +} diff --git a/packages/communication/src/messages/parser/inventory/badges/BadgesParser.ts b/packages/communication/src/messages/parser/inventory/badges/BadgesParser.ts new file mode 100644 index 0000000..5d305ed --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/badges/BadgesParser.ts @@ -0,0 +1,69 @@ +import { IAdvancedMap, IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AdvancedMap } from '@nitrots/utils'; + +export class BadgesParser implements IMessageParser +{ + private _allBadgeCodes: string[]; + private _activeBadgeCodes: string[]; + private _badgeIds: IAdvancedMap; + + public flush(): boolean + { + this._allBadgeCodes = []; + this._activeBadgeCodes = null; + 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.push(badgeCode); + + count--; + } + + return true; + } + + public getBadgeId(code: string): number + { + return this._badgeIds.getValue(code); + } + public getAllBadgeCodes(): string[] + { + return this._allBadgeCodes; + } + + public getActiveBadgeCodes(): string[] + { + return this._activeBadgeCodes; + } +} diff --git a/packages/communication/src/messages/parser/inventory/badges/IsBadgeRequestFulfilledParser.ts b/packages/communication/src/messages/parser/inventory/badges/IsBadgeRequestFulfilledParser.ts new file mode 100644 index 0000000..2cae759 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/badges/IsBadgeRequestFulfilledParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class IsBadgeRequestFulfilledParser implements IMessageParser +{ + private _requestCode: string; + private _fulfilled: boolean; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._requestCode = wrapper.readString(); + this._fulfilled = wrapper.readBoolean(); + + return true; + } + + public get requestCode(): string + { + return this._requestCode; + } + + public get fulfilled(): boolean + { + return this._fulfilled; + } +} diff --git a/packages/communication/src/messages/parser/inventory/badges/index.ts b/packages/communication/src/messages/parser/inventory/badges/index.ts new file mode 100644 index 0000000..5ba1686 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/badges/index.ts @@ -0,0 +1,5 @@ +export * from './BadgeAndPointLimit'; +export * from './BadgePointLimitsParser'; +export * from './BadgeReceivedParser'; +export * from './BadgesParser'; +export * from './IsBadgeRequestFulfilledParser'; diff --git a/packages/communication/src/messages/parser/inventory/clothing/FigureSetIdsMessageParser.ts b/packages/communication/src/messages/parser/inventory/clothing/FigureSetIdsMessageParser.ts new file mode 100644 index 0000000..28a2db4 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/clothing/FigureSetIdsMessageParser.ts @@ -0,0 +1,50 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/clothing/_Str_8728.ts b/packages/communication/src/messages/parser/inventory/clothing/_Str_8728.ts new file mode 100644 index 0000000..e4ba1a2 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/clothing/_Str_8728.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/clothing/_Str_9021.ts b/packages/communication/src/messages/parser/inventory/clothing/_Str_9021.ts new file mode 100644 index 0000000..9a75a5f --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/clothing/_Str_9021.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/clothing/index.ts b/packages/communication/src/messages/parser/inventory/clothing/index.ts new file mode 100644 index 0000000..72484f0 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/clothing/index.ts @@ -0,0 +1,3 @@ +export * from './FigureSetIdsMessageParser'; +export * from './_Str_8728'; +export * from './_Str_9021'; diff --git a/packages/communication/src/messages/parser/inventory/furniture/FurnitureListAddOrUpdateParser.ts b/packages/communication/src/messages/parser/inventory/furniture/FurnitureListAddOrUpdateParser.ts new file mode 100644 index 0000000..0c1d8e5 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/furniture/FurnitureListAddOrUpdateParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { FurnitureListItemParser } from './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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/furniture/FurnitureListInvalidateParser.ts b/packages/communication/src/messages/parser/inventory/furniture/FurnitureListInvalidateParser.ts new file mode 100644 index 0000000..009ce2e --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/furniture/FurnitureListInvalidateParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FurnitureListInvalidateParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/inventory/furniture/FurnitureListItemParser.ts b/packages/communication/src/messages/parser/inventory/furniture/FurnitureListItemParser.ts new file mode 100644 index 0000000..cde8466 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/furniture/FurnitureListItemParser.ts @@ -0,0 +1,217 @@ +import { IMessageDataWrapper, IObjectData } from '@nitrots/api'; +import { FurnitureDataParser } from '../../room'; +import { IFurnitureItemData } from './IFurnitureItemData'; + +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 _extra: number; + private _flatId: number; + private _isWallItem: boolean; + private _hasRentPeriodStarted: boolean; + private _expirationTimeStamp: number; + private _slotId: string; + private _songId: 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._extra = 0; + this._flatId = 0; + this._isWallItem = false; + this._hasRentPeriodStarted = false; + this._expirationTimeStamp = 0; + this._slotId = ''; + this._songId = -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._expirationTimeStamp = 0; //GetTickerTime + + 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._extra = 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 songId(): number + { + return this._songId; + } + + public get extra(): number + { + return this._extra; + } + + public get rentable(): boolean + { + return this._rentable; + } + + public get isWallItem(): boolean + { + return this._isWallItem; + } + + public get hasRentPeriodStarted(): boolean + { + return this._hasRentPeriodStarted; + } + + public get expirationTimeStamp(): number + { + return this._expirationTimeStamp; + } + + public get creationDay(): number + { + return 0; + } + + public get creationMonth(): number + { + return 0; + } + + public get creationYear(): number + { + return 0; + } + + public get isExternalImageFurni(): boolean + { + return !(this._furniType.indexOf('external_image') === -1); + } +} diff --git a/packages/communication/src/messages/parser/inventory/furniture/FurnitureListParser.ts b/packages/communication/src/messages/parser/inventory/furniture/FurnitureListParser.ts new file mode 100644 index 0000000..13deca6 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/furniture/FurnitureListParser.ts @@ -0,0 +1,54 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { FurnitureListItemParser } from './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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/furniture/FurnitureListRemovedParser.ts b/packages/communication/src/messages/parser/inventory/furniture/FurnitureListRemovedParser.ts new file mode 100644 index 0000000..81838e1 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/furniture/FurnitureListRemovedParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/furniture/FurniturePostItPlacedParser.ts b/packages/communication/src/messages/parser/inventory/furniture/FurniturePostItPlacedParser.ts new file mode 100644 index 0000000..8a6c4eb --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/furniture/FurniturePostItPlacedParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/furniture/IFurnitureItemData.ts b/packages/communication/src/messages/parser/inventory/furniture/IFurnitureItemData.ts new file mode 100644 index 0000000..e2a9bdd --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/furniture/IFurnitureItemData.ts @@ -0,0 +1,28 @@ +import { IObjectData } from '@nitrots/api'; + +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; + songId: number; + extra: number; + rentable: boolean; + isWallItem: boolean; + hasRentPeriodStarted: boolean; + expirationTimeStamp: number; + creationDay: number; + creationMonth: number; + creationYear: number; + isExternalImageFurni: boolean; +} diff --git a/packages/communication/src/messages/parser/inventory/furniture/PresentOpenedMessageParser.ts b/packages/communication/src/messages/parser/inventory/furniture/PresentOpenedMessageParser.ts new file mode 100644 index 0000000..8fb114b --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/furniture/PresentOpenedMessageParser.ts @@ -0,0 +1,70 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PresentOpenedMessageParser implements IMessageParser +{ + private _itemType: string; + private _classId: number; + private _productCode: string; + private _placedItemId: number; + private _placedItemType: string; + private _placedInRoom: boolean; + private _petFigureString: string; + + public flush(): boolean + { + this._itemType = ''; + this._classId = 0; + this._productCode = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemType = wrapper.readString(); + this._classId = wrapper.readInt(); + this._productCode = wrapper.readString(); + this._placedItemId = wrapper.readInt(); + this._placedItemType = wrapper.readString(); + this._placedInRoom = wrapper.readBoolean(); + this._petFigureString = wrapper.readString(); + return true; + } + + public get itemType(): string + { + return this._itemType; + } + + public get classId(): number + { + return this._classId; + } + + public get productCode(): string + { + return this._productCode; + } + + public get placedItemId(): number + { + return this._placedItemId; + } + + public get placedItemType(): string + { + return this._placedItemType; + } + + public get placedInRoom(): boolean + { + return this._placedInRoom; + } + + public get petFigureString(): string + { + return this._petFigureString; + } +} diff --git a/packages/communication/src/messages/parser/inventory/furniture/index.ts b/packages/communication/src/messages/parser/inventory/furniture/index.ts new file mode 100644 index 0000000..a56120a --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/furniture/index.ts @@ -0,0 +1,8 @@ +export * from './FurnitureListAddOrUpdateParser'; +export * from './FurnitureListInvalidateParser'; +export * from './FurnitureListItemParser'; +export * from './FurnitureListParser'; +export * from './FurnitureListRemovedParser'; +export * from './FurniturePostItPlacedParser'; +export * from './IFurnitureItemData'; +export * from './PresentOpenedMessageParser'; diff --git a/packages/communication/src/messages/parser/inventory/index.ts b/packages/communication/src/messages/parser/inventory/index.ts new file mode 100644 index 0000000..01f6a81 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/index.ts @@ -0,0 +1,8 @@ +export * from './achievements'; +export * from './avatareffect'; +export * from './badges'; +export * from './clothing'; +export * from './furniture'; +export * from './pets'; +export * from './purse'; +export * from './trading'; diff --git a/packages/communication/src/messages/parser/inventory/pets/ConfirmBreedingRequestParser.ts b/packages/communication/src/messages/parser/inventory/pets/ConfirmBreedingRequestParser.ts new file mode 100644 index 0000000..38ed7c6 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/ConfirmBreedingRequestParser.ts @@ -0,0 +1,80 @@ +import { BreedingPetInfo, IMessageDataWrapper, IMessageParser, RarityCategoryData } from '@nitrots/api'; + +export class ConfirmBreedingRequestParser implements IMessageParser +{ + private _nestId: number; + private _pet1: BreedingPetInfo; + private _pet2: BreedingPetInfo; + private _rarityCategories: RarityCategoryData[]; + private _resultPetType: number; + + public flush(): boolean + { + this._nestId = 0; + + if(this._pet1) + { + this._pet1.dispose(); + this._pet1 = null; + } + + if(this._pet2) + { + this._pet2.dispose(); + this._pet2 = null; + } + + for(const k of this._rarityCategories) k && k.dispose(); + + this._rarityCategories = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._nestId = wrapper.readInt(); + this._pet1 = new BreedingPetInfo(wrapper); + this._pet2 = new BreedingPetInfo(wrapper); + + let totalCount = wrapper.readInt(); + + while(totalCount > 0) + { + this._rarityCategories.push(new RarityCategoryData(wrapper)); + + totalCount--; + } + + this._resultPetType = wrapper.readInt(); + + return true; + } + + public get nestId(): number + { + return this._nestId; + } + + public get pet1(): BreedingPetInfo + { + return this._pet1; + } + + public get pet2(): BreedingPetInfo + { + return this._pet2; + } + + public get rarityCategories(): RarityCategoryData[] + { + return this._rarityCategories; + } + + public get resultPetType(): number + { + return this._resultPetType; + } +} diff --git a/packages/communication/src/messages/parser/inventory/pets/ConfirmBreedingResultParser.ts b/packages/communication/src/messages/parser/inventory/pets/ConfirmBreedingResultParser.ts new file mode 100644 index 0000000..4ca1eb5 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/ConfirmBreedingResultParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ConfirmBreedingResultParser implements IMessageParser +{ + private _breedingNestStuffId: number; + private _result: number; + + public flush(): boolean + { + this._breedingNestStuffId = 0; + this._result = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._breedingNestStuffId = wrapper.readInt(); + this._result = wrapper.readInt(); + + return true; + } + + public get breedingNestStuffId(): number + { + return this._breedingNestStuffId; + } + + public get result(): number + { + return this._result; + } +} diff --git a/packages/communication/src/messages/parser/inventory/pets/GoToBreedingNestFailureParser.ts b/packages/communication/src/messages/parser/inventory/pets/GoToBreedingNestFailureParser.ts new file mode 100644 index 0000000..3520c34 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/GoToBreedingNestFailureParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GoToBreedingNestFailureParser implements IMessageParser +{ + public static PET_TOO_TIRED_TO_BREED: 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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/pets/NestBreedingSuccessParser.ts b/packages/communication/src/messages/parser/inventory/pets/NestBreedingSuccessParser.ts new file mode 100644 index 0000000..905de61 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/NestBreedingSuccessParser.ts @@ -0,0 +1,33 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class NestBreedingSuccessParser implements IMessageParser +{ + private _rarityCategory: number; + private _petId: number; + + public flush(): boolean + { + this._petId = -1; + this._rarityCategory = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._petId = wrapper.readInt(); + this._rarityCategory = wrapper.readInt(); + + return true; + } + + public get rarityCategory(): number + { + return this._rarityCategory; + } + + public get petId(): number + { + return this._petId; + } +} diff --git a/packages/communication/src/messages/parser/inventory/pets/PetAddedToInventoryParser.ts b/packages/communication/src/messages/parser/inventory/pets/PetAddedToInventoryParser.ts new file mode 100644 index 0000000..f3c4515 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/PetAddedToInventoryParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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/packages/communication/src/messages/parser/inventory/pets/PetBreedingMessageParser.ts b/packages/communication/src/messages/parser/inventory/pets/PetBreedingMessageParser.ts new file mode 100644 index 0000000..595c32a --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/PetBreedingMessageParser.ts @@ -0,0 +1,47 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PetBreedingMessageParser implements IMessageParser +{ + public static STATE_CANCEL: number = 1; + public static STATE_ACCEPT: number = 2; + public static STATE_REQUEST: number = 3; + + private _state: number; + private _ownPetId: number; + private _otherPetId: number; + + public flush(): boolean + { + this._state = 0; + this._ownPetId = 0; + this._otherPetId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._state = wrapper.readInt(); + this._ownPetId = wrapper.readInt(); + this._otherPetId = wrapper.readInt(); + + return true; + } + + public get state(): number + { + return this._state; + } + + public get ownPetId(): number + { + return this._ownPetId; + } + + public get otherPetId(): number + { + return this._otherPetId; + } +} diff --git a/packages/communication/src/messages/parser/inventory/pets/PetData.ts b/packages/communication/src/messages/parser/inventory/pets/PetData.ts new file mode 100644 index 0000000..0f0eda5 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/PetData.ts @@ -0,0 +1,70 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { PetFigureDataParser } from './PetFigureDataParser'; + +export class PetData +{ + private _id: number; + private _name: string; + private _figureData: PetFigureDataParser; + private _level: number; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._id = wrapper.readInt(); + this._name = wrapper.readString(); + this._figureData = new PetFigureDataParser(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 breedId(): number + { + return this._figureData.breedId; + } + + public get customPartCount(): number + { + return this._figureData.customPartCount; + } + + public get figureString(): string + { + return this._figureData.figuredata; + } + + public get figureData(): PetFigureDataParser + { + return this._figureData; + } + + public get level(): number + { + return this._level; + } +} diff --git a/packages/communication/src/messages/parser/inventory/pets/PetFigureDataParser.ts b/packages/communication/src/messages/parser/inventory/pets/PetFigureDataParser.ts new file mode 100644 index 0000000..509db73 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/PetFigureDataParser.ts @@ -0,0 +1,71 @@ +import { IMessageDataWrapper, IPetCustomPart, IPetFigureData, PetCustomPart } from '@nitrots/api'; + +export class PetFigureDataParser implements IPetFigureData +{ + private _typeId: number; + private _paletteId: number; + private _color: string; + private _breedId: number; + private _customPartCount: number; + private _customParts: IPetCustomPart[]; + + 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(new PetCustomPart(wrapper.readInt(), wrapper.readInt(), 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.layerId + ' ' + _local_2.partId + ' ' + _local_2.paletteId)); + + return figure; + } + + public get customParts(): IPetCustomPart[] + { + return this._customParts; + } + + public get customPartCount(): number + { + return this._customPartCount; + } +} diff --git a/packages/communication/src/messages/parser/inventory/pets/PetInventoryParser.ts b/packages/communication/src/messages/parser/inventory/pets/PetInventoryParser.ts new file mode 100644 index 0000000..dbdfb2f --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/PetInventoryParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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/packages/communication/src/messages/parser/inventory/pets/PetReceivedMessageParser.ts b/packages/communication/src/messages/parser/inventory/pets/PetReceivedMessageParser.ts new file mode 100644 index 0000000..5401be4 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/PetReceivedMessageParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PetData } from './PetData'; + +export class PetReceivedMessageParser implements IMessageParser +{ + private _boughtAsGift: boolean; + private _pet: PetData; + + public flush(): boolean + { + this._boughtAsGift = false; + this._pet = null; + + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + this._boughtAsGift = k.readBoolean(); + this._pet = new PetData(k); + + return true; + } + + public get boughtAsGift(): boolean + { + return this._boughtAsGift; + } + + public get pet(): PetData + { + return this._pet; + } +} diff --git a/packages/communication/src/messages/parser/inventory/pets/PetRemovedFromInventoryParser.ts b/packages/communication/src/messages/parser/inventory/pets/PetRemovedFromInventoryParser.ts new file mode 100644 index 0000000..21b1193 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/PetRemovedFromInventoryParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/inventory/pets/index.ts b/packages/communication/src/messages/parser/inventory/pets/index.ts new file mode 100644 index 0000000..a69532a --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/pets/index.ts @@ -0,0 +1,11 @@ +export * from './ConfirmBreedingRequestParser'; +export * from './ConfirmBreedingResultParser'; +export * from './GoToBreedingNestFailureParser'; +export * from './NestBreedingSuccessParser'; +export * from './PetAddedToInventoryParser'; +export * from './PetBreedingMessageParser'; +export * from './PetData'; +export * from './PetFigureDataParser'; +export * from './PetInventoryParser'; +export * from './PetReceivedMessageParser'; +export * from './PetRemovedFromInventoryParser'; diff --git a/packages/communication/src/messages/parser/inventory/purse/UserCreditsMessageParser.ts b/packages/communication/src/messages/parser/inventory/purse/UserCreditsMessageParser.ts new file mode 100644 index 0000000..bfb427f --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/purse/UserCreditsMessageParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/inventory/purse/index.ts b/packages/communication/src/messages/parser/inventory/purse/index.ts new file mode 100644 index 0000000..720991a --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/purse/index.ts @@ -0,0 +1 @@ +export * from './UserCreditsMessageParser'; diff --git a/packages/communication/src/messages/parser/inventory/trading/ItemDataStructure.ts b/packages/communication/src/messages/parser/inventory/trading/ItemDataStructure.ts new file mode 100644 index 0000000..11914d4 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/ItemDataStructure.ts @@ -0,0 +1,162 @@ +import { IMessageDataWrapper, IObjectData } from '@nitrots/api'; +import { GetTickerTime } from '@nitrots/utils'; +import { FurnitureDataParser } from '../../room'; +import { IFurnitureItemData } from '../furniture'; + +export class ItemDataStructure implements IFurnitureItemData +{ + private _expirationTimeStamp: number; + private _isWallItem: boolean; + private _itemId: number; + private _furniType: string; + private _ref: number; + private _spriteId: number; + private _category: number; + private _stuffData: IObjectData; + private _extra: number; + private _secondsToExpiration: number; + private _creationDay: number; + private _creationMonth: number; + private _creationYear: number; + private _isGroupable: boolean; + private _songId: 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._expirationTimeStamp = GetTickerTime(); + this._hasRentPeriodStarted = false; + this._creationDay = wrapper.readInt(); + this._creationMonth = wrapper.readInt(); + this._creationYear = wrapper.readInt(); + this._extra = ((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 extra(): number + { + return this._extra; + } + + public get secondsToExpiration(): number + { + return this._secondsToExpiration; + } + + public get creationDay(): number + { + return this._creationDay; + } + + public get creationMonth(): number + { + return this._creationMonth; + } + + public get creationYear(): number + { + return this._creationYear; + } + + public get isGroupable(): boolean + { + return this._isGroupable; + } + + public get songId(): number + { + return this._extra; + } + + 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 expirationTimeStamp(): number + { + return this._expirationTimeStamp; + } + + 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 isExternalImageFurni(): boolean + { + return (this._furniType.indexOf('external_image') !== -1); + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingAcceptParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingAcceptParser.ts new file mode 100644 index 0000000..8106aac --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingAcceptParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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 userID(): number + { + return this._userID; + } + + public get userAccepts(): boolean + { + return this._userAccepts; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingCloseParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingCloseParser.ts new file mode 100644 index 0000000..6dbbec2 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingCloseParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TradingCloseParser implements IMessageParser +{ + public static ERROR_WHILE_COMMIT: 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 userID(): number + { + return this._userId; + } + + public get reason(): number + { + return this._reason; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingCompletedParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingCompletedParser.ts new file mode 100644 index 0000000..895d3d4 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingCompletedParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TradingCompletedParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingConfirmationParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingConfirmationParser.ts new file mode 100644 index 0000000..1047452 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingConfirmationParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TradingConfirmationParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingListItemParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingListItemParser.ts new file mode 100644 index 0000000..f4f6fe3 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingListItemParser.ts @@ -0,0 +1,105 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { ItemDataStructure } from './ItemDataStructure'; + +export class TradingListItemParser implements IMessageParser +{ + private _firstUserID: number; + private _firstUserItemArray: ItemDataStructure[]; + private _firstUserNumItems: number; + private _firstUserNumCredits: number; + private _secondUserID: number; + private _secondUserItemArray: ItemDataStructure[]; + 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: ItemDataStructure[]): boolean + { + let count = k.readInt(); + + while(count > 0) + { + itemArray.push(new ItemDataStructure(k)); + + count--; + } + + return true; + } + + public get firstUserID(): number + { + return this._firstUserID; + } + + public get firstUserItemArray(): ItemDataStructure[] + { + return this._firstUserItemArray; + } + + public get firstUserNumItems(): number + { + return this._firstUserNumItems; + } + + public get firstUserNumCredits(): number + { + return this._firstUserNumCredits; + } + + public get secondUserID(): number + { + return this._secondUserID; + } + + public get secondUserItemArray(): ItemDataStructure[] + { + return this._secondUserItemArray; + } + + public get secondUserNumItems(): number + { + return this._secondUserNumItems; + } + + public get secondUserNumCredits(): number + { + return this._secondUserNumCredits; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingNoSuchItemParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingNoSuchItemParser.ts new file mode 100644 index 0000000..b767fd1 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingNoSuchItemParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TradingNoSuchItemParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingNotOpenParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingNotOpenParser.ts new file mode 100644 index 0000000..5818c27 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingNotOpenParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TradingNotOpenParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingOpenFailedParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingOpenFailedParser.ts new file mode 100644 index 0000000..7d1bd5a --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingOpenFailedParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TradingOpenFailedParser implements IMessageParser +{ + public static REASON_YOU_ARE_ALREADY_TRADING: number = 7; + public static REASON_OTHER_USER_ALREADY_TRADING: number = 8; + + private _reason: number; + private _otherUserName: string; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._reason = wrapper.readInt(); + this._otherUserName = wrapper.readString(); + + return true; + } + + public get reason(): number + { + return this._reason; + } + + public get otherUserName(): string + { + return this._otherUserName; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingOpenParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingOpenParser.ts new file mode 100644 index 0000000..f8b3c98 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingOpenParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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 userID(): number + { + return this._userId; + } + + public get userCanTrade(): boolean + { + return this._userCanTrade; + } + + public get otherUserID(): number + { + return this._otherUserId; + } + + public get otherUserCanTrade(): boolean + { + return this._otherUserCanTrade; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingOtherNotAllowedParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingOtherNotAllowedParser.ts new file mode 100644 index 0000000..7f4de33 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingOtherNotAllowedParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TradingOtherNotAllowedParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/TradingYouAreNotAllowedParser.ts b/packages/communication/src/messages/parser/inventory/trading/TradingYouAreNotAllowedParser.ts new file mode 100644 index 0000000..f5570fa --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/TradingYouAreNotAllowedParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TradingYouAreNotAllowedParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/inventory/trading/index.ts b/packages/communication/src/messages/parser/inventory/trading/index.ts new file mode 100644 index 0000000..cc51bb9 --- /dev/null +++ b/packages/communication/src/messages/parser/inventory/trading/index.ts @@ -0,0 +1,12 @@ +export * from './ItemDataStructure'; +export * from './TradingAcceptParser'; +export * from './TradingCloseParser'; +export * from './TradingCompletedParser'; +export * from './TradingConfirmationParser'; +export * from './TradingListItemParser'; +export * from './TradingNoSuchItemParser'; +export * from './TradingNotOpenParser'; +export * from './TradingOpenFailedParser'; +export * from './TradingOpenParser'; +export * from './TradingOtherNotAllowedParser'; +export * from './TradingYouAreNotAllowedParser'; diff --git a/packages/communication/src/messages/parser/landingview/PromoArticleData.ts b/packages/communication/src/messages/parser/landingview/PromoArticleData.ts new file mode 100644 index 0000000..f698071 --- /dev/null +++ b/packages/communication/src/messages/parser/landingview/PromoArticleData.ts @@ -0,0 +1,62 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class PromoArticleData +{ + public static readonly LINK_TYPE_URL = 0; + public static readonly LINK_TYPE_INTERNAL = 1; + public static readonly LINK_TYPE_NO_LINK = 2; + + private _id: number; + private _title: string; + private _bodyText: string; + private _buttonText: string; + private _linkType: number; + private _linkContent: string; + private _imageUrl: string; + + constructor(k: IMessageDataWrapper) + { + this._id = k.readInt(); + this._title = k.readString(); + this._bodyText = k.readString(); + this._buttonText = k.readString(); + this._linkType = k.readInt(); + this._linkContent = k.readString(); + this._imageUrl = k.readString(); + } + + public get id(): number + { + return this._id; + } + + public get title(): string + { + return this._title; + } + + public get bodyText(): string + { + return this._bodyText; + } + + public get buttonText(): string + { + return this._buttonText; + } + + public get linkType(): number + { + return this._linkType; + } + + public get linkContent(): string + { + return this._linkContent; + } + + public get imageUrl(): string + { + return this._imageUrl; + } +} diff --git a/packages/communication/src/messages/parser/landingview/PromoArticlesMessageParser.ts b/packages/communication/src/messages/parser/landingview/PromoArticlesMessageParser.ts new file mode 100644 index 0000000..42b78c6 --- /dev/null +++ b/packages/communication/src/messages/parser/landingview/PromoArticlesMessageParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PromoArticleData } from './PromoArticleData'; + +export class PromoArticlesMessageParser implements IMessageParser +{ + private _articles: PromoArticleData[]; + + public flush(): boolean + { + this._articles = []; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._articles.push(new PromoArticleData(wrapper)); + } + + return true; + } + + public get articles(): PromoArticleData[] + { + return this._articles; + } +} diff --git a/packages/communication/src/messages/parser/landingview/index.ts b/packages/communication/src/messages/parser/landingview/index.ts new file mode 100644 index 0000000..2d3eae4 --- /dev/null +++ b/packages/communication/src/messages/parser/landingview/index.ts @@ -0,0 +1,3 @@ +export * from './PromoArticleData'; +export * from './PromoArticlesMessageParser'; +export * from './votes'; diff --git a/packages/communication/src/messages/parser/landingview/votes/CommunityVoteReceivedParser.ts b/packages/communication/src/messages/parser/landingview/votes/CommunityVoteReceivedParser.ts new file mode 100644 index 0000000..1cc5a4a --- /dev/null +++ b/packages/communication/src/messages/parser/landingview/votes/CommunityVoteReceivedParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CommunityVoteReceivedParser implements IMessageParser +{ + private _acknowledged: boolean; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + this._acknowledged = wrapper.readBoolean(); + return true; + } + + public get acknowledged(): boolean + { + return this._acknowledged; + } +} diff --git a/packages/communication/src/messages/parser/landingview/votes/index.ts b/packages/communication/src/messages/parser/landingview/votes/index.ts new file mode 100644 index 0000000..4a0e00f --- /dev/null +++ b/packages/communication/src/messages/parser/landingview/votes/index.ts @@ -0,0 +1 @@ +export * from './CommunityVoteReceivedParser'; diff --git a/packages/communication/src/messages/parser/marketplace/MarketplaceBuyOfferResultParser.ts b/packages/communication/src/messages/parser/marketplace/MarketplaceBuyOfferResultParser.ts new file mode 100644 index 0000000..c45c58f --- /dev/null +++ b/packages/communication/src/messages/parser/marketplace/MarketplaceBuyOfferResultParser.ts @@ -0,0 +1,50 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class MarketplaceBuyOfferResultParser implements IMessageParser +{ + private _result: number; + private _newOfferId: number; + private _newPrice: number; + private _requestedOfferId: number; + + public flush(): boolean + { + this._newOfferId = -1; + this._newPrice = 0; + this._requestedOfferId = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._result = wrapper.readInt(); + this._newOfferId = wrapper.readInt(); + this._newPrice = wrapper.readInt(); + this._requestedOfferId = wrapper.readInt(); + + return true; + } + + public get result(): number + { + return this._result; + } + + public get offerId(): number + { + return this._newOfferId; + } + + public get newPrice(): number + { + return this._newPrice; + } + + public get requestedOfferId(): number + { + return this._requestedOfferId; + } +} diff --git a/packages/communication/src/messages/parser/marketplace/MarketplaceCanMakeOfferResultParser.ts b/packages/communication/src/messages/parser/marketplace/MarketplaceCanMakeOfferResultParser.ts new file mode 100644 index 0000000..233a357 --- /dev/null +++ b/packages/communication/src/messages/parser/marketplace/MarketplaceCanMakeOfferResultParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class MarketplaceCanMakeOfferResultParser implements IMessageParser +{ + private _tokenCount: number; + private _result: number; + + public flush(): boolean + { + this._tokenCount = 0; + this._result = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._result = wrapper.readInt(); + this._tokenCount = wrapper.readInt(); + + return true; + } + + public get tokenCount(): number + { + return this._tokenCount; + } + + public get resultCode(): number + { + return this._result; + } +} diff --git a/packages/communication/src/messages/parser/marketplace/MarketplaceCancelOfferResultParser.ts b/packages/communication/src/messages/parser/marketplace/MarketplaceCancelOfferResultParser.ts new file mode 100644 index 0000000..1583b2c --- /dev/null +++ b/packages/communication/src/messages/parser/marketplace/MarketplaceCancelOfferResultParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class MarketplaceCancelOfferResultParser implements IMessageParser +{ + private _offerId: number; + private _success: boolean; + + public flush(): boolean + { + this._offerId = 0; + this._success = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offerId = wrapper.readInt(); + this._success = wrapper.readBoolean(); + + return true; + } + + public get offerId(): number + { + return this._offerId; + } + + public get success(): boolean + { + return this._success; + } +} diff --git a/packages/communication/src/messages/parser/marketplace/MarketplaceConfigurationMessageParser.ts b/packages/communication/src/messages/parser/marketplace/MarketplaceConfigurationMessageParser.ts new file mode 100644 index 0000000..5185954 --- /dev/null +++ b/packages/communication/src/messages/parser/marketplace/MarketplaceConfigurationMessageParser.ts @@ -0,0 +1,83 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class MarketplaceConfigurationMessageParser implements IMessageParser +{ + private _enabled: boolean; + private _commission: number; + private _credits: number; + private _advertisements: number; + private _maximumPrice: number; + private _minimumPrice: number; + private _offerTime: number; + private _displayTime: number; + + public flush(): boolean + { + this._enabled = false; + this._commission = 0; + this._credits = 0; + this._advertisements = 0; + this._maximumPrice = 0; + this._minimumPrice = 0; + this._offerTime = 0; + this._displayTime = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._enabled = wrapper.readBoolean(); + this._commission = wrapper.readInt(); + this._credits = wrapper.readInt(); + this._advertisements = wrapper.readInt(); + this._minimumPrice = wrapper.readInt(); + this._maximumPrice = wrapper.readInt(); + this._offerTime = wrapper.readInt(); + this._displayTime = wrapper.readInt(); + + return true; + } + + public get enabled(): boolean + { + return this._enabled; + } + + public get commission(): number + { + return this._commission; + } + + public get credits(): number + { + return this._credits; + } + + public get advertisements(): number + { + return this._advertisements; + } + + public get minimumPrice(): number + { + return this._minimumPrice; + } + + public get maximumPrice(): number + { + return this._maximumPrice; + } + + public get offerTime(): number + { + return this._offerTime; + } + + public get displayTime(): number + { + return this._displayTime; + } +} diff --git a/packages/communication/src/messages/parser/marketplace/MarketplaceItemPostedParser.ts b/packages/communication/src/messages/parser/marketplace/MarketplaceItemPostedParser.ts new file mode 100644 index 0000000..dbcc81c --- /dev/null +++ b/packages/communication/src/messages/parser/marketplace/MarketplaceItemPostedParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class MarketplaceMakeOfferResultParser implements IMessageParser +{ + private _result: number; + + public flush(): boolean + { + this._result = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._result = wrapper.readInt(); + + return true; + } + + public get result(): number + { + return this._result; + } +} diff --git a/packages/communication/src/messages/parser/marketplace/MarketplaceItemStatsParser.ts b/packages/communication/src/messages/parser/marketplace/MarketplaceItemStatsParser.ts new file mode 100644 index 0000000..1f96880 --- /dev/null +++ b/packages/communication/src/messages/parser/marketplace/MarketplaceItemStatsParser.ts @@ -0,0 +1,92 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class MarketplaceItemStatsParser implements IMessageParser +{ + private _averagePrice: number; + private _currentOfferCount: number; + private _historyLength: number; + private _dayOffsets: number[]; + private _averagePrices: number[]; + private _soldAmounts: number[]; + private _furniTypeId: number; + private _furniCategoryId: number; + + public flush(): boolean + { + this._averagePrice = 0; + this._currentOfferCount = 0; + this._historyLength = 0; + this._dayOffsets = []; + this._averagePrices = []; + this._soldAmounts = []; + this._furniTypeId = 0; + this._furniCategoryId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._averagePrice = wrapper.readInt(); + this._currentOfferCount = wrapper.readInt(); + this._historyLength = wrapper.readInt(); + + let count = wrapper.readInt(); + + while(count > 0) + { + this._dayOffsets.push(wrapper.readInt()); + this._averagePrices.push(wrapper.readInt()); + this._soldAmounts.push(wrapper.readInt()); + + count--; + } + + this._furniCategoryId = wrapper.readInt(); + this._furniTypeId = wrapper.readInt(); + + return true; + } + + public get averagePrice(): number + { + return this._averagePrice; + } + + public get offerCount(): number + { + return this._currentOfferCount; + } + + public get historyLength(): number + { + return this._historyLength; + } + + public get dayOffsets(): number[] + { + return this._dayOffsets; + } + + public get averagePrices(): number[] + { + return this._averagePrices; + } + + public get soldAmounts(): number[] + { + return this._soldAmounts; + } + + public get furniTypeId(): number + { + return this._furniTypeId; + } + + public get furniCategoryId(): number + { + return this._furniCategoryId; + } +} diff --git a/packages/communication/src/messages/parser/marketplace/MarketplaceOffer.ts b/packages/communication/src/messages/parser/marketplace/MarketplaceOffer.ts new file mode 100644 index 0000000..fe2cd2a --- /dev/null +++ b/packages/communication/src/messages/parser/marketplace/MarketplaceOffer.ts @@ -0,0 +1,84 @@ +import { IObjectData } from '@nitrots/api'; + +export class MarketplaceOffer +{ + private readonly _offerId: number; + private readonly _furniId: number; + private readonly _furniType: number; + private readonly _extraData: string; + private readonly _stuffData: IObjectData; + private readonly _price: number; + private readonly _status: number; + private readonly _timeLeftMinutes: number = -1; + private readonly _averagePrice: number; + private readonly _offerCount: number; + + constructor(offerId: number, furniId: number, furniType: number, extraData: string, stuffData: IObjectData, price: number, status: number, timeLeftMinutes: number, averagePrice: number, offerCount: number = -1) + { + this._offerId = offerId; + this._furniId = furniId; + this._furniType = furniType; + this._extraData = extraData; + this._stuffData = stuffData; + this._price = price; + this._status = status; + this._timeLeftMinutes = timeLeftMinutes; + this._averagePrice = averagePrice; + this._offerCount = offerCount; + } + + public get offerId(): number + { + return this._offerId; + } + + public get furniId(): number + { + return this._furniId; + } + + public get furniType(): number + { + return this._furniType; + } + + public get extraData(): string + { + return this._extraData; + } + + public get stuffData(): IObjectData + { + return this._stuffData; + } + + public get price(): number + { + return this._price; + } + + public get status(): number + { + return this._status; + } + + public get timeLeftMinutes(): number + { + return this._timeLeftMinutes; + } + + public get averagePrice(): number + { + return this._averagePrice; + } + + public get offerCount(): number + { + return this._offerCount; + } + + public get isUniqueLimitedItem(): boolean + { + return (!(this.stuffData == null)) && (this.stuffData.uniqueSeries > 0); + } +} diff --git a/src/api/catalog/MarketplaceOfferData.ts b/packages/communication/src/messages/parser/marketplace/MarketplaceOfferData.ts similarity index 94% rename from src/api/catalog/MarketplaceOfferData.ts rename to packages/communication/src/messages/parser/marketplace/MarketplaceOfferData.ts index ba1fa88..3fb4b32 100644 --- a/src/api/catalog/MarketplaceOfferData.ts +++ b/packages/communication/src/messages/parser/marketplace/MarketplaceOfferData.ts @@ -1,9 +1,9 @@ -import { IObjectData } from '@nitrots/nitro-renderer'; +import { IObjectData } from '@nitrots/api'; export class MarketplaceOfferData { - public static readonly TYPE_FLOOR: number = 1; - public static readonly TYPE_WALL: number = 2; + public static TYPE_LANDSCAPE: number = 1; + public static TYPE_FLOOR: number = 2; private _offerId: number; private _furniId: number; diff --git a/packages/communication/src/messages/parser/marketplace/MarketplaceOffersParser.ts b/packages/communication/src/messages/parser/marketplace/MarketplaceOffersParser.ts new file mode 100644 index 0000000..4053b4a --- /dev/null +++ b/packages/communication/src/messages/parser/marketplace/MarketplaceOffersParser.ts @@ -0,0 +1,89 @@ +import { IMessageDataWrapper, IMessageParser, IObjectData, LegacyDataType, ObjectDataFactory } from '@nitrots/api'; +import { FurnitureDataParser } from '../room'; +import { MarketplaceOffer } from './MarketplaceOffer'; + +export class MarketplaceOffersParser implements IMessageParser +{ + private static FURNITYPE_STUFF: number = 1; + private static FURNITYPE_WALL: number = 2; + private static FAKE_FURNITYPE_UNIQUE: number = 3; + + private readonly MAX_LIST_LENGTH = 500; + + private _offers: MarketplaceOffer[]; + private _totalItemsFound: number; + + public flush(): boolean + { + this._offers = []; + this._totalItemsFound = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const count = wrapper.readInt(); + + let i = 0; + + while(i < count) + { + const offerId = wrapper.readInt(); + const status = wrapper.readInt(); + let furniType = wrapper.readInt(); + + let furniId = -1; + let extraData = ''; + let stuffData: IObjectData = null; + + if(furniType === MarketplaceOffersParser.FURNITYPE_STUFF) + { + furniId = wrapper.readInt(); + stuffData = FurnitureDataParser.parseObjectData(wrapper); + } + + else if(furniType === MarketplaceOffersParser.FURNITYPE_WALL) + { + furniId = wrapper.readInt(); + extraData = wrapper.readString(); + } + + else if(furniType == MarketplaceOffersParser.FAKE_FURNITYPE_UNIQUE) + { + furniId = wrapper.readInt(); + stuffData = ObjectDataFactory.getData(LegacyDataType.FORMAT_KEY); + stuffData.uniqueNumber = wrapper.readInt(); + stuffData.uniqueSeries = wrapper.readInt(); + furniType = MarketplaceOffersParser.FURNITYPE_STUFF; + } + + const price = wrapper.readInt(); + const timeLeftMinutes = wrapper.readInt(); + const averagePrice = wrapper.readInt(); + const offerCount = wrapper.readInt(); + + const offerItem = new MarketplaceOffer(offerId, furniId, furniType, extraData, stuffData, price, status, timeLeftMinutes, averagePrice, offerCount); + + if(i < this.MAX_LIST_LENGTH) this._offers.push(offerItem); + + i++; + } + + this._totalItemsFound = wrapper.readInt(); + + return true; + } + + public get offers(): MarketplaceOffer[] + { + return this._offers; + } + + public get totalItemsFound(): number + { + return this._totalItemsFound; + } +} diff --git a/packages/communication/src/messages/parser/marketplace/MarketplaceOwnOffersParser.ts b/packages/communication/src/messages/parser/marketplace/MarketplaceOwnOffersParser.ts new file mode 100644 index 0000000..d06d51b --- /dev/null +++ b/packages/communication/src/messages/parser/marketplace/MarketplaceOwnOffersParser.ts @@ -0,0 +1,88 @@ +import { IMessageDataWrapper, IMessageParser, IObjectData, LegacyDataType, ObjectDataFactory } from '@nitrots/api'; +import { MarketplaceOffer } from './MarketplaceOffer'; + +export class MarketplaceOwnOffersParser implements IMessageParser +{ + private static MAX_LIST_LENGTH = 500; + private _offers: MarketplaceOffer[]; + private _creditsWaiting: number; + + + public flush(): boolean + { + this._offers = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offers = []; + this._creditsWaiting = wrapper.readInt(); // SoldPriceTotal + + const offerCount = wrapper.readInt(); + for(let i = 0; i < offerCount; i++) + { + const offerId = wrapper.readInt(); + const status = wrapper.readInt(); + let furniType = wrapper.readInt(); + + let furniId; + let extraData; + let stuffData: IObjectData; + if(furniType == 1) + { + furniId = wrapper.readInt(); + stuffData = this.getStuffData(wrapper); + } + else + { + if(furniType == 2) + { + furniId = wrapper.readInt(); + extraData = wrapper.readString(); + } + else if(furniType == 3) + { + furniId = wrapper.readInt(); + stuffData = ObjectDataFactory.getData(LegacyDataType.FORMAT_KEY); + stuffData.uniqueNumber = wrapper.readInt(); + stuffData.uniqueSeries = wrapper.readInt(); + furniType = 1; + } + } + + const price = wrapper.readInt(); + const local9 = wrapper.readInt(); + const local10 = wrapper.readInt(); + const local13 = new MarketplaceOffer(offerId, furniId, furniType, extraData, stuffData, price, status, local9, local10); + + if(i < MarketplaceOwnOffersParser.MAX_LIST_LENGTH) + { + this._offers.push(local13); + } + } + + return true; + } + + public get offers(): MarketplaceOffer[] + { + return this._offers; + } + + public get creditsWaiting(): number + { + return this._creditsWaiting; + } + + private getStuffData(wrapper: IMessageDataWrapper): IObjectData + { + const local2 = wrapper.readInt(); + const local3 = ObjectDataFactory.getData(local2); + local3.parseWrapper(wrapper); + return local3; + } +} diff --git a/packages/communication/src/messages/parser/marketplace/index.ts b/packages/communication/src/messages/parser/marketplace/index.ts new file mode 100644 index 0000000..3b77f7e --- /dev/null +++ b/packages/communication/src/messages/parser/marketplace/index.ts @@ -0,0 +1,10 @@ +export * from './MarketplaceBuyOfferResultParser'; +export * from './MarketplaceCancelOfferResultParser'; +export * from './MarketplaceCanMakeOfferResultParser'; +export * from './MarketplaceConfigurationMessageParser'; +export * from './MarketplaceItemPostedParser'; +export * from './MarketplaceItemStatsParser'; +export * from './MarketplaceOffer'; +export * from './MarketplaceOfferData'; +export * from './MarketplaceOffersParser'; +export * from './MarketplaceOwnOffersParser'; diff --git a/packages/communication/src/messages/parser/moderation/CfhChatlogData.ts b/packages/communication/src/messages/parser/moderation/CfhChatlogData.ts new file mode 100644 index 0000000..5245393 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/CfhChatlogData.ts @@ -0,0 +1,45 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { ChatRecordData } from './ChatRecordData'; + +export class CfhChatlogData +{ + private _issueId: number; + private _callerUserId: number; + private _reportedUserId: number; + private _chatRecordId: number; + private _chatRecord: ChatRecordData; + + constructor(k: IMessageDataWrapper) + { + this._issueId = k.readInt(); + this._callerUserId = k.readInt(); + this._reportedUserId = k.readInt(); + this._chatRecordId = k.readInt(); + this._chatRecord = new ChatRecordData(k); + } + + public get issueId(): number + { + return this._issueId; + } + + public get callerUserId(): number + { + return this._callerUserId; + } + + public get reportedUserId(): number + { + return this._reportedUserId; + } + + public get chatRecordId(): number + { + return this._chatRecordId; + } + + public get chatRecord(): ChatRecordData + { + return this._chatRecord; + } +} diff --git a/packages/communication/src/messages/parser/moderation/CfhChatlogMessageParser.ts b/packages/communication/src/messages/parser/moderation/CfhChatlogMessageParser.ts new file mode 100644 index 0000000..7774166 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/CfhChatlogMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CfhChatlogData } from './CfhChatlogData'; + +export class CfhChatlogMessageParser implements IMessageParser +{ + private _data: CfhChatlogData; + + public flush(): boolean + { + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new CfhChatlogData(wrapper); + + return true; + } + + public get data(): CfhChatlogData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ChatRecordData.ts b/packages/communication/src/messages/parser/moderation/ChatRecordData.ts new file mode 100644 index 0000000..d49cbf8 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ChatRecordData.ts @@ -0,0 +1,110 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { ChatlineData } from './ChatlineData'; + +export class ChatRecordData +{ + public static readonly TYPE_SIMPLE = 0; + public static readonly TYPE_ROOM_CHAT = 1; + public static readonly TYPE_IM_SESSION = 2; + public static readonly TYPE_DISCUSSION_THREAD = 3; + public static readonly TYPE_DISCUSSION_MESSAGE = 4; + public static readonly TYPE_SELFIE = 5; + public static readonly TYPE_PHOTO = 6; + + private _recordType: number; + private _context: Map; + private _chatlog: ChatlineData[]; + + constructor(wrapper: IMessageDataWrapper) + { + this._context = new Map(); + this._chatlog = []; + + this._recordType = wrapper.readByte(); + const contextCount = wrapper.readShort(); + + for(let i = 0; i < contextCount; i++) + { + const key = wrapper.readString(); + const type = wrapper.readByte(); + + switch(type) + { + case 0: + this._context.set(key, wrapper.readBoolean()); + break; + case 1: + this._context.set(key, wrapper.readInt()); + break; + case 2: + this._context.set(key, wrapper.readString()); + break; + default: + throw new Error('Unknown data type ' + type); + } + } + + const chatCount = wrapper.readShort(); + + for(let i = 0; i < chatCount; i++) + { + const timestamp = wrapper.readString(); + const habboId = wrapper.readInt(); + const username = wrapper.readString(); + const message = wrapper.readString(); + const hasHighlighting = wrapper.readBoolean(); + + this._chatlog.push(new ChatlineData(timestamp, habboId, username, message, hasHighlighting)); + } + } + + public get recordType(): number + { + return this._recordType; + } + + public get context(): Map + { + return this._context; + } + + public get chatlog(): ChatlineData[] + { + return this._chatlog; + } + + public get roomId(): number + { + return this.getInt('roomId'); + } + + public get roomName(): string + { + return this._context.get('roomName') as string; + } + + public get groupId(): number + { + return this.getInt('groupId'); + } + + public get threadId(): number + { + return this.getInt('threadId'); + } + + public get messageId(): number + { + return this.getInt('messageId'); + } + + private getInt(k: string): number + { + const value = this._context.get(k); + if(!value) + { + return 0; + } + return value as number; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ChatlineData.ts b/packages/communication/src/messages/parser/moderation/ChatlineData.ts new file mode 100644 index 0000000..32432b7 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ChatlineData.ts @@ -0,0 +1,42 @@ +export class ChatlineData +{ + private readonly _timestamp: string; + private readonly _habboId: number; + private readonly _username: string; + private readonly _message: string; + private readonly _hasHighlighting: boolean; + + constructor(timestamp: string, habboId: number, username: string, message: string, hasHighlighting: boolean) + { + this._timestamp = timestamp; + this._habboId = habboId; + this._username = username; + this._message = message; + this._hasHighlighting = hasHighlighting; + } + + 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; + } + + public get hasHighlighting(): boolean + { + return this._hasHighlighting; + } +} diff --git a/packages/communication/src/messages/parser/moderation/INamed.ts b/packages/communication/src/messages/parser/moderation/INamed.ts new file mode 100644 index 0000000..3a74243 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/INamed.ts @@ -0,0 +1,4 @@ +export interface INamed +{ + name: string; +} diff --git a/packages/communication/src/messages/parser/moderation/IssueDeletedMessageParser.ts b/packages/communication/src/messages/parser/moderation/IssueDeletedMessageParser.ts new file mode 100644 index 0000000..4b7dd9c --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/IssueDeletedMessageParser.ts @@ -0,0 +1,22 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class IssueDeletedMessageParser implements IMessageParser +{ + private _issueId: number; + + public flush(): boolean + { + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + this._issueId = parseInt(k.readString()); + return true; + } + + public get issueId(): number + { + return this._issueId; + } +} diff --git a/packages/communication/src/messages/parser/moderation/IssueInfoMessageParser.ts b/packages/communication/src/messages/parser/moderation/IssueInfoMessageParser.ts new file mode 100644 index 0000000..cd0d18e --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/IssueInfoMessageParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { IssueMessageData } from './IssueMessageData'; +import { PatternMatchData } from './PatternMatchData'; + +export class IssueInfoMessageParser implements IMessageParser +{ + private _issueData: IssueMessageData; + + + public get issueData(): IssueMessageData + { + return this._issueData; + } + + public flush(): boolean + { + this._issueData = null; + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + const issueId: number = k.readInt(); + const state: number = k.readInt(); + const categoryId: number = k.readInt(); + const reportedCategoryId: number = k.readInt(); + const issueAgeInMs: number = k.readInt(); + const priority: number = k.readInt(); + const groupingId: number = k.readInt(); + const reporterUserId: number = k.readInt(); + const reporterUsername: string = k.readString(); + const reportedUserId: number = k.readInt(); + const reportedUsername: string = k.readString(); + const pickerUserId: number = k.readInt(); + const pickerUsername: string = k.readString(); + const message: string = k.readString(); + const chatRecordId: number = k.readInt(); + + const patternsCount: number = k.readInt(); + const patterns: PatternMatchData[] = []; + + for(let i = 0; i < patternsCount; i++) + { + patterns.push(new PatternMatchData(k)); + } + + this._issueData = new IssueMessageData(issueId, state, categoryId, reportedCategoryId, issueAgeInMs, + priority, groupingId, reporterUserId, reporterUsername, reportedUserId, reportedUsername, + pickerUserId, pickerUsername, message, chatRecordId, patterns); + return true; + } +} diff --git a/packages/communication/src/messages/parser/moderation/IssueMessageData.ts b/packages/communication/src/messages/parser/moderation/IssueMessageData.ts new file mode 100644 index 0000000..a0b945a --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/IssueMessageData.ts @@ -0,0 +1,162 @@ +import { PatternMatchData } from './PatternMatchData'; + +export class IssueMessageData +{ + public static STATE_OPEN: number = 1; + public static STATE_PICKED: number = 2; + public static STATE_CLOSED: number = 3; + + private _issueId: number; + private _state: number; + private _categoryId: number; + private _reportedCategoryId: number; + private _issueAgeInMilliseconds: number; + private _priority: number; + private _groupingId: number; + private _reporterUserId: number; + private _reporterUserName: string; + private _reportedUserId: number; + private _reportedUserName: string; + private _pickerUserId: number; + private _pickerUserName: string; + private _message: string; + private _chatRecordId: number; + private _patterns: PatternMatchData[]; + private _disposed: boolean = false; + private _creationTimeInMilliseconds: number; + + constructor(issueId: number, state: number, categoryId: number, reportedCategoryId: number, + issueAgeinMs: number, priority: number, groupingId: number, reporterUserId: number, reporterUsername: string, + reportedUserId: number, reportedUsername: string, pickerUserId: number, pickerUsername: string, message: string, + chatRecordId: number, patterns: PatternMatchData[]) + { + this._issueId = issueId; + this._state = state; + this._categoryId = categoryId; + this._reportedCategoryId = reportedCategoryId; + this._issueAgeInMilliseconds = issueAgeinMs; + this._priority = priority; + this._groupingId = groupingId; + this._reporterUserId = reporterUserId; + this._reporterUserName = reporterUsername; + this._reportedUserId = reportedUserId; + this._reportedUserName = reportedUsername; + this._pickerUserId = pickerUserId; + this._pickerUserName = pickerUsername; + this._message = message; + this._chatRecordId = chatRecordId; + this._patterns = patterns; + this._creationTimeInMilliseconds = 0; //0 + } + + public get issueId(): number + { + return this._issueId; + } + + public get state(): number + { + return this._state; + } + + public get categoryId(): number + { + return this._categoryId; + } + + public get reportedCategoryId(): number + { + return this._reportedCategoryId; + } + + public get issueAgeInMilliseconds(): number + { + return this._issueAgeInMilliseconds; + } + + public get priority(): number + { + return this._priority; + } + + public get groupingId(): number + { + return this._groupingId; + } + + public get reporterUserId(): number + { + return this._reporterUserId; + } + + public get reporterUserName(): string + { + return this._reporterUserName; + } + + public get reportedUserId(): number + { + return this._reportedUserId; + } + + public get reportedUserName(): string + { + return this._reportedUserName; + } + + public get pickerUserId(): number + { + return this._pickerUserId; + } + + public get pickerUserName(): string + { + return this._pickerUserName; + } + + public get message(): string + { + return this._message; + } + + public get chatRecordId(): number + { + return this._chatRecordId; + } + + public get patterns(): PatternMatchData[] + { + return this._patterns; + } + + public dispose(): void + { + + if(this.disposed) + { + return; + } + for(const k of this._patterns) + { + k.dispose(); + } + this._patterns = []; + this._disposed = true; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public getOpenTime(k: number): string + { + const _local_2: number = (((this._issueAgeInMilliseconds + k) - this._creationTimeInMilliseconds) / 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/packages/communication/src/messages/parser/moderation/IssuePickFailedMessageParser.ts b/packages/communication/src/messages/parser/moderation/IssuePickFailedMessageParser.ts new file mode 100644 index 0000000..3032ae3 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/IssuePickFailedMessageParser.ts @@ -0,0 +1,50 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { IssueMessageData } from './IssueMessageData'; + +export class IssuePickFailedMessageParser implements IMessageParser +{ + private _issues: IssueMessageData[]; + private _retryEnabled: boolean; + private _retryCount: number; + + public flush(): boolean + { + this._issues = null; + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + this._issues = []; + + const count = k.readInt(); + + for(let i = 0; i < count; i++) + { + const _local_4 = k.readInt(); + const _local_5 = k.readInt(); + const _local_6 = k.readString(); + const _local_7 = new IssueMessageData(_local_4, 0, 0, 0, 0, 0, 0, 0, null, 0, null, _local_5, _local_6, null, 0, []); + this._issues.push(_local_7); + } + + this._retryEnabled = k.readBoolean(); + this._retryCount = k.readInt(); + return true; + } + + public get issues(): IssueMessageData[] + { + return this._issues; + } + + public get retryEnabled(): boolean + { + return this._retryEnabled; + } + + public get retryCount(): number + { + return this._retryCount; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ModRoomData.ts b/packages/communication/src/messages/parser/moderation/ModRoomData.ts new file mode 100644 index 0000000..4d84501 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ModRoomData.ts @@ -0,0 +1,64 @@ +import { IDisposable, IMessageDataWrapper } from '@nitrots/api'; + +export class ModRoomData implements IDisposable +{ + private _exists: boolean; + private _name: string; + private _desc: string; + private _tags: string[]; + private _disposed: boolean; + + constructor(k: IMessageDataWrapper) + { + this._tags = []; + this._exists = k.readBoolean(); + if(!this.exists) + { + return; + } + this._name = k.readString(); + this._desc = k.readString(); + + const tagCount = k.readInt(); + + for(let i = 0; i < tagCount; i++) + { + this._tags.push(k.readString()); + } + } + + public get name(): string + { + return this._name; + } + + public get desc(): string + { + return this._desc; + } + + public get tags(): string[] + { + return this._tags; + } + + public get exists(): boolean + { + return this._exists; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public dispose(): void + { + if(this._disposed) + { + return; + } + this._disposed = true; + this._tags = null; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ModerationCautionParser.ts b/packages/communication/src/messages/parser/moderation/ModerationCautionParser.ts new file mode 100644 index 0000000..d2b965d --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ModerationCautionParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ModerationCautionParser implements IMessageParser +{ + private _message: string; + private _url: string; + + public flush(): boolean + { + this._message = ''; + this._url = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._message = wrapper.readString(); + this._url = wrapper.readString(); + + return true; + } + + public get message(): string + { + return this._message; + } + + public get url(): string + { + return this._url; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ModeratorActionResultMessageParser.ts b/packages/communication/src/messages/parser/moderation/ModeratorActionResultMessageParser.ts new file mode 100644 index 0000000..0bf8523 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ModeratorActionResultMessageParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ModeratorActionResultMessageParser implements IMessageParser +{ + private _userId: number; + private _success: boolean; + + public flush(): boolean + { + this._userId = -1; + this._success = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._userId = wrapper.readInt(); + this._success = wrapper.readBoolean(); + return true; + } + + public get userId(): number + { + return this._userId; + } + + public get success(): boolean + { + return this._success; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ModeratorInitData.ts b/packages/communication/src/messages/parser/moderation/ModeratorInitData.ts new file mode 100644 index 0000000..b78935f --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ModeratorInitData.ts @@ -0,0 +1,138 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { IssueInfoMessageParser } from './IssueInfoMessageParser'; +import { IssueMessageData } from './IssueMessageData'; + +export class ModeratorInitData +{ + private _messageTemplates: string[]; + private _roomMessageTemplates: string[]; + private _issues: IssueMessageData[]; + private _cfhPermission: boolean; + private _chatlogsPermission: boolean; + private _alertPermission: boolean; + private _kickPermission: boolean; + private _banPermission: boolean; + private _roomAlertPermission: boolean; + private _roomKickPermission: boolean; + + private _disposed: boolean = false; + + constructor(wrapper: IMessageDataWrapper) + { + const local2 = new IssueInfoMessageParser(); + this._issues = []; + this._messageTemplates = []; + this._roomMessageTemplates = []; + + let local3 = wrapper.readInt(); + let i = 0; + while(i < local3) + { + if(local2.parse(wrapper)) + { + this._issues.push(local2.issueData); + } + i++; + } + + local3 = wrapper.readInt(); + i = 0; + while(i < local3) + { + this._messageTemplates.push(wrapper.readString()); + i++; + } + + local3 = wrapper.readInt(); + i = 0; + while(i < local3) + { + wrapper.readString(); + i++; + } + + this._cfhPermission = wrapper.readBoolean(); + this._chatlogsPermission = wrapper.readBoolean(); + this._alertPermission = wrapper.readBoolean(); + this._kickPermission = wrapper.readBoolean(); + this._banPermission = wrapper.readBoolean(); + this._roomAlertPermission = wrapper.readBoolean(); + this._roomKickPermission = wrapper.readBoolean(); + local3 = wrapper.readInt(); + i = 0; + while(i < local3) + { + this._roomMessageTemplates.push(wrapper.readString()); + i++; + } + + + } + public dispose(): void + { + if(this._disposed) + { + return; + } + this._disposed = true; + this._messageTemplates = null; + this._roomMessageTemplates = null; + this._issues = null; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public get messageTemplates(): string[] + { + return this._messageTemplates; + } + + public get roomMessageTemplates(): string[] + { + return this._roomMessageTemplates; + } + + public get issues(): IssueMessageData[] + { + return this._issues; + } + + public get cfhPermission(): boolean + { + return this._cfhPermission; + } + + public get chatlogsPermission(): boolean + { + return this._chatlogsPermission; + } + + public get alertPermission(): boolean + { + return this._alertPermission; + } + + public get kickPermission(): boolean + { + return this._kickPermission; + } + + public get banPermission(): boolean + { + return this._banPermission; + } + + public get roomAlertPermission(): boolean + { + return this._roomAlertPermission; + } + + public get roomKickPermission(): boolean + { + return this._roomKickPermission; + } + +} diff --git a/packages/communication/src/messages/parser/moderation/ModeratorInitMessageParser.ts b/packages/communication/src/messages/parser/moderation/ModeratorInitMessageParser.ts new file mode 100644 index 0000000..74132cf --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ModeratorInitMessageParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { ModeratorInitData } from './ModeratorInitData'; + +export class ModeratorInitMessageParser implements IMessageParser +{ + private _data: ModeratorInitData = null; + public flush(): boolean + { + this._data = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._data = new ModeratorInitData(wrapper); + return true; + } + + public get data(): ModeratorInitData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ModeratorMessageParser.ts b/packages/communication/src/messages/parser/moderation/ModeratorMessageParser.ts new file mode 100644 index 0000000..ec9459f --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ModeratorMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ModeratorMessageParser implements IMessageParser +{ + private _message: string; + private _url: string; + + public flush(): boolean + { + this._message = ''; + this._url = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._message = wrapper.readString(); + this._url = wrapper.readString(); + + return true; + } + + public get message(): string + { + return this._message; + } + + public get url(): string + { + return this._url; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ModeratorRoomInfoMessageParser.ts b/packages/communication/src/messages/parser/moderation/ModeratorRoomInfoMessageParser.ts new file mode 100644 index 0000000..1f95990 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ModeratorRoomInfoMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { RoomModerationData } from './RoomModerationData'; + +export class ModeratorRoomInfoMessageParser implements IMessageParser +{ + private _data: RoomModerationData; + + public flush(): boolean + { + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new RoomModerationData(wrapper); + + return true; + } + + public get data(): RoomModerationData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ModeratorToolPreferencesMessageParser.ts b/packages/communication/src/messages/parser/moderation/ModeratorToolPreferencesMessageParser.ts new file mode 100644 index 0000000..a2d83a0 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ModeratorToolPreferencesMessageParser.ts @@ -0,0 +1,47 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ModeratorToolPreferencesMessageParser implements IMessageParser +{ + private _windowX: number; + private _windowY: number; + private _windowWidth: number; + private _windowHeight: number; + + public flush(): boolean + { + this._windowX = 0; + this._windowY = 0; + this._windowWidth = 0; + this._windowHeight = 0; + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + this._windowX = k.readInt(); + this._windowY = k.readInt(); + this._windowWidth = k.readInt(); + this._windowHeight = k.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; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ModeratorUserInfoData.ts b/packages/communication/src/messages/parser/moderation/ModeratorUserInfoData.ts new file mode 100644 index 0000000..011f14e --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ModeratorUserInfoData.ts @@ -0,0 +1,145 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class ModeratorUserInfoData +{ + private _userId: number; + private _userName: string; + private _registrationAgeInMinutes: number; + private _minutesSinceLastLogin: number; + private _online: boolean; + private _cfhCount: number; + private _abusiveCfhCount: number; + private _cautionCount: number; + private _banCount: number; + private _tradingLockCount: number; + private _tradingExpiryDate: string; + private _lastPurchaseDate: string; + private _identityId: number; + private _identityRelatedBanCount: number; + private _primaryEmailAddress: string; + private _figure: string; + private _userClassification: string; + private _lastSanctionTime: string = ''; + private _sanctionAgeHours: number = 0; + + constructor(wrapper: IMessageDataWrapper) + { + this._userId = wrapper.readInt(); + this._userName = wrapper.readString(); + this._figure = wrapper.readString(); + this._registrationAgeInMinutes = wrapper.readInt(); + this._minutesSinceLastLogin = wrapper.readInt(); + this._online = wrapper.readBoolean(); + this._cfhCount = wrapper.readInt(); + this._abusiveCfhCount = wrapper.readInt(); + this._cautionCount = wrapper.readInt(); + this._banCount = wrapper.readInt(); + this._tradingLockCount = wrapper.readInt(); + this._tradingExpiryDate = wrapper.readString(); + this._lastPurchaseDate = wrapper.readString(); + this._identityId = wrapper.readInt(); + this._identityRelatedBanCount = wrapper.readInt(); + this._primaryEmailAddress = wrapper.readString(); + this._userClassification = wrapper.readString(); + if(wrapper.bytesAvailable) + { + this._lastSanctionTime = wrapper.readString(); + this._sanctionAgeHours = 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 registrationAgeInMinutes(): number + { + return this._registrationAgeInMinutes; + } + + public get minutesSinceLastLogin(): number + { + return this._minutesSinceLastLogin; + } + + public get online(): boolean + { + return this._online; + } + + public get cfhCount(): number + { + return this._cfhCount; + } + + public get abusiveCfhCount(): number + { + return this._abusiveCfhCount; + } + + public get cautionCount(): number + { + return this._cautionCount; + } + + public get banCount(): number + { + return this._banCount; + } + + public get tradingLockCount(): number + { + return this._tradingLockCount; + } + + public get tradingExpiryDate(): string + { + return this._tradingExpiryDate; + } + + public get lastPurchaseDate(): string + { + return this._lastPurchaseDate; + } + + public get identityId(): number + { + return this._identityId; + } + + public get identityRelatedBanCount(): number + { + return this._identityRelatedBanCount; + } + + public get primaryEmailAddress(): string + { + return this._primaryEmailAddress; + } + + public get userClassification(): string + { + return this._userClassification; + } + + public get lastSanctionTime(): string + { + return this._lastSanctionTime; + } + + public get sanctionAgeHours(): number + { + return this._sanctionAgeHours; + } +} diff --git a/packages/communication/src/messages/parser/moderation/ModeratorUserInfoMessageParser.ts b/packages/communication/src/messages/parser/moderation/ModeratorUserInfoMessageParser.ts new file mode 100644 index 0000000..344e83f --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/ModeratorUserInfoMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { ModeratorUserInfoData } from './ModeratorUserInfoData'; + +export class ModeratorUserInfoMessageParser implements IMessageParser +{ + private _data: ModeratorUserInfoData; + + public flush(): boolean + { + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new ModeratorUserInfoData(wrapper); + + return true; + } + + public get data(): ModeratorUserInfoData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/moderation/PatternMatchData.ts b/packages/communication/src/messages/parser/moderation/PatternMatchData.ts new file mode 100644 index 0000000..88285d1 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/PatternMatchData.ts @@ -0,0 +1,44 @@ +import { IDisposable, IMessageDataWrapper } from '@nitrots/api'; + +export class PatternMatchData 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/packages/communication/src/messages/parser/moderation/RoomChatlogMessageParser.ts b/packages/communication/src/messages/parser/moderation/RoomChatlogMessageParser.ts new file mode 100644 index 0000000..91be2bb --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/RoomChatlogMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { ChatRecordData } from './ChatRecordData'; + +export class RoomChatlogMessageParser implements IMessageParser +{ + private _data: ChatRecordData; + + public flush(): boolean + { + this._data = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new ChatRecordData(wrapper); + + return true; + } + + public get data(): ChatRecordData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/moderation/RoomModerationData.ts b/packages/communication/src/messages/parser/moderation/RoomModerationData.ts new file mode 100644 index 0000000..ba5b065 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/RoomModerationData.ts @@ -0,0 +1,72 @@ +import { IDisposable, IMessageDataWrapper } from '@nitrots/api'; +import { ModRoomData } from './ModRoomData'; + +export class RoomModerationData implements IDisposable +{ + private _flatId: number; + private _userCount: number; + private _ownerInRoom: boolean; + private _ownerId: number; + private _ownerName: string; + private _room: ModRoomData; + private _disposed: boolean; + + constructor(k: IMessageDataWrapper) + { + this._flatId = k.readInt(); + this._userCount = k.readInt(); + this._ownerInRoom = k.readBoolean(); + this._ownerId = k.readInt(); + this._ownerName = k.readString(); + this._room = new ModRoomData(k); + } + + public get flatId(): number + { + return this._flatId; + } + + public get userCount(): number + { + return this._userCount; + } + + public get ownerInRoom(): boolean + { + return this._ownerInRoom; + } + + public get ownerId(): number + { + return this._ownerId; + } + + public get ownerName(): string + { + return this._ownerName; + } + + public get room(): ModRoomData + { + return this._room; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public dispose(): void + { + if(this._disposed) + { + return; + } + this._disposed = true; + if(this._room != null) + { + this._room.dispose(); + this._room = null; + } + } +} diff --git a/packages/communication/src/messages/parser/moderation/RoomVisitData.ts b/packages/communication/src/messages/parser/moderation/RoomVisitData.ts new file mode 100644 index 0000000..9db6c0d --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/RoomVisitData.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class RoomVisitData +{ + private _roomId: number; + private _roomName: string; + private _enterHour: number; + private _enterMinute: number; + + constructor(k: IMessageDataWrapper) + { + this._roomId = k.readInt(); + this._roomName = k.readString(); + this._enterHour = k.readInt(); + this._enterMinute = k.readInt(); + } + + public get roomId(): number + { + return this._roomId; + } + + public get roomName(): string + { + return this._roomName; + } + + public get enterHour(): number + { + return this._enterHour; + } + + public get enterMinute(): number + { + return this._enterMinute; + } +} diff --git a/packages/communication/src/messages/parser/moderation/RoomVisitsData.ts b/packages/communication/src/messages/parser/moderation/RoomVisitsData.ts new file mode 100644 index 0000000..13c80d7 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/RoomVisitsData.ts @@ -0,0 +1,38 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { RoomVisitData } from './RoomVisitData'; + +export class RoomVisitsData +{ + private _userId: number; + private _userName: string; + private _rooms: RoomVisitData[]; + + 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 RoomVisitData(k)); + _local_3++; + } + } + + public get userId(): number + { + return this._userId; + } + + public get userName(): string + { + return this._userName; + } + + public get rooms(): RoomVisitData[] + { + return this._rooms; + } +} diff --git a/packages/communication/src/messages/parser/moderation/RoomVisitsMessageParser.ts b/packages/communication/src/messages/parser/moderation/RoomVisitsMessageParser.ts new file mode 100644 index 0000000..9724f97 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/RoomVisitsMessageParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { RoomVisitsData } from './RoomVisitsData'; + +export class RoomVisitsMessageParser implements IMessageParser +{ + private _data: RoomVisitsData; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._data = new RoomVisitsData(wrapper); + return true; + } + + public get data(): RoomVisitsData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/moderation/UserBannedMessageParser.ts b/packages/communication/src/messages/parser/moderation/UserBannedMessageParser.ts new file mode 100644 index 0000000..16d5719 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/UserBannedMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class UserBannedMessageParser implements IMessageParser +{ + private _message: string; + + public flush(): boolean + { + this._message = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._message = wrapper.readString(); + + return true; + } + + public get message(): string + { + return this._message; + } +} diff --git a/packages/communication/src/messages/parser/moderation/UserChatlogData.ts b/packages/communication/src/messages/parser/moderation/UserChatlogData.ts new file mode 100644 index 0000000..29dfd1e --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/UserChatlogData.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { ChatRecordData } from './ChatRecordData'; + +export class UserChatlogData +{ + private _userId: number; + private _username: string; + private _roomChatlogs: ChatRecordData[] = []; + + constructor(wrapper: IMessageDataWrapper) + { + this._userId = wrapper.readInt(); + this._username = wrapper.readString(); + const size = wrapper.readInt(); + for(let i = 0; i < size; i++) + { + this._roomChatlogs.push(new ChatRecordData(wrapper)); + } + } + + public get userId(): number + { + return this._userId; + } + + public get username(): string + { + return this._username; + } + + public get roomChatlogs(): ChatRecordData[] + { + return this._roomChatlogs; + } +} diff --git a/packages/communication/src/messages/parser/moderation/UserChatlogMessageParser.ts b/packages/communication/src/messages/parser/moderation/UserChatlogMessageParser.ts new file mode 100644 index 0000000..9beac71 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/UserChatlogMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { UserChatlogData } from './UserChatlogData'; + +export class UserChatlogMessageParser implements IMessageParser +{ + private _data: UserChatlogData; + + public flush(): boolean + { + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new UserChatlogData(wrapper); + + return true; + } + + public get data(): UserChatlogData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/moderation/index.ts b/packages/communication/src/messages/parser/moderation/index.ts new file mode 100644 index 0000000..4d7d3a3 --- /dev/null +++ b/packages/communication/src/messages/parser/moderation/index.ts @@ -0,0 +1,28 @@ +export * from './CfhChatlogData'; +export * from './CfhChatlogMessageParser'; +export * from './ChatlineData'; +export * from './ChatRecordData'; +export * from './INamed'; +export * from './IssueDeletedMessageParser'; +export * from './IssueInfoMessageParser'; +export * from './IssueMessageData'; +export * from './IssuePickFailedMessageParser'; +export * from './ModerationCautionParser'; +export * from './ModeratorActionResultMessageParser'; +export * from './ModeratorInitData'; +export * from './ModeratorInitMessageParser'; +export * from './ModeratorMessageParser'; +export * from './ModeratorRoomInfoMessageParser'; +export * from './ModeratorToolPreferencesMessageParser'; +export * from './ModeratorUserInfoData'; +export * from './ModeratorUserInfoMessageParser'; +export * from './ModRoomData'; +export * from './PatternMatchData'; +export * from './RoomChatlogMessageParser'; +export * from './RoomModerationData'; +export * from './RoomVisitData'; +export * from './RoomVisitsData'; +export * from './RoomVisitsMessageParser'; +export * from './UserBannedMessageParser'; +export * from './UserChatlogData'; +export * from './UserChatlogMessageParser'; diff --git a/packages/communication/src/messages/parser/mysterybox/CancelMysteryBoxWaitMessageParser.ts b/packages/communication/src/messages/parser/mysterybox/CancelMysteryBoxWaitMessageParser.ts new file mode 100644 index 0000000..6f6b105 --- /dev/null +++ b/packages/communication/src/messages/parser/mysterybox/CancelMysteryBoxWaitMessageParser.ts @@ -0,0 +1,21 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CancelMysteryBoxWaitMessageParser implements IMessageParser +{ + + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + + + return true; + } + +} diff --git a/packages/communication/src/messages/parser/mysterybox/GotMysteryBoxPrizeMessageParser.ts b/packages/communication/src/messages/parser/mysterybox/GotMysteryBoxPrizeMessageParser.ts new file mode 100644 index 0000000..3268e5a --- /dev/null +++ b/packages/communication/src/messages/parser/mysterybox/GotMysteryBoxPrizeMessageParser.ts @@ -0,0 +1,33 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GotMysteryBoxPrizeMessageParser implements IMessageParser +{ + private _contentType:string; + private _classId:number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._contentType = wrapper.readString(); + this._classId = wrapper.readInt(); + + return true; + } + + public get contentType():string + { + return this._contentType; + } + + public get classId():number + { + return this._classId; + } + +} diff --git a/packages/communication/src/messages/parser/mysterybox/MysteryBoxKeysParser.ts b/packages/communication/src/messages/parser/mysterybox/MysteryBoxKeysParser.ts new file mode 100644 index 0000000..3934ff0 --- /dev/null +++ b/packages/communication/src/messages/parser/mysterybox/MysteryBoxKeysParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class MysteryBoxKeysParser implements IMessageParser +{ + private _boxColor: string; + private _keyColor: string; + + public flush(): boolean + { + this._boxColor = null; + this._keyColor = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._boxColor = wrapper.readString(); + this._keyColor = wrapper.readString(); + + return true; + } + + public get boxColor(): string + { + return this._boxColor; + } + + public get keyColor(): string + { + return this._keyColor; + } +} diff --git a/packages/communication/src/messages/parser/mysterybox/ShowMysteryBoxWaitMessageParser.ts b/packages/communication/src/messages/parser/mysterybox/ShowMysteryBoxWaitMessageParser.ts new file mode 100644 index 0000000..e847264 --- /dev/null +++ b/packages/communication/src/messages/parser/mysterybox/ShowMysteryBoxWaitMessageParser.ts @@ -0,0 +1,21 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ShowMysteryBoxWaitMessageParser implements IMessageParser +{ + + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + + + return true; + } + +} diff --git a/packages/communication/src/messages/parser/mysterybox/index.ts b/packages/communication/src/messages/parser/mysterybox/index.ts new file mode 100644 index 0000000..8a3c165 --- /dev/null +++ b/packages/communication/src/messages/parser/mysterybox/index.ts @@ -0,0 +1,4 @@ +export * from './CancelMysteryBoxWaitMessageParser'; +export * from './GotMysteryBoxPrizeMessageParser'; +export * from './MysteryBoxKeysParser'; +export * from './ShowMysteryBoxWaitMessageParser'; diff --git a/packages/communication/src/messages/parser/navigator/CanCreateRoomEventParser.ts b/packages/communication/src/messages/parser/navigator/CanCreateRoomEventParser.ts new file mode 100644 index 0000000..85b291e --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/CanCreateRoomEventParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CanCreateRoomEventParser implements IMessageParser +{ + private _canCreate: boolean; + private _errorCode: number; + + public flush(): boolean + { + this._canCreate = false; + this._errorCode = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._canCreate = wrapper.readBoolean(); + this._errorCode = wrapper.readInt(); + + return true; + } + + public get canCreate(): boolean + { + return this._canCreate; + } + + public get errorCode(): number + { + return this._errorCode; + } +} diff --git a/packages/communication/src/messages/parser/navigator/CanCreateRoomMessageParser.ts b/packages/communication/src/messages/parser/navigator/CanCreateRoomMessageParser.ts new file mode 100644 index 0000000..dfe39fa --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/CanCreateRoomMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CanCreateRoomMessageParser implements IMessageParser +{ + public static readonly CREATION_ALLOWED = 0; + public static readonly ROOM_LIMIT_REACHED = 1; + + private _resultCode: number; + private _roomLimit: number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._resultCode = wrapper.readInt(); + this._roomLimit = wrapper.readInt(); + + return true; + } + + public get resultCode(): number + { + return this._resultCode; + } + + public get roomLimit(): number + { + return this._roomLimit; + } +} diff --git a/packages/communication/src/messages/parser/navigator/CategoriesWithVisitorCountParser.ts b/packages/communication/src/messages/parser/navigator/CategoriesWithVisitorCountParser.ts new file mode 100644 index 0000000..3214f4e --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/CategoriesWithVisitorCountParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CategoriesWithVisitorCountData } from './utils'; + +export class CategoriesWithVisitorCountParser implements IMessageParser +{ + private _data: CategoriesWithVisitorCountData; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new CategoriesWithVisitorCountData(wrapper); + + return true; + } + + public get data(): CategoriesWithVisitorCountData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/navigator/CompetitionRoomsDataMessageParser.ts b/packages/communication/src/messages/parser/navigator/CompetitionRoomsDataMessageParser.ts new file mode 100644 index 0000000..f06fb32 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/CompetitionRoomsDataMessageParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CompetitionRoomsData } from './utils'; + +export class CompetitionRoomsDataMessageParser implements IMessageParser +{ + private _data: CompetitionRoomsData; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new CompetitionRoomsData(wrapper); + + return true; + } + + public get data(): CompetitionRoomsData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/navigator/ConvertedRoomIdMessageParser.ts b/packages/communication/src/messages/parser/navigator/ConvertedRoomIdMessageParser.ts new file mode 100644 index 0000000..0ef5825 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/ConvertedRoomIdMessageParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ConvertedRoomIdMessageParser implements IMessageParser +{ + private _globalId: string; + private _convertedId: number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._globalId = wrapper.readString(); + this._convertedId = wrapper.readInt(); + + return true; + } + + public get globalId(): string + { + return this._globalId; + } + + public get convertedId(): number + { + return this._convertedId; + } +} diff --git a/packages/communication/src/messages/parser/navigator/DoorbellMessageParser.ts b/packages/communication/src/messages/parser/navigator/DoorbellMessageParser.ts new file mode 100644 index 0000000..1ab4dbe --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/DoorbellMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class DoorbellMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/FavouriteChangedMessageParser.ts b/packages/communication/src/messages/parser/navigator/FavouriteChangedMessageParser.ts new file mode 100644 index 0000000..3495d4d --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/FavouriteChangedMessageParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FavouriteChangedMessageParser implements IMessageParser +{ + private _flatId: number; + private _added: boolean; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._flatId = wrapper.readInt(); + this._added = wrapper.readBoolean(); + + return true; + } + + public get flatId(): number + { + return this._flatId; + } + + public get added(): boolean + { + return this._added; + } +} diff --git a/packages/communication/src/messages/parser/navigator/FavouritesMessageParser.ts b/packages/communication/src/messages/parser/navigator/FavouritesMessageParser.ts new file mode 100644 index 0000000..f34b04c --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/FavouritesMessageParser.ts @@ -0,0 +1,39 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FavouritesMessageParser implements IMessageParser +{ + private _limit: number; + private _favouriteRoomIds: number[]; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._favouriteRoomIds = []; + this._limit = wrapper.readInt(); + + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._favouriteRoomIds.push(wrapper.readInt()); + } + + return true; + } + + public get limit(): number + { + return this._limit; + } + + public get favoriteRoomIds(): number[] + { + return this._favouriteRoomIds; + } +} diff --git a/packages/communication/src/messages/parser/navigator/FlatAccessDeniedMessageParser.ts b/packages/communication/src/messages/parser/navigator/FlatAccessDeniedMessageParser.ts new file mode 100644 index 0000000..52cb9f4 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/FlatAccessDeniedMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FlatAccessDeniedMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/FlatCreatedMessageParser.ts b/packages/communication/src/messages/parser/navigator/FlatCreatedMessageParser.ts new file mode 100644 index 0000000..e1d888f --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/FlatCreatedMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FlatCreatedMessageParser 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 false; + + this._roomId = wrapper.readInt(); + this._roomName = wrapper.readString(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get roomName(): string + { + return this._roomName; + } +} diff --git a/packages/communication/src/messages/parser/navigator/GetGuestRoomResultMessageParser.ts b/packages/communication/src/messages/parser/navigator/GetGuestRoomResultMessageParser.ts new file mode 100644 index 0000000..ebebe41 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/GetGuestRoomResultMessageParser.ts @@ -0,0 +1,79 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { RoomDataParser } from '../room'; +import { RoomChatSettings, RoomModerationSettings } from '../roomsettings'; + +export class GetGuestRoomResultMessageParser implements IMessageParser +{ + private _roomEnter: boolean; + private _roomForward: boolean; + private _data: RoomDataParser; + private _staffPick: boolean; + private _isGroupMember: boolean; + private _moderation: RoomModerationSettings; + private _chat: RoomChatSettings; + + public flush(): boolean + { + this._roomEnter = false; + this._roomForward = false; + this._data = null; + this._staffPick = false; + 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._staffPick = wrapper.readBoolean(); + this._isGroupMember = wrapper.readBoolean(); + this.data.allInRoomMuted = wrapper.readBoolean(); + this._moderation = new RoomModerationSettings(wrapper); + this.data.canMute = wrapper.readBoolean(); + this._chat = new RoomChatSettings(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 staffPick(): boolean + { + return this._staffPick; + } + + public get isGroupMember(): boolean + { + return this._isGroupMember; + } + + public get moderation(): RoomModerationSettings + { + return this._moderation; + } + + public get chat(): RoomChatSettings + { + return this._chat; + } +} diff --git a/packages/communication/src/messages/parser/navigator/GuestRoomSearchResultMessageParser.ts b/packages/communication/src/messages/parser/navigator/GuestRoomSearchResultMessageParser.ts new file mode 100644 index 0000000..3ed50a9 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/GuestRoomSearchResultMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { GuestRoomSearchResultData } from './utils'; + +export class GuestRoomSearchResultMessageParser implements IMessageParser +{ + _data: GuestRoomSearchResultData; + + public flush(): boolean + { + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new GuestRoomSearchResultData(wrapper); + + return true; + } + + public get data(): GuestRoomSearchResultData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorCategoryDataParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorCategoryDataParser.ts new file mode 100644 index 0000000..0c5506b --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorCategoryDataParser.ts @@ -0,0 +1,83 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorCollapsedParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorCollapsedParser.ts new file mode 100644 index 0000000..bccb78c --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorCollapsedParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorEventCategoryDataParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorEventCategoryDataParser.ts new file mode 100644 index 0000000..bde28ee --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorEventCategoryDataParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorHomeRoomParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorHomeRoomParser.ts new file mode 100644 index 0000000..e34f47c --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorHomeRoomParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorLiftedDataParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorLiftedDataParser.ts new file mode 100644 index 0000000..c370434 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorLiftedDataParser.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorLiftedParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorLiftedParser.ts new file mode 100644 index 0000000..f8071ac --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorLiftedParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorMetadataParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorMetadataParser.ts new file mode 100644 index 0000000..14fc619 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorMetadataParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { NavigatorTopLevelContext } from './utils'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorOpenRoomCreatorParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorOpenRoomCreatorParser.ts new file mode 100644 index 0000000..397fcef --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorOpenRoomCreatorParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class NavigatorOpenRoomCreatorParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorSearchParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorSearchParser.ts new file mode 100644 index 0000000..e437597 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorSearchParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { NavigatorSearchResultSet } from './utils'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorSearchesParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorSearchesParser.ts new file mode 100644 index 0000000..f63e673 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorSearchesParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { NavigatorSavedSearch } from './utils'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/NavigatorSettingsParser.ts b/packages/communication/src/messages/parser/navigator/NavigatorSettingsParser.ts new file mode 100644 index 0000000..3a32f12 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/NavigatorSettingsParser.ts @@ -0,0 +1,67 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/PopularRoomTagsData.ts b/packages/communication/src/messages/parser/navigator/PopularRoomTagsData.ts new file mode 100644 index 0000000..10471b0 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/PopularRoomTagsData.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { PopularTagData } from './PopularTagData'; + +export class PopularRoomTagsData +{ + private _tags: PopularTagData[]; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._tags = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._tags = []; + + const totalTags = wrapper.readInt(); + + let total = 0; + + while(total < totalTags) + { + this._tags.push(new PopularTagData(wrapper)); + total++; + } + + return true; + } + + public get tags(): PopularTagData[] + { + return this._tags; + } +} diff --git a/packages/communication/src/messages/parser/navigator/PopularRoomTagsResultMessageParser.ts b/packages/communication/src/messages/parser/navigator/PopularRoomTagsResultMessageParser.ts new file mode 100644 index 0000000..b7be4ba --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/PopularRoomTagsResultMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PopularRoomTagsData } from './PopularRoomTagsData'; + +export class PopularRoomTagsResultMessageParser implements IMessageParser +{ + private _data: PopularRoomTagsData; + + public flush(): boolean + { + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new PopularRoomTagsData(wrapper); + + return true; + } + + public get data(): PopularRoomTagsData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/navigator/PopularTagData.ts b/packages/communication/src/messages/parser/navigator/PopularTagData.ts new file mode 100644 index 0000000..34f898a --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/PopularTagData.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class PopularTagData +{ + private _tagName: string; + private _userCount: number; + + constructor(wrapper: IMessageDataWrapper) + { + this._tagName = wrapper.readString(); + this._userCount = wrapper.readInt(); + } + + public get tagName(): string + { + return this._tagName; + } + + public get userCount(): number + { + return this._userCount; + } +} diff --git a/packages/communication/src/messages/parser/navigator/RoomEventCancelMessageParser.ts b/packages/communication/src/messages/parser/navigator/RoomEventCancelMessageParser.ts new file mode 100644 index 0000000..768829e --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/RoomEventCancelMessageParser.ts @@ -0,0 +1,15 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomEventCancelMessageParser implements IMessageParser +{ + flush(): boolean + { + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + return true; + } + +} diff --git a/packages/communication/src/messages/parser/navigator/RoomEventMessageParser.ts b/packages/communication/src/messages/parser/navigator/RoomEventMessageParser.ts new file mode 100644 index 0000000..c77d0ac --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/RoomEventMessageParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { RoomEventData } from './utils'; + +export class RoomEventMessageParser implements IMessageParser +{ + private _data: RoomEventData; + + flush(): boolean + { + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._data = new RoomEventData(wrapper); + return true; + } + + public get data(): RoomEventData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/navigator/RoomFilterSettingsMessageParser.ts b/packages/communication/src/messages/parser/navigator/RoomFilterSettingsMessageParser.ts new file mode 100644 index 0000000..84f116d --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/RoomFilterSettingsMessageParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomFilterSettingsMessageParser implements IMessageParser +{ + private _words: string[]; + + public flush(): boolean + { + this._words = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalWords = wrapper.readInt(); + + while(totalWords > 0) + { + this._words.push(wrapper.readString()); + + totalWords--; + } + + return true; + } + + public get words(): string[] + { + return this._words; + } +} diff --git a/packages/communication/src/messages/parser/navigator/RoomSettingsUpdatedParser.ts b/packages/communication/src/messages/parser/navigator/RoomSettingsUpdatedParser.ts new file mode 100644 index 0000000..3163301 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/RoomSettingsUpdatedParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/RoomThumbnailUpdateResultMessageParser.ts b/packages/communication/src/messages/parser/navigator/RoomThumbnailUpdateResultMessageParser.ts new file mode 100644 index 0000000..0767844 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/RoomThumbnailUpdateResultMessageParser.ts @@ -0,0 +1,30 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomThumbnailUpdateResultMessageParser implements IMessageParser +{ + private _flatId: number; + private _resultCode: number; + + flush(): boolean + { + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._flatId = wrapper.readInt(); + this._resultCode = wrapper.readInt(); + return true; + } + + public get flatId(): number + { + return this._flatId; + } + + public get resultCode(): number + { + return this._resultCode; + } + +} diff --git a/packages/communication/src/messages/parser/navigator/UserEventCatsMessageParser.ts b/packages/communication/src/messages/parser/navigator/UserEventCatsMessageParser.ts new file mode 100644 index 0000000..97765ee --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/UserEventCatsMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { NavigatorEventCategoryDataParser } from './NavigatorEventCategoryDataParser'; + +export class UserEventCatsMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/UserFlatCatsMessageParser.ts b/packages/communication/src/messages/parser/navigator/UserFlatCatsMessageParser.ts new file mode 100644 index 0000000..fc1ab68 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/UserFlatCatsMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { NavigatorCategoryDataParser } from './NavigatorCategoryDataParser'; + +export class UserFlatCatsMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/index.ts b/packages/communication/src/messages/parser/navigator/index.ts new file mode 100644 index 0000000..e4b0bc8 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/index.ts @@ -0,0 +1,34 @@ +export * from './CanCreateRoomEventParser'; +export * from './CanCreateRoomMessageParser'; +export * from './CategoriesWithVisitorCountParser'; +export * from './CompetitionRoomsDataMessageParser'; +export * from './ConvertedRoomIdMessageParser'; +export * from './DoorbellMessageParser'; +export * from './FavouriteChangedMessageParser'; +export * from './FavouritesMessageParser'; +export * from './FlatAccessDeniedMessageParser'; +export * from './FlatCreatedMessageParser'; +export * from './GetGuestRoomResultMessageParser'; +export * from './GuestRoomSearchResultMessageParser'; +export * from './NavigatorCategoryDataParser'; +export * from './NavigatorCollapsedParser'; +export * from './NavigatorEventCategoryDataParser'; +export * from './NavigatorHomeRoomParser'; +export * from './NavigatorLiftedDataParser'; +export * from './NavigatorLiftedParser'; +export * from './NavigatorMetadataParser'; +export * from './NavigatorOpenRoomCreatorParser'; +export * from './NavigatorSearchesParser'; +export * from './NavigatorSearchParser'; +export * from './NavigatorSettingsParser'; +export * from './PopularRoomTagsData'; +export * from './PopularRoomTagsResultMessageParser'; +export * from './PopularTagData'; +export * from './RoomEventCancelMessageParser'; +export * from './RoomEventMessageParser'; +export * from './RoomFilterSettingsMessageParser'; +export * from './RoomSettingsUpdatedParser'; +export * from './RoomThumbnailUpdateResultMessageParser'; +export * from './UserEventCatsMessageParser'; +export * from './UserFlatCatsMessageParser'; +export * from './utils'; diff --git a/packages/communication/src/messages/parser/navigator/utils/CategoriesWithVisitorCountData.ts b/packages/communication/src/messages/parser/navigator/utils/CategoriesWithVisitorCountData.ts new file mode 100644 index 0000000..e32777b --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/utils/CategoriesWithVisitorCountData.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class CategoriesWithVisitorCountData +{ + private _categoryToCurrentUserCountMap: Map; + private _categoryToMaxUserCountMap: Map; + + constructor(k: IMessageDataWrapper) + { + this._categoryToCurrentUserCountMap = new Map(); + this._categoryToMaxUserCountMap = new Map(); + + const count = k.readInt(); + + for(let i = 0; i < count; i++) + { + const _local_4 = k.readInt(); + const _local_5 = k.readInt(); + const _local_6 = k.readInt(); + this._categoryToCurrentUserCountMap.set(_local_4, _local_5); + this._categoryToMaxUserCountMap.set(_local_4, _local_6); + } + } + + public get categoryToCurrentUserCountMap(): Map + { + return this._categoryToCurrentUserCountMap; + } + + public get categoryToMaxUserCountMap(): Map + { + return this._categoryToMaxUserCountMap; + } +} diff --git a/packages/communication/src/messages/parser/navigator/utils/CompetitionRoomsData.ts b/packages/communication/src/messages/parser/navigator/utils/CompetitionRoomsData.ts new file mode 100644 index 0000000..3780d4b --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/utils/CompetitionRoomsData.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class CompetitionRoomsData +{ + private _goalId: number; + private _pageIndex: number; + private _pageCount: number; + + constructor(k: IMessageDataWrapper, _arg_2: number = 0, _arg_3: number = 0) + { + this._goalId = _arg_2; + this._pageIndex = _arg_3; + + if(k) + { + this._goalId = k.readInt(); + this._pageIndex = k.readInt(); + this._pageCount = k.readInt(); + } + } + + public get goalId(): number + { + return this._goalId; + } + + public get pageIndex(): number + { + return this._pageIndex; + } + + public get pageCount(): number + { + return this._pageCount; + } +} diff --git a/packages/communication/src/messages/parser/navigator/utils/GuestRoomSearchResultData.ts b/packages/communication/src/messages/parser/navigator/utils/GuestRoomSearchResultData.ts new file mode 100644 index 0000000..87013ee --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/utils/GuestRoomSearchResultData.ts @@ -0,0 +1,76 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { RoomDataParser } from '../../room'; +import { OfficialRoomEntryData } from './OfficialRoomEntryData'; + +export class GuestRoomSearchResultData +{ + private _searchType: number; + private _searchParam: string; + private _rooms: RoomDataParser[]; + private _ad: OfficialRoomEntryData; + private _disposed: boolean; + + constructor(k: IMessageDataWrapper) + { + this._rooms = []; + this._searchType = k.readInt(); + this._searchParam = k.readString(); + const count = k.readInt(); + for(let i = 0; i < count; i++) + { + this._rooms.push(new RoomDataParser(k)); + } + const hasAdditional = k.readBoolean(); + if(hasAdditional) + { + this._ad = new OfficialRoomEntryData(k); + } + } + + public dispose(): void + { + if(this._disposed) + { + return; + } + this._disposed = true; + if(this._rooms != null) + { + for(const k of this._rooms) + { + k.flush(); + } + } + if(this._ad != null) + { + this._ad.dispose(); + this._ad = null; + } + this._rooms = null; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public get searchType(): number + { + return this._searchType; + } + + public get searchParam(): string + { + return this._searchParam; + } + + public get rooms(): RoomDataParser[] + { + return this._rooms; + } + + public get ad(): OfficialRoomEntryData + { + return this._ad; + } +} diff --git a/packages/communication/src/messages/parser/navigator/utils/NavigatorSavedSearch.ts b/packages/communication/src/messages/parser/navigator/utils/NavigatorSavedSearch.ts new file mode 100644 index 0000000..9ac1cbc --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/utils/NavigatorSavedSearch.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/utils/NavigatorSearchResultList.ts b/packages/communication/src/messages/parser/navigator/utils/NavigatorSearchResultList.ts new file mode 100644 index 0000000..b96c83d --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/utils/NavigatorSearchResultList.ts @@ -0,0 +1,84 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { RoomDataParser } from '../../room'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/utils/NavigatorSearchResultSet.ts b/packages/communication/src/messages/parser/navigator/utils/NavigatorSearchResultSet.ts new file mode 100644 index 0000000..301f723 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/utils/NavigatorSearchResultSet.ts @@ -0,0 +1,60 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/utils/NavigatorTopLevelContext.ts b/packages/communication/src/messages/parser/navigator/utils/NavigatorTopLevelContext.ts new file mode 100644 index 0000000..7c8b6ef --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/utils/NavigatorTopLevelContext.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/navigator/utils/OfficialRoomEntryData.ts b/packages/communication/src/messages/parser/navigator/utils/OfficialRoomEntryData.ts new file mode 100644 index 0000000..e96b601 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/utils/OfficialRoomEntryData.ts @@ -0,0 +1,148 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { RoomDataParser } from '../../room'; + +export class OfficialRoomEntryData +{ + public static readonly TYPE_TAG = 1; + public static readonly TYPE_GUEST_ROOM = 2; + public static readonly TYPE_FOLDER = 4; + + private _index: number; + private _popupCaption: string; + private _popupDesc: string; + private _showDetails: boolean; + private _picText: string; + private _picRef: string; + private _folderId: number; + private _userCount: number; + private _type: number; + private _tag: string; + private _guestRoomData: RoomDataParser; + private _open: boolean; + private _disposed: boolean; + + constructor(k: IMessageDataWrapper) + { + this._index = k.readInt(); + this._popupCaption = k.readString(); + this._popupDesc = k.readString(); + this._showDetails = k.readInt() == 1; + this._picText = k.readString(); + this._picRef = k.readString(); + this._folderId = k.readInt(); + this._userCount = k.readInt(); + this._type = k.readInt(); + if(this._type == OfficialRoomEntryData.TYPE_TAG) + { + this._tag = k.readString(); + } + else + { + if(this._type == OfficialRoomEntryData.TYPE_GUEST_ROOM) + { + this._guestRoomData = new RoomDataParser(k); + } + else + { + this._open = k.readBoolean(); + } + } + } + + public dispose(): void + { + if(this._disposed) + { + return; + } + this._disposed = true; + if(this._guestRoomData != null) + { + this._guestRoomData.flush(); + this._guestRoomData = null; + } + } + + public get disposed(): boolean + { + return this._disposed; + } + + public get type(): number + { + return this._type; + } + + public get index(): number + { + return this._index; + } + + public get popupCaption(): string + { + return this._popupCaption; + } + + public get popupDesc(): string + { + return this._popupDesc; + } + + public get showDetails(): boolean + { + return this._showDetails; + } + + public get picText(): string + { + return this._picText; + } + + public get picRef(): string + { + return this._picRef; + } + + public get folderId(): number + { + return this._folderId; + } + + public get tag(): string + { + return this._tag; + } + + public get userCount(): number + { + return this._userCount; + } + + public get guestRoomData(): RoomDataParser + { + return this._guestRoomData; + } + + public get open(): boolean + { + return this._open; + } + + public toggleOpen(): void + { + this._open = !this._open; + } + + public get maxUsers(): number + { + if(this.type == OfficialRoomEntryData.TYPE_TAG) + { + return 0; + } + if(this.type == OfficialRoomEntryData.TYPE_GUEST_ROOM) + { + return this._guestRoomData.maxUserCount; + } + return 0; + } +} diff --git a/packages/communication/src/messages/parser/navigator/utils/RoomEventData.ts b/packages/communication/src/messages/parser/navigator/utils/RoomEventData.ts new file mode 100644 index 0000000..2ae9ebd --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/utils/RoomEventData.ts @@ -0,0 +1,104 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class RoomEventData +{ + private _adId: number; + private _ownerAvatarId: number; + private _ownerAvatarName: string; + private _flatId: number; + private _categoryId: number; + private _eventType: number; + private _eventName: string; + private _eventDescription: string; + private _creationTime: string; + private _expirationDate: Date; + private _disposed: boolean; + + constructor(k: IMessageDataWrapper) + { + this._adId = k.readInt(); + this._ownerAvatarId = k.readInt(); + this._ownerAvatarName = k.readString(); + this._flatId = k.readInt(); + this._eventType = k.readInt(); + this._eventName = k.readString(); + this._eventDescription = k.readString(); + const _local_2 = k.readInt(); + const _local_3 = k.readInt(); + const _local_4: Date = new Date(); + let _local_5 = _local_4.getTime(); + const _local_6 = ((_local_2 * 60) * 1000); + _local_5 = (_local_5 - _local_6); + const _local_7: Date = new Date(_local_5); + this._creationTime = ((((((((_local_7.getDate() + '-') + _local_7.getMonth()) + '-') + _local_7.getFullYear()) + ' ') + _local_7.getHours()) + ':') + _local_7.getMinutes()); + let _local_8 = _local_4.getTime(); + const _local_9 = ((_local_3 * 60) * 1000); + _local_8 = (_local_8 + _local_9); + this._expirationDate = new Date(_local_8); + this._categoryId = k.readInt(); + } + + public dispose(): void + { + if(this._disposed) + { + return; + } + this._disposed = true; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public get adId(): number + { + return this._adId; + } + + public get ownerAvatarId(): number + { + return this._ownerAvatarId; + } + + public get ownerAvatarName(): string + { + return this._ownerAvatarName; + } + + public get flatId(): number + { + return this._flatId; + } + + public get categoryId(): number + { + return this._categoryId; + } + + public get eventType(): number + { + return this._eventType; + } + + public get eventName(): string + { + return this._eventName; + } + + public get eventDescription(): string + { + return this._eventDescription; + } + + public get creationTime(): string + { + return this._creationTime; + } + + public get expirationDate(): Date + { + return this._expirationDate; + } +} diff --git a/packages/communication/src/messages/parser/navigator/utils/index.ts b/packages/communication/src/messages/parser/navigator/utils/index.ts new file mode 100644 index 0000000..7b9f182 --- /dev/null +++ b/packages/communication/src/messages/parser/navigator/utils/index.ts @@ -0,0 +1,9 @@ +export * from './CategoriesWithVisitorCountData'; +export * from './CompetitionRoomsData'; +export * from './GuestRoomSearchResultData'; +export * from './NavigatorSavedSearch'; +export * from './NavigatorSearchResultList'; +export * from './NavigatorSearchResultSet'; +export * from './NavigatorTopLevelContext'; +export * from './OfficialRoomEntryData'; +export * from './RoomEventData'; diff --git a/packages/communication/src/messages/parser/notifications/AchievementLevelUpData.ts b/packages/communication/src/messages/parser/notifications/AchievementLevelUpData.ts new file mode 100644 index 0000000..a22c736 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/AchievementLevelUpData.ts @@ -0,0 +1,93 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class AchievementLevelUpData +{ + private _type: number; + private _level: number; + private _points: number; + private _levelRewardPoints: number; + private _levelRewardPointType: number; + private _bonusPoints: number; + private _badgeId: number; + private _badgeCode: string = ''; + private _removedBadgeCode: string = ''; + private _achievementID: number; + private _category: string; + private _showDialogToUser: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + this._type = wrapper.readInt(); + this._level = wrapper.readInt(); + this._badgeId = wrapper.readInt(); + this._badgeCode = wrapper.readString(); + this._points = wrapper.readInt(); + this._levelRewardPoints = wrapper.readInt(); + this._levelRewardPointType = wrapper.readInt(); + this._bonusPoints = wrapper.readInt(); + this._achievementID = wrapper.readInt(); + this._removedBadgeCode = wrapper.readString(); + this._category = wrapper.readString(); + this._showDialogToUser = wrapper.readBoolean(); + } + + public get type(): number + { + return this._type; + } + + public get level(): number + { + return this._level; + } + + public get points(): number + { + return this._points; + } + + public get levelRewardPoints(): number + { + return this._levelRewardPoints; + } + + public get levelRewardPointType(): number + { + return this._levelRewardPointType; + } + + public get bonusPoints(): number + { + return this._bonusPoints; + } + + public get badgeId(): number + { + return this._badgeId; + } + + public get badgeCode(): string + { + return this._badgeCode; + } + + public get removedBadgeCode(): string + { + return this._removedBadgeCode; + } + + public get achievementID(): number + { + return this._achievementID; + } + + public get category(): string + { + return this._category; + } + + public get showDialogToUser(): boolean + { + return this._showDialogToUser; + } +} diff --git a/packages/communication/src/messages/parser/notifications/AchievementNotificationMessageParser.ts b/packages/communication/src/messages/parser/notifications/AchievementNotificationMessageParser.ts new file mode 100644 index 0000000..2ece3e6 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/AchievementNotificationMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AchievementLevelUpData } from './AchievementLevelUpData'; + +export class AchievementNotificationMessageParser implements IMessageParser +{ + private _data: AchievementLevelUpData; + + public flush(): boolean + { + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new AchievementLevelUpData(wrapper); + + return true; + } + + public get data(): AchievementLevelUpData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/notifications/ActivityPointNotificationParser.ts b/packages/communication/src/messages/parser/notifications/ActivityPointNotificationParser.ts new file mode 100644 index 0000000..d2d777d --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/ActivityPointNotificationParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ActivityPointNotificationParser 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; + } +} diff --git a/packages/communication/src/messages/parser/notifications/BotErrorEventParser.ts b/packages/communication/src/messages/parser/notifications/BotErrorEventParser.ts new file mode 100644 index 0000000..c22f9f4 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/BotErrorEventParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/notifications/ClubGiftNotificationParser.ts b/packages/communication/src/messages/parser/notifications/ClubGiftNotificationParser.ts new file mode 100644 index 0000000..a027612 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/ClubGiftNotificationParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ClubGiftNotificationParser implements IMessageParser +{ + private _numGifts: number; + + public flush(): boolean + { + this._numGifts = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._numGifts = wrapper.readInt(); + + return true; + } + + public get numGifts(): number + { + return this._numGifts; + } +} diff --git a/packages/communication/src/messages/parser/notifications/ConnectionErrorMessageParser.ts b/packages/communication/src/messages/parser/notifications/ConnectionErrorMessageParser.ts new file mode 100644 index 0000000..8075593 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/ConnectionErrorMessageParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ConnectionErrorMessageParser implements IMessageParser +{ + private _errorCode: number; + private _messageId: number; + private _timestamp: string; + + public flush(): boolean + { + this._errorCode = 0; + this._messageId = 0; + this._timestamp = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._messageId = wrapper.readInt(); + this._errorCode = wrapper.readInt(); + this._timestamp = wrapper.readString(); + + return true; + } + + public get errorCode(): number + { + return this._errorCode; + } + + public get messageId(): number + { + return this._messageId; + } + + public get timestamp(): string + { + return this._timestamp; + } +} diff --git a/packages/communication/src/messages/parser/notifications/ElementPointerMessageParser.ts b/packages/communication/src/messages/parser/notifications/ElementPointerMessageParser.ts new file mode 100644 index 0000000..e2c97d4 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/ElementPointerMessageParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ElementPointerMessageParser implements IMessageParser +{ + private _key: string; + + public flush(): boolean + { + this._key = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._key = wrapper.readString(); + + return true; + } + + public get key(): string + { + return this._key; + } +} diff --git a/packages/communication/src/messages/parser/notifications/HabboBroadcastMessageParser.ts b/packages/communication/src/messages/parser/notifications/HabboBroadcastMessageParser.ts new file mode 100644 index 0000000..6246122 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/HabboBroadcastMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/notifications/HotelWillShutdownParser.ts b/packages/communication/src/messages/parser/notifications/HotelWillShutdownParser.ts new file mode 100644 index 0000000..03a40c2 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/HotelWillShutdownParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/notifications/InfoFeedEnableMessageParser.ts b/packages/communication/src/messages/parser/notifications/InfoFeedEnableMessageParser.ts new file mode 100644 index 0000000..47c6ef0 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/InfoFeedEnableMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class InfoFeedEnableMessageParser implements IMessageParser +{ + private _enabled: boolean; + + public flush(): boolean + { + this._enabled = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._enabled = wrapper.readBoolean(); + + return true; + } + + public get enabled(): boolean + { + return this._enabled; + } +} diff --git a/packages/communication/src/messages/parser/notifications/MOTDNotificationParser.ts b/packages/communication/src/messages/parser/notifications/MOTDNotificationParser.ts new file mode 100644 index 0000000..855dc9e --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/MOTDNotificationParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/notifications/NotificationDialogMessageParser.ts b/packages/communication/src/messages/parser/notifications/NotificationDialogMessageParser.ts new file mode 100644 index 0000000..81009a4 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/NotificationDialogMessageParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/notifications/OfferRewardDeliveredMessageParser.ts b/packages/communication/src/messages/parser/notifications/OfferRewardDeliveredMessageParser.ts new file mode 100644 index 0000000..81b9512 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/OfferRewardDeliveredMessageParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class OfferRewardDeliveredMessageParser implements IMessageParser +{ + private _contentType: string; + private _classId: number; + private _name: string; + private _description: string; + + public flush(): boolean + { + this._contentType = null; + this._classId = 0; + this._name = null; + this._description = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._contentType = wrapper.readString(); + this._classId = wrapper.readInt(); + this._name = wrapper.readString(); + this._description = wrapper.readString(); + + return true; + } + + public get contentType(): string + { + return this._contentType; + } + + public get classId(): number + { + return this._classId; + } + + public get name(): string + { + return this._name; + } + + public get description(): string + { + return this._description; + } +} diff --git a/packages/communication/src/messages/parser/notifications/PetLevelNotificationParser.ts b/packages/communication/src/messages/parser/notifications/PetLevelNotificationParser.ts new file mode 100644 index 0000000..280771b --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/PetLevelNotificationParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PetFigureDataParser } from '../inventory'; + +export class PetLevelNotificationParser implements IMessageParser +{ + private _petId: number; + private _petName: string; + private _level: number; + private _figureData: PetFigureDataParser; + + public flush(): boolean + { + this._petId = -1; + this._petName = null; + this._level = 0; + this._figureData = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._petId = wrapper.readInt(); + this._petName = wrapper.readString(); + this._level = wrapper.readInt(); + this._figureData = new PetFigureDataParser(wrapper); + + return true; + } + + public get petId(): number + { + return this._petId; + } + + public get petName(): string + { + return this._petName; + } + + public get level(): number + { + return this._level; + } + + public get figureData(): PetFigureDataParser + { + return this._figureData; + } +} diff --git a/packages/communication/src/messages/parser/notifications/PetPlacingErrorEventParser.ts b/packages/communication/src/messages/parser/notifications/PetPlacingErrorEventParser.ts new file mode 100644 index 0000000..66ee55a --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/PetPlacingErrorEventParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/notifications/RestoreClientMessageParser.ts b/packages/communication/src/messages/parser/notifications/RestoreClientMessageParser.ts new file mode 100644 index 0000000..7f9e5be --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/RestoreClientMessageParser.ts @@ -0,0 +1,14 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RestoreClientMessageParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + return true; + } +} diff --git a/packages/communication/src/messages/parser/notifications/SimpleAlertMessageParser.ts b/packages/communication/src/messages/parser/notifications/SimpleAlertMessageParser.ts new file mode 100644 index 0000000..8781898 --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/SimpleAlertMessageParser.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class SimpleAlertMessageParser implements IMessageParser +{ + private _alertMessage: string; + private _titleMessage: string; + + public flush(): boolean + { + this._alertMessage = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._alertMessage = wrapper.readString(); + + if(wrapper.bytesAvailable) + { + this._titleMessage = wrapper.readString(); + } + + return true; + } + + public get alertMessage(): string + { + return this._alertMessage; + } + + public get titleMessage(): string + { + return this._titleMessage; + } +} diff --git a/packages/communication/src/messages/parser/notifications/UnseenItemsParser.ts b/packages/communication/src/messages/parser/notifications/UnseenItemsParser.ts new file mode 100644 index 0000000..099019c --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/UnseenItemsParser.ts @@ -0,0 +1,52 @@ +import { IAdvancedMap, IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AdvancedMap } from '@nitrots/utils'; + +export class UnseenItemsParser implements IMessageParser +{ + private _items: IAdvancedMap; + + 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(); + } +} diff --git a/packages/communication/src/messages/parser/notifications/index.ts b/packages/communication/src/messages/parser/notifications/index.ts new file mode 100644 index 0000000..d22f38f --- /dev/null +++ b/packages/communication/src/messages/parser/notifications/index.ts @@ -0,0 +1,18 @@ +export * from './AchievementLevelUpData'; +export * from './AchievementNotificationMessageParser'; +export * from './ActivityPointNotificationParser'; +export * from './BotErrorEventParser'; +export * from './ClubGiftNotificationParser'; +export * from './ConnectionErrorMessageParser'; +export * from './ElementPointerMessageParser'; +export * from './HabboBroadcastMessageParser'; +export * from './HotelWillShutdownParser'; +export * from './InfoFeedEnableMessageParser'; +export * from './MOTDNotificationParser'; +export * from './NotificationDialogMessageParser'; +export * from './OfferRewardDeliveredMessageParser'; +export * from './PetLevelNotificationParser'; +export * from './PetPlacingErrorEventParser'; +export * from './RestoreClientMessageParser'; +export * from './SimpleAlertMessageParser'; +export * from './UnseenItemsParser'; diff --git a/packages/communication/src/messages/parser/nux/NewUserExperienceGiftOfferMessageParser.ts b/packages/communication/src/messages/parser/nux/NewUserExperienceGiftOfferMessageParser.ts new file mode 100644 index 0000000..d3e9a08 --- /dev/null +++ b/packages/communication/src/messages/parser/nux/NewUserExperienceGiftOfferMessageParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { NewUserExperienceGiftOptions } from '../../incoming/nux'; + +export class NewUserExperienceGiftOfferMessageParser implements IMessageParser +{ + private _giftOptions: NewUserExperienceGiftOptions[]; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const count = wrapper.readInt(); + this._giftOptions = []; + let index = 0; + + while(index < count) + { + this._giftOptions.push(new NewUserExperienceGiftOptions(wrapper)); + index++; + } + + return true; + } + + public get giftOptions(): NewUserExperienceGiftOptions[] + { + return this._giftOptions; + } +} diff --git a/packages/communication/src/messages/parser/nux/NewUserExperienceNotCompleteParser.ts b/packages/communication/src/messages/parser/nux/NewUserExperienceNotCompleteParser.ts new file mode 100644 index 0000000..d54b86b --- /dev/null +++ b/packages/communication/src/messages/parser/nux/NewUserExperienceNotCompleteParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class NewUserExperienceNotCompleteParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/nux/index.ts b/packages/communication/src/messages/parser/nux/index.ts new file mode 100644 index 0000000..0ebcd05 --- /dev/null +++ b/packages/communication/src/messages/parser/nux/index.ts @@ -0,0 +1,2 @@ +export * from './NewUserExperienceGiftOfferMessageParser'; +export * from './NewUserExperienceNotCompleteParser'; diff --git a/packages/communication/src/messages/parser/perk/PerkAllowancesMessageParser.ts b/packages/communication/src/messages/parser/perk/PerkAllowancesMessageParser.ts new file mode 100644 index 0000000..0aae0de --- /dev/null +++ b/packages/communication/src/messages/parser/perk/PerkAllowancesMessageParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PerkData } from './common'; + +export class PerkAllowancesMessageParser implements IMessageParser +{ + private _perks: PerkData[]; + + public flush(): boolean + { + this._perks = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._perks = []; + + const size: number = wrapper.readInt(); + + for(let i = 0; i < size; i++) this._perks.push(new PerkData( + wrapper.readString(), + wrapper.readString(), + wrapper.readBoolean() + )); + + return true; + } + + public isAllowed(perkCode: string): boolean + { + let allowed = false; + + for(const perk of this._perks) + { + if(perk.code === perkCode) + { + allowed = perk.isAllowed; + break; + } + } + + return allowed; + } + + public get perks(): PerkData[] + { + return this._perks; + } +} diff --git a/packages/communication/src/messages/parser/perk/common/PerkData.ts b/packages/communication/src/messages/parser/perk/common/PerkData.ts new file mode 100644 index 0000000..61ef542 --- /dev/null +++ b/packages/communication/src/messages/parser/perk/common/PerkData.ts @@ -0,0 +1,28 @@ +export class PerkData +{ + private _code: string; + private _errorMessage: string; + private _isAllowed: boolean; + + constructor(code: string, errorMessage: string, isAllowed: boolean) + { + this._code = code; + this._errorMessage = errorMessage; + this._isAllowed = isAllowed; + } + + public get code(): string + { + return this._code; + } + + public get errorMessage(): string + { + return this._errorMessage; + } + + public get isAllowed(): boolean + { + return this._isAllowed; + } +} diff --git a/packages/communication/src/messages/parser/perk/common/PerkEnum.ts b/packages/communication/src/messages/parser/perk/common/PerkEnum.ts new file mode 100644 index 0000000..454eee9 --- /dev/null +++ b/packages/communication/src/messages/parser/perk/common/PerkEnum.ts @@ -0,0 +1,15 @@ +export class PerkEnum +{ + public static USE_GUIDE_TOOL: string = 'USE_GUIDE_TOOL'; + public static GIVE_GUIDE_TOUR: string = 'GIVE_GUIDE_TOUR'; + public static JUDGE_CHAT_REVIEWS: string = 'JUDGE_CHAT_REVIEWS'; + public static VOTE_IN_COMPETITIONS: string = 'VOTE_IN_COMPETITIONS'; + public static CALL_ON_HELPERS: string = 'CALL_ON_HELPERS'; + public static CITIZEN: string = 'CITIZEN'; + public static TRADE: string = 'TRADE'; + public static HEIGHTMAP_EDITOR_BETA: string = 'HEIGHTMAP_EDITOR_BETA'; + public static BUILDER_AT_WORK: string = 'BUILDER_AT_WORK'; + public static NAVIGATOR_ROOM_THUMBNAIL_CAMERA: string = 'NAVIGATOR_ROOM_THUMBNAIL_CAMERA'; + public static CAMERA: string = 'CAMERA'; + public static MOUSE_ZOOM: string = 'MOUSE_ZOOM'; +} diff --git a/packages/communication/src/messages/parser/perk/common/index.ts b/packages/communication/src/messages/parser/perk/common/index.ts new file mode 100644 index 0000000..a617073 --- /dev/null +++ b/packages/communication/src/messages/parser/perk/common/index.ts @@ -0,0 +1,2 @@ +export * from './PerkData'; +export * from './PerkEnum'; diff --git a/packages/communication/src/messages/parser/perk/index.ts b/packages/communication/src/messages/parser/perk/index.ts new file mode 100644 index 0000000..598feef --- /dev/null +++ b/packages/communication/src/messages/parser/perk/index.ts @@ -0,0 +1,2 @@ +export * from './common'; +export * from './PerkAllowancesMessageParser'; diff --git a/packages/communication/src/messages/parser/pet/OpenPetPackageRequestedMessageParser.ts b/packages/communication/src/messages/parser/pet/OpenPetPackageRequestedMessageParser.ts new file mode 100644 index 0000000..30b7421 --- /dev/null +++ b/packages/communication/src/messages/parser/pet/OpenPetPackageRequestedMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser, PetFigureData } from '@nitrots/api'; + +export class OpenPetPackageRequestedMessageParser implements IMessageParser +{ + private _objectId: number; + private _figureData: PetFigureData; + + flush(): boolean + { + this._objectId = -1; + this._figureData = null; + + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._objectId = wrapper.readInt(); + + if(!wrapper.bytesAvailable) return true; + + this._figureData = new PetFigureData(wrapper.readString()); + + return true; + } + + public get objectId(): number + { + return this._objectId; + } + + public get figureData(): PetFigureData + { + return this._figureData; + } +} diff --git a/packages/communication/src/messages/parser/pet/OpenPetPackageResultMessageParser.ts b/packages/communication/src/messages/parser/pet/OpenPetPackageResultMessageParser.ts new file mode 100644 index 0000000..38f8c35 --- /dev/null +++ b/packages/communication/src/messages/parser/pet/OpenPetPackageResultMessageParser.ts @@ -0,0 +1,41 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class OpenPetPackageResultMessageParser implements IMessageParser +{ + private _objectId: number; + private _nameValidationStatus: number; + private _nameValidationInfo: string; + + flush(): boolean + { + this._objectId = 0; + this._nameValidationStatus = 0; + this._nameValidationInfo = null; + + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._objectId = wrapper.readInt(); + this._nameValidationStatus = wrapper.readInt(); + this._nameValidationInfo = wrapper.readString(); + + return true; + } + + public get objectId(): number + { + return this._objectId; + } + + public get nameValidationStatus(): number + { + return this._nameValidationStatus; + } + + public get nameValidationInfo(): string + { + return this._nameValidationInfo; + } +} diff --git a/packages/communication/src/messages/parser/pet/PetLevelUpdateMessageParser.ts b/packages/communication/src/messages/parser/pet/PetLevelUpdateMessageParser.ts new file mode 100644 index 0000000..52107f0 --- /dev/null +++ b/packages/communication/src/messages/parser/pet/PetLevelUpdateMessageParser.ts @@ -0,0 +1,41 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PetLevelUpdateMessageParser implements IMessageParser +{ + private _roomIndex: number; + private _petId: number; + private _level: number; + + flush(): boolean + { + this._roomIndex = -1; + this._petId = -1; + this._level = -1; + + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._roomIndex = wrapper.readInt(); + this._petId = wrapper.readInt(); + this._level = wrapper.readInt(); + + return true; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get petId(): number + { + return this._petId; + } + + public get level(): number + { + return this._level; + } +} diff --git a/packages/communication/src/messages/parser/pet/PetScratchFailedMessageParser.ts b/packages/communication/src/messages/parser/pet/PetScratchFailedMessageParser.ts new file mode 100644 index 0000000..6633bd6 --- /dev/null +++ b/packages/communication/src/messages/parser/pet/PetScratchFailedMessageParser.ts @@ -0,0 +1,33 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PetScratchFailedMessageParser implements IMessageParser +{ + private _currentAge: number; + private _requiredAge: number; + + flush(): boolean + { + this._currentAge = -1; + this._requiredAge = -1; + + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._currentAge = wrapper.readInt(); + this._requiredAge = wrapper.readInt(); + + return true; + } + + public get currentAge(): number + { + return this._currentAge; + } + + public get requiredAge(): number + { + return this._requiredAge; + } +} diff --git a/packages/communication/src/messages/parser/pet/PetTrainingMessageParser.ts b/packages/communication/src/messages/parser/pet/PetTrainingMessageParser.ts new file mode 100644 index 0000000..0918200 --- /dev/null +++ b/packages/communication/src/messages/parser/pet/PetTrainingMessageParser.ts @@ -0,0 +1,57 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PetTrainingMessageParser implements IMessageParser +{ + private _petId: number; + private _commands: number[]; + private _enabledCommands: number[]; + + flush(): boolean + { + this._petId = -1; + this._commands = []; + this._enabledCommands = []; + + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._petId = wrapper.readInt(); + + let commands = wrapper.readInt(); + + while(commands > 0) + { + this._commands.push(wrapper.readInt()); + + commands--; + } + + let enabledCommands = wrapper.readInt(); + + while(enabledCommands > 0) + { + this._enabledCommands.push(wrapper.readInt()); + + enabledCommands--; + } + + return true; + } + + public get petId(): number + { + return this._petId; + } + + public get commands(): number[] + { + return this._commands; + } + + public get enabledCommands(): number[] + { + return this._enabledCommands; + } +} diff --git a/packages/communication/src/messages/parser/pet/index.ts b/packages/communication/src/messages/parser/pet/index.ts new file mode 100644 index 0000000..41e89ca --- /dev/null +++ b/packages/communication/src/messages/parser/pet/index.ts @@ -0,0 +1,5 @@ +export * from './OpenPetPackageRequestedMessageParser'; +export * from './OpenPetPackageResultMessageParser'; +export * from './PetLevelUpdateMessageParser'; +export * from './PetScratchFailedMessageParser'; +export * from './PetTrainingMessageParser'; diff --git a/packages/communication/src/messages/parser/poll/PollChoice.ts b/packages/communication/src/messages/parser/poll/PollChoice.ts new file mode 100644 index 0000000..ccf9612 --- /dev/null +++ b/packages/communication/src/messages/parser/poll/PollChoice.ts @@ -0,0 +1,45 @@ +import { IPollChoice } from '@nitrots/api'; + +export class PollChoice implements IPollChoice +{ + private _value: string; + private _choiceText: string; + private _choiceType: number; + + constructor(value: string, choiceText: string, choiceType: number) + { + this._value = value; + this._choiceText = choiceText; + this._choiceType = choiceType; + } + + public get value(): string + { + return this._value; + } + + public set value(value: string) + { + this._value = value; + } + + public get choiceText(): string + { + return this._choiceText; + } + + public set choiceText(choiceText: string) + { + this._choiceText = choiceText; + } + + public get choiceType(): number + { + return this._choiceType; + } + + public set choiceType(choiceType: number) + { + this._choiceType = choiceType; + } +} diff --git a/packages/communication/src/messages/parser/poll/PollContentsParser.ts b/packages/communication/src/messages/parser/poll/PollContentsParser.ts new file mode 100644 index 0000000..c8f66dd --- /dev/null +++ b/packages/communication/src/messages/parser/poll/PollContentsParser.ts @@ -0,0 +1,98 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PollChoice } from './PollChoice'; +import { PollQuestion } from './PollQuestion'; + +export class PollContentsParser implements IMessageParser +{ + private _id = -1; + private _startMessage = ''; + private _endMessage = ''; + private _numQuestions = 0; + private _questionArray: PollQuestion[] = []; + private _npsPoll = false; + + flush(): boolean + { + this._id = -1; + this._startMessage = ''; + this._endMessage = ''; + this._numQuestions = 0; + this._questionArray = []; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._id = wrapper.readInt(); + this._startMessage = wrapper.readString(); + this._endMessage = wrapper.readString(); + this._numQuestions = wrapper.readInt(); + + for(let i = 0; i < this._numQuestions; i++) + { + const question = this.parsePollQuestion(wrapper); + const childrenCount = wrapper.readInt(); + + for(let j = 0; j < childrenCount; j++) + { + question.children.push(this.parsePollQuestion(wrapper)); + } + + this._questionArray.push(question); + } + + this._npsPoll = wrapper.readBoolean(); + return true; + } + + private parsePollQuestion(k: IMessageDataWrapper): PollQuestion + { + const pollQuestion = new PollQuestion(); + pollQuestion.questionId = k.readInt(); + pollQuestion.sortOrder = k.readInt(); + pollQuestion.questionType = k.readInt(); + pollQuestion.questionText = k.readString(); + pollQuestion.questionCategory = k.readInt(); + pollQuestion.questionAnswerType = k.readInt(); + pollQuestion.questionAnswerCount = k.readInt(); + if(((pollQuestion.questionType == 1) || (pollQuestion.questionType == 2))) + { + for(let i = 0; i < pollQuestion.questionAnswerCount; i++) + { + pollQuestion.questionChoices.push(new PollChoice(k.readString(), k.readString(), k.readInt())); + } + } + return pollQuestion; + } + + public get id(): number + { + return this._id; + } + + public get startMessage(): string + { + return this._startMessage; + } + + public get endMessage(): string + { + return this._endMessage; + } + + public get numQuestions(): number + { + return this._numQuestions; + } + + public get questionArray(): PollQuestion[] + { + return this._questionArray; + } + + public get npsPoll(): boolean + { + return this._npsPoll; + } + +} diff --git a/packages/communication/src/messages/parser/poll/PollErrorParser.ts b/packages/communication/src/messages/parser/poll/PollErrorParser.ts new file mode 100644 index 0000000..f15fed6 --- /dev/null +++ b/packages/communication/src/messages/parser/poll/PollErrorParser.ts @@ -0,0 +1,14 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PollErrorParser implements IMessageParser +{ + flush(): boolean + { + throw true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + return true; + } +} diff --git a/packages/communication/src/messages/parser/poll/PollOfferParser.ts b/packages/communication/src/messages/parser/poll/PollOfferParser.ts new file mode 100644 index 0000000..bff1dfc --- /dev/null +++ b/packages/communication/src/messages/parser/poll/PollOfferParser.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PollOfferParser implements IMessageParser +{ + private _id = -1; + private _type = ''; + private _headline = ''; + private _summary = ''; + + flush(): boolean + { + this._id = -1; + this._type = ''; + this._summary = ''; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._id = wrapper.readInt(); + this._type = wrapper.readString(); + this._headline = wrapper.readString(); + this._summary = wrapper.readString(); + return true; + } + + public get id(): number + { + return this._id; + } + + public get type(): string + { + return this._type; + } + + public get headline(): string + { + return this._headline; + } + + public get summary(): string + { + return this._summary; + } +} diff --git a/packages/communication/src/messages/parser/poll/PollQuestion.ts b/packages/communication/src/messages/parser/poll/PollQuestion.ts new file mode 100644 index 0000000..2e158f9 --- /dev/null +++ b/packages/communication/src/messages/parser/poll/PollQuestion.ts @@ -0,0 +1,111 @@ +import { IPollQuestion } from '@nitrots/api'; +import { PollChoice } from './PollChoice'; + +export class PollQuestion implements IPollQuestion +{ + private _questionId: number; + private _questionType: number; + private _sortOrder: number; + private _questionCategory: number; + private _questionText: string; + private _questionAnswerType: number; + private _questionAnswerCount: number; + private _children: PollQuestion[]; + private _questionChoices: PollChoice[]; + + constructor() + { + this._children = []; + this._questionChoices = []; + } + + public get questionId(): number + { + return this._questionId; + } + + public set questionId(questionId: number) + { + this._questionId = questionId; + } + + public get questionType(): number + { + return this._questionType; + } + + public set questionType(questionType: number) + { + this._questionType = questionType; + } + + public get sortOrder(): number + { + return this._sortOrder; + } + + public set sortOrder(sortOrder: number) + { + this._sortOrder = sortOrder; + } + + public get questionText(): string + { + return this._questionText; + } + + public set questionText(questionText: string) + { + this._questionText = questionText; + } + + public get questionCategory(): number + { + return this._questionCategory; + } + + public set questionCategory(questionCategory: number) + { + this._questionCategory = questionCategory; + } + + public get questionAnswerType(): number + { + return this._questionAnswerType; + } + + public set questionAnswerType(answerType: number) + { + this._questionAnswerType = answerType; + } + + public get questionAnswerCount(): number + { + return this._questionAnswerCount; + } + + public set questionAnswerCount(k: number) + { + this._questionAnswerCount = k; + } + + public get children(): PollQuestion[] + { + return this._children; + } + + public set children(children: PollQuestion[]) + { + this._children = children; + } + + public get questionChoices(): PollChoice[] + { + return this._questionChoices; + } + + public set questionChoices(k: PollChoice[]) + { + this._questionChoices = k; + } +} diff --git a/packages/communication/src/messages/parser/poll/QuestionAnsweredParser.ts b/packages/communication/src/messages/parser/poll/QuestionAnsweredParser.ts new file mode 100644 index 0000000..ebbcadd --- /dev/null +++ b/packages/communication/src/messages/parser/poll/QuestionAnsweredParser.ts @@ -0,0 +1,49 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class QuestionAnsweredParser implements IMessageParser +{ + private _userId: number; + private _value: string; + private _answerCounts: Map; + + flush(): boolean + { + this._userId = -1; + this._value = ''; + this._answerCounts = null; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._userId = wrapper.readInt(); + this._value = wrapper.readString(); + this._answerCounts = new Map(); + + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + const key = wrapper.readString(); + const value = wrapper.readInt(); + this._answerCounts.set(key, value); + } + return true; + } + + public get userId(): number + { + return this._userId; + } + + public get value(): string + { + return this._value; + } + + public get answerCounts(): Map + { + return this._answerCounts; + } + +} diff --git a/packages/communication/src/messages/parser/poll/QuestionFinishedParser.ts b/packages/communication/src/messages/parser/poll/QuestionFinishedParser.ts new file mode 100644 index 0000000..540c6c9 --- /dev/null +++ b/packages/communication/src/messages/parser/poll/QuestionFinishedParser.ts @@ -0,0 +1,39 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class QuestionFinishedParser implements IMessageParser +{ + private _questionId: number; + private _answerCounts: Map; + + flush(): boolean + { + this._questionId = -1; + this._answerCounts = null; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._questionId = wrapper.readInt(); + this._answerCounts = new Map(); + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + const key = wrapper.readString(); + const value = wrapper.readInt(); + this._answerCounts.set(key, value); + } + return true; + } + + public get questionId(): number + { + return this._questionId; + } + + public get answerCounts(): Map + { + return this._answerCounts; + } +} diff --git a/packages/communication/src/messages/parser/poll/QuestionParser.ts b/packages/communication/src/messages/parser/poll/QuestionParser.ts new file mode 100644 index 0000000..2bb19fe --- /dev/null +++ b/packages/communication/src/messages/parser/poll/QuestionParser.ts @@ -0,0 +1,77 @@ +import { IMessageDataWrapper, IMessageParser, IQuestion } from '@nitrots/api'; + +export class QuestionParser implements IMessageParser +{ + private _pollType: string = null; + private _pollId = -1; + private _questionId = -1; + private _duration = -1; + private _question: IQuestion = null; + + flush(): boolean + { + this._pollType = null; + this._pollId = -1; + this._questionId = -1; + this._duration = -1; + this._question = null; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._pollType = wrapper.readString(); + this._pollId = wrapper.readInt(); + this._questionId = wrapper.readInt(); + this._duration = wrapper.readInt(); + + const questionId = wrapper.readInt(); + const questionNumber = wrapper.readInt(); + const questionType = wrapper.readInt(); + const questionContent = wrapper.readString(); + + this._question = { id: questionId, number: questionNumber, type: questionType, content: questionContent }; + + if(((this._question.type == 1) || (this._question.type == 2))) + { + this._question.selection_min = wrapper.readInt(); + const count = wrapper.readInt(); + this._question.selections = []; + this._question.selection_values = []; + this._question.selection_count = count; + this._question.selection_max = count; + + for(let i = 0; i < count; i++) + { + this._question.selection_values.push(wrapper.readString()); + this._question.selections.push(wrapper.readString()); + } + } + return true; + } + + public get pollType(): string + { + return this._pollType; + } + + public get pollId(): number + { + return this._pollId; + } + + public get questionId(): number + { + return this._questionId; + } + + public get duration(): number + { + return this._duration; + } + + public get question(): IQuestion + { + return this._question; + } +} diff --git a/packages/communication/src/messages/parser/poll/RoomPollDataParser.ts b/packages/communication/src/messages/parser/poll/RoomPollDataParser.ts new file mode 100644 index 0000000..bebbc25 --- /dev/null +++ b/packages/communication/src/messages/parser/poll/RoomPollDataParser.ts @@ -0,0 +1,41 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomPollDataParser implements IMessageParser +{ + private _question: string; + private _choices: string[]; + + flush(): boolean + { + this._question = null; + this._choices = []; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._question = wrapper.readString(); + this._choices = []; + + const totalChoices = wrapper.readInt(); + let total = 0; + + while(total < totalChoices) + { + this._choices.push(wrapper.readString()); + total++; + } + + return true; + } + + public get question(): string + { + return this._question; + } + + public get choices(): string[] + { + return this._choices.slice(); + } +} diff --git a/packages/communication/src/messages/parser/poll/RoomPollResultParser.ts b/packages/communication/src/messages/parser/poll/RoomPollResultParser.ts new file mode 100644 index 0000000..ac19feb --- /dev/null +++ b/packages/communication/src/messages/parser/poll/RoomPollResultParser.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomPollResultParser implements IMessageParser +{ + private _question: string; + private _choices: string[]; + private _SafeStr_7651: any[]; + private _SafeStr_7654: number; + + flush(): boolean + { + this._question = null; + this._choices = []; + this._SafeStr_7651 = []; + this._SafeStr_7654 = -1; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._question = wrapper.readString(); + + this._choices = []; + this._SafeStr_7651 = []; + + let totalChoices = wrapper.readInt(); + + while(totalChoices > 0) + { + this._choices.push(wrapper.readString()); + this._SafeStr_7651.push(wrapper.readInt()); + + totalChoices--; + } + this._SafeStr_7654 = wrapper.readInt(); + + return true; + } + + public get question(): string + { + return this._question; + } + + public get choices(): string[] + { + return this._choices; + } + + public get SafeStr_7651(): any[] + { + return this._SafeStr_7651; + } + + public get SafeStr_7654(): number + { + return this._SafeStr_7654; + } +} diff --git a/packages/communication/src/messages/parser/poll/index.ts b/packages/communication/src/messages/parser/poll/index.ts new file mode 100644 index 0000000..efe3a4a --- /dev/null +++ b/packages/communication/src/messages/parser/poll/index.ts @@ -0,0 +1,10 @@ +export * from './PollChoice'; +export * from './PollContentsParser'; +export * from './PollErrorParser'; +export * from './PollOfferParser'; +export * from './PollQuestion'; +export * from './QuestionAnsweredParser'; +export * from './QuestionFinishedParser'; +export * from './QuestionParser'; +export * from './RoomPollResultParser'; +export * from './RoomPollDataParser'; diff --git a/packages/communication/src/messages/parser/quest/CommunityGoalData.ts b/packages/communication/src/messages/parser/quest/CommunityGoalData.ts new file mode 100644 index 0000000..aad88a9 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/CommunityGoalData.ts @@ -0,0 +1,95 @@ +import { IDisposable, IMessageDataWrapper } from '@nitrots/api'; + +export class CommunityGoalData implements IDisposable +{ + private _hasGoalExpired: boolean; + private _personalContributionScore: number; + private _personalContributionRank: number; + private _communityTotalScore: number; + private _communityHighestAchievedLevel: number; + private _scoreRemainingUntilNextLevel: number; + private _percentCompletionTowardsNextLevel: number; + private _goalCode: string; + private _timeRemainingInSeconds: number; + private _rewardUserLimits: number[]; + + constructor(wrapper: IMessageDataWrapper) + { + this._rewardUserLimits = []; + this._hasGoalExpired = wrapper.readBoolean(); + this._personalContributionScore = wrapper.readInt(); + this._personalContributionRank = wrapper.readInt(); + this._communityTotalScore = wrapper.readInt(); + this._communityHighestAchievedLevel = wrapper.readInt(); + this._scoreRemainingUntilNextLevel = wrapper.readInt(); + this._percentCompletionTowardsNextLevel = wrapper.readInt(); + this._goalCode = wrapper.readString(); + this._timeRemainingInSeconds = wrapper.readInt(); + + const count = wrapper.readInt(); + for(let i = 0; i < count; i++) + { + this._rewardUserLimits.push(wrapper.readInt()); + } + } + + public dispose(): void + { + this._rewardUserLimits = null; + } + + public get disposed(): boolean + { + return this._rewardUserLimits == null; + } + + public get hasGoalExpired(): boolean + { + return this._hasGoalExpired; + } + + public get personalContributionScore(): number + { + return this._personalContributionScore; + } + + public get personalContributionRank(): number + { + return this._personalContributionRank; + } + + public get communityTotalScore(): number + { + return this._communityTotalScore; + } + + public get communityHighestAchievedLevel(): number + { + return this._communityHighestAchievedLevel; + } + + public get scoreRemainingUntilNextLevel(): number + { + return this._scoreRemainingUntilNextLevel; + } + + public get percentCompletionTowardsNextLevel(): number + { + return this._percentCompletionTowardsNextLevel; + } + + public get timeRemainingInSeconds(): number + { + return this._timeRemainingInSeconds; + } + + public get rewardUserLimits(): number[] + { + return this._rewardUserLimits; + } + + public get goalCode(): string + { + return this._goalCode; + } +} diff --git a/packages/communication/src/messages/parser/quest/CommunityGoalEarnedPrizesMessageParser.ts b/packages/communication/src/messages/parser/quest/CommunityGoalEarnedPrizesMessageParser.ts new file mode 100644 index 0000000..836bff9 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/CommunityGoalEarnedPrizesMessageParser.ts @@ -0,0 +1,30 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PrizeData } from './PrizeData'; + +export class CommunityGoalEarnedPrizesMessageParser implements IMessageParser +{ + private _prizes: PrizeData[]; + + public flush(): boolean + { + this._prizes = []; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const count = wrapper.readInt(); + for(let i = 0; i < count; i++) + { + this._prizes.push(new PrizeData(wrapper)); + } + return true; + } + + public get prizes(): PrizeData[] + { + return this._prizes; + } +} diff --git a/packages/communication/src/messages/parser/quest/CommunityGoalHallOfFameData.ts b/packages/communication/src/messages/parser/quest/CommunityGoalHallOfFameData.ts new file mode 100644 index 0000000..9132de6 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/CommunityGoalHallOfFameData.ts @@ -0,0 +1,41 @@ +import { IDisposable, IMessageDataWrapper } from '@nitrots/api'; +import { HallOfFameEntryData } from './HallOfFameEntryData'; + +export class CommunityGoalHallOfFameData implements IDisposable +{ + private _goalCode: string; + private _hof: HallOfFameEntryData[]; + + constructor(wrapper: IMessageDataWrapper) + { + this._hof = []; + this._goalCode = wrapper.readString(); + + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._hof.push(new HallOfFameEntryData(wrapper)); + } + } + + public dispose(): void + { + this._hof = null; + } + + public get disposed(): boolean + { + return this._hof == null; + } + + public get hof(): HallOfFameEntryData[] + { + return this._hof; + } + + public get goalCode(): string + { + return this._goalCode; + } +} diff --git a/packages/communication/src/messages/parser/quest/CommunityGoalHallOfFameMessageParser.ts b/packages/communication/src/messages/parser/quest/CommunityGoalHallOfFameMessageParser.ts new file mode 100644 index 0000000..b65644c --- /dev/null +++ b/packages/communication/src/messages/parser/quest/CommunityGoalHallOfFameMessageParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CommunityGoalHallOfFameData } from './CommunityGoalHallOfFameData'; + +export class CommunityGoalHallOfFameMessageParser implements IMessageParser +{ + private _data: CommunityGoalHallOfFameData; + + public flush(): boolean + { + this._data = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new CommunityGoalHallOfFameData(wrapper); + return true; + } + + public get data(): CommunityGoalHallOfFameData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/quest/CommunityGoalProgressMessageParser.ts b/packages/communication/src/messages/parser/quest/CommunityGoalProgressMessageParser.ts new file mode 100644 index 0000000..f2b866c --- /dev/null +++ b/packages/communication/src/messages/parser/quest/CommunityGoalProgressMessageParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { CommunityGoalData } from './CommunityGoalData'; + +export class CommunityGoalProgressMessageParser implements IMessageParser +{ + private _data: CommunityGoalData; + + public flush(): boolean + { + this._data = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new CommunityGoalData(wrapper); + return true; + } + + public get data(): CommunityGoalData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/quest/ConcurrentUsersGoalProgressMessageParser.ts b/packages/communication/src/messages/parser/quest/ConcurrentUsersGoalProgressMessageParser.ts new file mode 100644 index 0000000..2c9f1b7 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/ConcurrentUsersGoalProgressMessageParser.ts @@ -0,0 +1,41 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ConcurrentUsersGoalProgressMessageParser implements IMessageParser +{ + private _state: number; + private _userCount: number; + private _userCountGoal: number; + + public flush(): boolean + { + this._state = -1; + this._userCount = -1; + this._userCountGoal = -1; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._state = wrapper.readInt(); + this._userCount = wrapper.readInt(); + this._userCountGoal = wrapper.readInt(); + return true; + } + + public get state(): number + { + return this._state; + } + + public get userCount(): number + { + return this._userCount; + } + + public get userCountGoal(): number + { + return this._userCountGoal; + } +} diff --git a/packages/communication/src/messages/parser/quest/EpicPopupMessageParser.ts b/packages/communication/src/messages/parser/quest/EpicPopupMessageParser.ts new file mode 100644 index 0000000..2feea55 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/EpicPopupMessageParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class EpicPopupMessageParser implements IMessageParser +{ + private _imageUri: string; + + public flush(): boolean + { + this._imageUri = ''; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._imageUri = wrapper.readString(); + return true; + } + + public get imageUri(): string + { + return this._imageUri; + } +} diff --git a/packages/communication/src/messages/parser/quest/HallOfFameEntryData.ts b/packages/communication/src/messages/parser/quest/HallOfFameEntryData.ts new file mode 100644 index 0000000..4d2d257 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/HallOfFameEntryData.ts @@ -0,0 +1,45 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { ILandingPageUserEntry } from './ILandingPageUserEntry'; + +export class HallOfFameEntryData implements ILandingPageUserEntry +{ + private _userId: number; + private _userName: string; + private _figure: string; + private _rank: number; + private _currentScore: number; + + constructor(wrapper: IMessageDataWrapper) + { + this._userId = wrapper.readInt(); + this._userName = wrapper.readString(); + this._figure = wrapper.readString(); + this._rank = wrapper.readInt(); + this._currentScore = 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 rank(): number + { + return this._rank; + } + + public get currentScore(): number + { + return this._currentScore; + } +} diff --git a/packages/communication/src/messages/parser/quest/ILandingPageUserEntry.ts b/packages/communication/src/messages/parser/quest/ILandingPageUserEntry.ts new file mode 100644 index 0000000..02362a8 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/ILandingPageUserEntry.ts @@ -0,0 +1,6 @@ +export interface ILandingPageUserEntry +{ + userId: number; + userName: string; + figure: string; +} diff --git a/packages/communication/src/messages/parser/quest/PrizeData.ts b/packages/communication/src/messages/parser/quest/PrizeData.ts new file mode 100644 index 0000000..c3a5085 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/PrizeData.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class PrizeData +{ + private _communityGoalId: number; + private _communityGoalCode: string; + private _userRank: number; + private _rewardCode: string; + private _badge: boolean; + private _localizedName: string; + + constructor(k: IMessageDataWrapper) + { + this._communityGoalId = k.readInt(); + this._communityGoalCode = k.readString(); + this._userRank = k.readInt(); + this._rewardCode = k.readString(); + this._badge = k.readBoolean(); + this._localizedName = k.readString(); + } + + public get communityGoalId(): number + { + return this._communityGoalId; + } + + public get communityGoalCode(): string + { + return this._communityGoalCode; + } + + public get userRank(): number + { + return this._userRank; + } + + public get rewardCode(): string + { + return this._rewardCode; + } + + public get badge(): boolean + { + return this._badge; + } + + public get localizedName(): string + { + return this._localizedName; + } +} diff --git a/packages/communication/src/messages/parser/quest/QuestCancelledMessageParser.ts b/packages/communication/src/messages/parser/quest/QuestCancelledMessageParser.ts new file mode 100644 index 0000000..d9e729d --- /dev/null +++ b/packages/communication/src/messages/parser/quest/QuestCancelledMessageParser.ts @@ -0,0 +1,24 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class QuestCancelledMessageParser implements IMessageParser +{ + private _expired: boolean; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._expired = wrapper.readBoolean(); + return true; + } + + public get expired(): boolean + { + return this._expired; + } +} diff --git a/packages/communication/src/messages/parser/quest/QuestCompletedMessageParser.ts b/packages/communication/src/messages/parser/quest/QuestCompletedMessageParser.ts new file mode 100644 index 0000000..a6c5826 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/QuestCompletedMessageParser.ts @@ -0,0 +1,33 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { QuestMessageData } from './QuestMessageData'; + +export class QuestCompletedMessageParser implements IMessageParser +{ + private _questData: QuestMessageData; + private _showDialog: boolean; + + public flush(): boolean + { + this._questData = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._questData = new QuestMessageData(wrapper); + this._showDialog = wrapper.readBoolean(); + return true; + } + + public get questData(): QuestMessageData + { + return this._questData; + } + + public get showDialog(): boolean + { + return this._showDialog; + } +} diff --git a/packages/communication/src/messages/parser/quest/QuestDailyMessageParser.ts b/packages/communication/src/messages/parser/quest/QuestDailyMessageParser.ts new file mode 100644 index 0000000..c2b14a9 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/QuestDailyMessageParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { QuestMessageData } from './QuestMessageData'; + +export class QuestDailyMessageParser implements IMessageParser +{ + private _quest: QuestMessageData; + private _easyQuestCount: number; + private _hardQuestCount: number; + + public flush(): boolean + { + this._quest = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const _local_2 = wrapper.readBoolean(); + if(_local_2) + { + this._quest = new QuestMessageData(wrapper); + this._easyQuestCount = wrapper.readInt(); + this._hardQuestCount = wrapper.readInt(); + } + return true; + } + + public get quest(): QuestMessageData + { + return this._quest; + } + + public get easyQuestCount(): number + { + return this._easyQuestCount; + } + + public get hardQuestCount(): number + { + return this._hardQuestCount; + } +} diff --git a/packages/communication/src/messages/parser/quest/QuestMessageData.ts b/packages/communication/src/messages/parser/quest/QuestMessageData.ts new file mode 100644 index 0000000..98b4806 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/QuestMessageData.ts @@ -0,0 +1,186 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class QuestMessageData +{ + private _campaignCode: string; + private _completedQuestsInCampaign: number; + private _questCountInCampaign: number; + private _activityPointType: number; + private _id: number; + private _accepted: boolean; + private _type: string; + private _imageVersion: string; + private _rewardCurrencyAmount: number; + private _localizationCode: string; + private _completedSteps: number; + private _totalSteps: number; + private _waitPeriodSeconds: number; + private _sortOrder: number; + private _catalogPageName: string; + private _chainCode: string; + private _easy: boolean; + private _receiveTime: Date; + + constructor(wrapper: IMessageDataWrapper) + { + this._receiveTime = new Date(); + this._campaignCode = wrapper.readString(); + this._completedQuestsInCampaign = wrapper.readInt(); + this._questCountInCampaign = wrapper.readInt(); + this._activityPointType = wrapper.readInt(); + this._id = wrapper.readInt(); + this._accepted = wrapper.readBoolean(); + this._type = wrapper.readString(); + this._imageVersion = wrapper.readString(); + this._rewardCurrencyAmount = wrapper.readInt(); + this._localizationCode = wrapper.readString(); + this._completedSteps = wrapper.readInt(); + this._totalSteps = wrapper.readInt(); + this._sortOrder = wrapper.readInt(); + this._catalogPageName = wrapper.readString(); + this._chainCode = wrapper.readString(); + this._easy = wrapper.readBoolean(); + } + + public static getCampaignLocalizationKeyForCode(k: string): string + { + return 'quests.' + k; + } + + public get campaignCode(): string + { + return this._campaignCode; + } + + public get localizationCode(): string + { + return this._localizationCode; + } + + public get completedQuestsInCampaign(): number + { + return this._completedQuestsInCampaign; + } + + public get questCountInCampaign(): number + { + return this._questCountInCampaign; + } + + public get activityPointType(): number + { + return this._activityPointType; + } + + public set accepted(k: boolean) + { + this._accepted = k; + } + + public get accepted(): boolean + { + return this._accepted; + } + + public set id(k: number) + { + this._id = k; + } + + public get id(): number + { + return this._id; + } + + public get type(): string + { + return this._type; + } + + public get imageVersion(): string + { + return this._imageVersion; + } + + public get rewardCurrencyAmount(): number + { + return this._rewardCurrencyAmount; + } + + public get completedSteps(): number + { + return this._completedSteps; + } + + public get totalSteps(): number + { + return this._totalSteps; + } + + public get isCompleted(): boolean + { + return this._completedSteps == this._totalSteps; + } + + public set waitPeriodSeconds(k: number) + { + this._waitPeriodSeconds = k; + } + + public get waitPeriodSeconds(): number + { + if(this._waitPeriodSeconds < 1) + { + return 0; + } + const k = new Date(); + const _local_2 = (k.getTime() - this._receiveTime.getTime()); + const _local_3 = Math.max(0, (this._waitPeriodSeconds - Math.floor((_local_2 / 1000)))); + return _local_3; + } + + public getCampaignLocalizationKey(): string + { + return QuestMessageData.getCampaignLocalizationKeyForCode(this.campaignCode); + } + + public getQuestLocalizationKey(): string + { + return (this.getCampaignLocalizationKey() + '.') + this._localizationCode; + } + + public get completedCampaign(): boolean + { + return this._id < 1; + } + + public get lastQuestInCampaign(): boolean + { + return this._completedQuestsInCampaign >= this._questCountInCampaign; + } + + public get receiveTime(): Date + { + return this._receiveTime; + } + + public get sortOrder(): number + { + return this._sortOrder; + } + + public get catalogPageName(): string + { + return this._catalogPageName; + } + + public get chainCode(): string + { + return this._chainCode; + } + + public get easy(): boolean + { + return this._easy; + } +} diff --git a/packages/communication/src/messages/parser/quest/QuestMessageParser.ts b/packages/communication/src/messages/parser/quest/QuestMessageParser.ts new file mode 100644 index 0000000..851ebb9 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/QuestMessageParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { QuestMessageData } from './QuestMessageData'; + +export class QuestMessageParser implements IMessageParser +{ + private _quest: QuestMessageData; + + public flush(): boolean + { + this._quest = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._quest = new QuestMessageData(wrapper); + return true; + } + + public get quest(): QuestMessageData + { + return this._quest; + } +} diff --git a/packages/communication/src/messages/parser/quest/QuestsMessageParser.ts b/packages/communication/src/messages/parser/quest/QuestsMessageParser.ts new file mode 100644 index 0000000..c87cf82 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/QuestsMessageParser.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { QuestMessageData } from './QuestMessageData'; + +export class QuestsMessageParser implements IMessageParser +{ + private _quests: QuestMessageData[]; + private _openWindow: boolean; + + + public flush(): boolean + { + this._quests = []; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._quests.push(new QuestMessageData(wrapper)); + } + + this._openWindow = wrapper.readBoolean(); + return true; + } + + public get quests(): QuestMessageData[] + { + return this._quests; + } + + public get openWindow(): boolean + { + return this._openWindow; + } +} diff --git a/packages/communication/src/messages/parser/quest/SeasonalQuestsParser.ts b/packages/communication/src/messages/parser/quest/SeasonalQuestsParser.ts new file mode 100644 index 0000000..a658469 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/SeasonalQuestsParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { QuestMessageData } from './QuestMessageData'; + +export class SeasonalQuestsParser implements IMessageParser +{ + private _quests: QuestMessageData[]; + + public flush(): boolean + { + this._quests = []; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._quests.push(new QuestMessageData(wrapper)); + } + + return true; + } + + public get quests(): QuestMessageData[] + { + return this._quests; + } +} diff --git a/packages/communication/src/messages/parser/quest/index.ts b/packages/communication/src/messages/parser/quest/index.ts new file mode 100644 index 0000000..1185da4 --- /dev/null +++ b/packages/communication/src/messages/parser/quest/index.ts @@ -0,0 +1,17 @@ +export * from './CommunityGoalData'; +export * from './CommunityGoalEarnedPrizesMessageParser'; +export * from './CommunityGoalHallOfFameData'; +export * from './CommunityGoalHallOfFameMessageParser'; +export * from './CommunityGoalProgressMessageParser'; +export * from './ConcurrentUsersGoalProgressMessageParser'; +export * from './EpicPopupMessageParser'; +export * from './HallOfFameEntryData'; +export * from './ILandingPageUserEntry'; +export * from './PrizeData'; +export * from './QuestCancelledMessageParser'; +export * from './QuestCompletedMessageParser'; +export * from './QuestDailyMessageParser'; +export * from './QuestMessageData'; +export * from './QuestMessageParser'; +export * from './QuestsMessageParser'; +export * from './SeasonalQuestsParser'; diff --git a/packages/communication/src/messages/parser/recycler/RecyclerFinishedMessageParser.ts b/packages/communication/src/messages/parser/recycler/RecyclerFinishedMessageParser.ts new file mode 100644 index 0000000..4d366de --- /dev/null +++ b/packages/communication/src/messages/parser/recycler/RecyclerFinishedMessageParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RecyclerFinishedMessageParser implements IMessageParser +{ + private _recyclerFinishedStatus: number; + private _prizeId: number; + + public flush(): boolean + { + this._recyclerFinishedStatus = -1; + this._prizeId = 0; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._recyclerFinishedStatus = wrapper.readInt(); + this._prizeId = wrapper.readInt(); + + return true; + } + + public get recyclerFinishedStatus(): number + { + return this._recyclerFinishedStatus; + } + + public get prizeId(): number + { + return this._prizeId; + } +} diff --git a/packages/communication/src/messages/parser/recycler/RecyclerStatusMessageParser.ts b/packages/communication/src/messages/parser/recycler/RecyclerStatusMessageParser.ts new file mode 100644 index 0000000..15aed28 --- /dev/null +++ b/packages/communication/src/messages/parser/recycler/RecyclerStatusMessageParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RecyclerStatusMessageParser implements IMessageParser +{ + private _recyclerStatus: number; + private _recyclerTimeoutSeconds: number; + + public flush(): boolean + { + this._recyclerStatus = -1; + this._recyclerTimeoutSeconds = 0; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._recyclerStatus = wrapper.readInt(); + this._recyclerTimeoutSeconds = wrapper.readInt(); + + return true; + } + + public get recyclerStatus(): number + { + return this._recyclerStatus; + } + + public get recyclerTimeoutSeconds(): number + { + return this._recyclerTimeoutSeconds; + } +} diff --git a/packages/communication/src/messages/parser/recycler/index.ts b/packages/communication/src/messages/parser/recycler/index.ts new file mode 100644 index 0000000..8fbc648 --- /dev/null +++ b/packages/communication/src/messages/parser/recycler/index.ts @@ -0,0 +1,2 @@ +export * from './RecyclerFinishedMessageParser'; +export * from './RecyclerStatusMessageParser'; diff --git a/packages/communication/src/messages/parser/room/access/CantConnectMessageParser.ts b/packages/communication/src/messages/parser/room/access/CantConnectMessageParser.ts new file mode 100644 index 0000000..b7c6c70 --- /dev/null +++ b/packages/communication/src/messages/parser/room/access/CantConnectMessageParser.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CantConnectMessageParser implements IMessageParser +{ + public static REASON_FULL: number = 1; + public static REASON_CLOSED: number = 2; + public static REASON_QUEUE_ERROR: number = 3; + public static REASON_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; + } +} diff --git a/packages/communication/src/messages/parser/room/access/RoomEnterParser.ts b/packages/communication/src/messages/parser/room/access/RoomEnterParser.ts new file mode 100644 index 0000000..0f0e892 --- /dev/null +++ b/packages/communication/src/messages/parser/room/access/RoomEnterParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomEnterParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/room/access/RoomFowardParser.ts b/packages/communication/src/messages/parser/room/access/RoomFowardParser.ts new file mode 100644 index 0000000..1b09136 --- /dev/null +++ b/packages/communication/src/messages/parser/room/access/RoomFowardParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/access/doorbell/RoomDoorbellAcceptedParser.ts b/packages/communication/src/messages/parser/room/access/doorbell/RoomDoorbellAcceptedParser.ts new file mode 100644 index 0000000..2b4d825 --- /dev/null +++ b/packages/communication/src/messages/parser/room/access/doorbell/RoomDoorbellAcceptedParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/access/doorbell/index.ts b/packages/communication/src/messages/parser/room/access/doorbell/index.ts new file mode 100644 index 0000000..bc56d17 --- /dev/null +++ b/packages/communication/src/messages/parser/room/access/doorbell/index.ts @@ -0,0 +1 @@ +export * from './RoomDoorbellAcceptedParser'; diff --git a/packages/communication/src/messages/parser/room/access/index.ts b/packages/communication/src/messages/parser/room/access/index.ts new file mode 100644 index 0000000..90158a7 --- /dev/null +++ b/packages/communication/src/messages/parser/room/access/index.ts @@ -0,0 +1,5 @@ +export * from './CantConnectMessageParser'; +export * from './doorbell'; +export * from './rights'; +export * from './RoomEnterParser'; +export * from './RoomFowardParser'; diff --git a/packages/communication/src/messages/parser/room/access/rights/RoomRightsClearParser.ts b/packages/communication/src/messages/parser/room/access/rights/RoomRightsClearParser.ts new file mode 100644 index 0000000..12823ba --- /dev/null +++ b/packages/communication/src/messages/parser/room/access/rights/RoomRightsClearParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomRightsClearParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/room/access/rights/RoomRightsOwnerParser.ts b/packages/communication/src/messages/parser/room/access/rights/RoomRightsOwnerParser.ts new file mode 100644 index 0000000..be0ca3b --- /dev/null +++ b/packages/communication/src/messages/parser/room/access/rights/RoomRightsOwnerParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomRightsOwnerParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/room/access/rights/RoomRightsParser.ts b/packages/communication/src/messages/parser/room/access/rights/RoomRightsParser.ts new file mode 100644 index 0000000..5e5b541 --- /dev/null +++ b/packages/communication/src/messages/parser/room/access/rights/RoomRightsParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser, RoomControllerLevel } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/access/rights/index.ts b/packages/communication/src/messages/parser/room/access/rights/index.ts new file mode 100644 index 0000000..e5a319d --- /dev/null +++ b/packages/communication/src/messages/parser/room/access/rights/index.ts @@ -0,0 +1,3 @@ +export * from './RoomRightsClearParser'; +export * from './RoomRightsOwnerParser'; +export * from './RoomRightsParser'; diff --git a/packages/communication/src/messages/parser/room/bots/BotCommandConfigurationParser.ts b/packages/communication/src/messages/parser/room/bots/BotCommandConfigurationParser.ts new file mode 100644 index 0000000..ee3dc82 --- /dev/null +++ b/packages/communication/src/messages/parser/room/bots/BotCommandConfigurationParser.ts @@ -0,0 +1,42 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/room/bots/BotForceOpenContextMenuParser.ts b/packages/communication/src/messages/parser/room/bots/BotForceOpenContextMenuParser.ts new file mode 100644 index 0000000..402ec9f --- /dev/null +++ b/packages/communication/src/messages/parser/room/bots/BotForceOpenContextMenuParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class BotForceOpenContextMenuParser implements IMessageParser +{ + private _botId: number; + + public flush(): boolean + { + this._botId = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._botId = wrapper.readInt(); + + return true; + } + + public get botId(): number + { + return this._botId; + } +} diff --git a/packages/communication/src/messages/parser/room/bots/BotSkillData.ts b/packages/communication/src/messages/parser/room/bots/BotSkillData.ts new file mode 100644 index 0000000..4be45e4 --- /dev/null +++ b/packages/communication/src/messages/parser/room/bots/BotSkillData.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class BotSkillData +{ + private _id: number; + private _data: string; + + constructor(wrapper: IMessageDataWrapper) + { + this._id = wrapper.readInt(); + this._data = wrapper.readString(); + } + + public get id(): number + { + return this._id; + } + + public get data(): string + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/room/bots/BotSkillListUpdateParser.ts b/packages/communication/src/messages/parser/room/bots/BotSkillListUpdateParser.ts new file mode 100644 index 0000000..4d09a4f --- /dev/null +++ b/packages/communication/src/messages/parser/room/bots/BotSkillListUpdateParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { BotSkillData } from './BotSkillData'; + +export class BotSkillListUpdateParser implements IMessageParser +{ + private _botId: number; + private _skillList: BotSkillData[]; + + public flush(): boolean + { + this._botId = -1; + this._skillList = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._botId = wrapper.readInt(); + + let totalSkills = wrapper.readInt(); + + while(totalSkills > 0) + { + this._skillList.push(new BotSkillData(wrapper)); + + totalSkills--; + } + + return true; + } + + public get botId(): number + { + return this._botId; + } + + public get skillList(): BotSkillData[] + { + return this._skillList; + } +} diff --git a/packages/communication/src/messages/parser/room/bots/index.ts b/packages/communication/src/messages/parser/room/bots/index.ts new file mode 100644 index 0000000..f9be3fa --- /dev/null +++ b/packages/communication/src/messages/parser/room/bots/index.ts @@ -0,0 +1,4 @@ +export * from './BotCommandConfigurationParser'; +export * from './BotForceOpenContextMenuParser'; +export * from './BotSkillData'; +export * from './BotSkillListUpdateParser'; diff --git a/packages/communication/src/messages/parser/room/data/RoomChatSettingsParser.ts b/packages/communication/src/messages/parser/room/data/RoomChatSettingsParser.ts new file mode 100644 index 0000000..cfa3338 --- /dev/null +++ b/packages/communication/src/messages/parser/room/data/RoomChatSettingsParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { RoomChatSettings } from '../../roomsettings'; + +export class RoomChatSettingsParser implements IMessageParser +{ + private _chat: RoomChatSettings; + + public flush(): boolean + { + this._chat = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._chat = new RoomChatSettings(wrapper); + + return true; + } + + public get chat(): RoomChatSettings + { + return this._chat; + } +} diff --git a/packages/communication/src/messages/parser/room/data/RoomDataParser.ts b/packages/communication/src/messages/parser/room/data/RoomDataParser.ts new file mode 100644 index 0000000..067649b --- /dev/null +++ b/packages/communication/src/messages/parser/room/data/RoomDataParser.ts @@ -0,0 +1,301 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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 = 3; + public static NOOB_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 _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._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 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/packages/communication/src/messages/parser/room/data/RoomEntryInfoMessageParser.ts b/packages/communication/src/messages/parser/room/data/RoomEntryInfoMessageParser.ts new file mode 100644 index 0000000..8d5d5bd --- /dev/null +++ b/packages/communication/src/messages/parser/room/data/RoomEntryInfoMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomEntryInfoMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/room/data/RoomScoreParser.ts b/packages/communication/src/messages/parser/room/data/RoomScoreParser.ts new file mode 100644 index 0000000..df2579d --- /dev/null +++ b/packages/communication/src/messages/parser/room/data/RoomScoreParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/data/index.ts b/packages/communication/src/messages/parser/room/data/index.ts new file mode 100644 index 0000000..7e040d1 --- /dev/null +++ b/packages/communication/src/messages/parser/room/data/index.ts @@ -0,0 +1,4 @@ +export * from './RoomChatSettingsParser'; +export * from './RoomDataParser'; +export * from './RoomEntryInfoMessageParser'; +export * from './RoomScoreParser'; diff --git a/packages/communication/src/messages/parser/room/engine/FavoriteMembershipUpdateMessageParser.ts b/packages/communication/src/messages/parser/room/engine/FavoriteMembershipUpdateMessageParser.ts new file mode 100644 index 0000000..9473fc4 --- /dev/null +++ b/packages/communication/src/messages/parser/room/engine/FavoriteMembershipUpdateMessageParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FavoriteMembershipUpdateMessageParser implements IMessageParser +{ + private _roomIndex: number; + private _groupId: number; + private _status: number; + private _groupName: string; + + public flush(): boolean + { + this._roomIndex = -1; + this._groupId = -1; + this._status = 0; + this._groupName = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomIndex = wrapper.readInt(); + this._groupId = wrapper.readInt(); + this._status = wrapper.readInt(); + this._groupName = wrapper.readString(); + + return true; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get groupId(): number + { + return this._groupId; + } + + public get status(): number + { + return this._status; + } + + public get groupName(): string + { + return this._groupName; + } +} diff --git a/packages/communication/src/messages/parser/room/engine/ObjectData.ts b/packages/communication/src/messages/parser/room/engine/ObjectData.ts new file mode 100644 index 0000000..ba5f1bf --- /dev/null +++ b/packages/communication/src/messages/parser/room/engine/ObjectData.ts @@ -0,0 +1,30 @@ +import { IObjectData } from '@nitrots/api'; + +export class ObjectData +{ + private _id: number = 0; + private _state: number = 0; + private _data: IObjectData; + + constructor(id: number, state: number, objectData: IObjectData) + { + this._id = id; + this._state = state; + this._data = objectData; + } + + public get id(): number + { + return this._id; + } + + public get state(): number + { + return this._state; + } + + public get data(): IObjectData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/room/engine/ObjectsDataUpdateParser.ts b/packages/communication/src/messages/parser/room/engine/ObjectsDataUpdateParser.ts new file mode 100644 index 0000000..c9b933e --- /dev/null +++ b/packages/communication/src/messages/parser/room/engine/ObjectsDataUpdateParser.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { FurnitureDataParser } from '../furniture'; +import { ObjectData } from './ObjectData'; + +export class ObjectsDataUpdateParser implements IMessageParser +{ + private _objects: ObjectData[]; + + public flush(): boolean + { + this._objects = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalObjects = wrapper.readInt(); + + while(totalObjects > 0) + { + const id = wrapper.readInt(); + const stuffData = FurnitureDataParser.parseObjectData(wrapper); + const state = parseFloat(stuffData.getLegacyString()); + + this._objects.push(new ObjectData(id, state, stuffData)); + + totalObjects--; + } + + return true; + } + + public get objects(): ObjectData[] + { + return this._objects; + } +} diff --git a/packages/communication/src/messages/parser/room/engine/ObjectsRollingParser.ts b/packages/communication/src/messages/parser/room/engine/ObjectsRollingParser.ts new file mode 100644 index 0000000..32240d8 --- /dev/null +++ b/packages/communication/src/messages/parser/room/engine/ObjectsRollingParser.ts @@ -0,0 +1,80 @@ +import { IMessageDataWrapper, IMessageParser, ObjectRolling } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; + +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 false; + + 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; + } +} diff --git a/packages/communication/src/messages/parser/room/engine/index.ts b/packages/communication/src/messages/parser/room/engine/index.ts new file mode 100644 index 0000000..ba275c9 --- /dev/null +++ b/packages/communication/src/messages/parser/room/engine/index.ts @@ -0,0 +1,4 @@ +export * from './FavoriteMembershipUpdateMessageParser'; +export * from './ObjectData'; +export * from './ObjectsDataUpdateParser'; +export * from './ObjectsRollingParser'; diff --git a/packages/communication/src/messages/parser/room/furniture/CustomUserNotificationMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/CustomUserNotificationMessageParser.ts new file mode 100644 index 0000000..e951a1c --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/CustomUserNotificationMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class CustomUserNotificationMessageParser 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 count(): number + { + return this._code; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/DiceValueMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/DiceValueMessageParser.ts new file mode 100644 index 0000000..18f341a --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/DiceValueMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class DiceValueMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/FurniRentOrBuyoutOfferMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/FurniRentOrBuyoutOfferMessageParser.ts new file mode 100644 index 0000000..14655f3 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/FurniRentOrBuyoutOfferMessageParser.ts @@ -0,0 +1,67 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FurniRentOrBuyoutOfferMessageParser implements IMessageParser +{ + private _isWallItem: boolean; + private _furniTypeName: string; + private _buyout: boolean; + private _priceInCredits: number; + private _priceInActivityPoints: number; + private _activityPointType: number; + + public flush(): boolean + { + this._isWallItem = false; + this._furniTypeName = null; + this._buyout = false; + this._priceInCredits = -1; + this._priceInActivityPoints = -1; + this._activityPointType = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._isWallItem = wrapper.readBoolean(); + this._furniTypeName = wrapper.readString(); + this._buyout = wrapper.readBoolean(); + this._priceInCredits = wrapper.readInt(); + this._priceInActivityPoints = wrapper.readInt(); + this._activityPointType = wrapper.readInt(); + + return true; + } + + public get isWallItem(): boolean + { + return this._isWallItem; + } + + public get furniTypeName(): string + { + return this._furniTypeName; + } + + public get buyout(): boolean + { + return this._buyout; + } + + public get priceInCredits(): number + { + return this._priceInCredits; + } + + public get priceInActivityPoints(): number + { + return this._priceInActivityPoints; + } + + public get activityPointType(): number + { + return this._activityPointType; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/FurnitureAliasesParser.ts b/packages/communication/src/messages/parser/room/furniture/FurnitureAliasesParser.ts new file mode 100644 index 0000000..82f2427 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/FurnitureAliasesParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/FurnitureDataParser.ts b/packages/communication/src/messages/parser/room/furniture/FurnitureDataParser.ts new file mode 100644 index 0000000..2d73d29 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/FurnitureDataParser.ts @@ -0,0 +1,48 @@ +import { IMessageDataWrapper, IMessageParser, IObjectData, ObjectDataFactory } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/FurnitureStackHeightParser.ts b/packages/communication/src/messages/parser/room/furniture/FurnitureStackHeightParser.ts new file mode 100644 index 0000000..eedf85d --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/FurnitureStackHeightParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/GroupFurniContextMenuInfoMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/GroupFurniContextMenuInfoMessageParser.ts new file mode 100644 index 0000000..ab5a649 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/GroupFurniContextMenuInfoMessageParser.ts @@ -0,0 +1,67 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GroupFurniContextMenuInfoMessageParser implements IMessageParser +{ + private _objectId: number; + private _guildId: number; + private _guildName: string; + private _guildHomeRoomId: number; + private _userIsMember: boolean; + private _guildHasReadableForum: boolean; + + public flush(): boolean + { + this._objectId = 0; + this._guildId = 0; + this._guildName = null; + this._guildHomeRoomId = 0; + this._userIsMember = false; + this._guildHasReadableForum = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._objectId = wrapper.readInt(); + this._guildId = wrapper.readInt(); + this._guildName = wrapper.readString(); + this._guildHomeRoomId = wrapper.readInt(); + this._userIsMember = wrapper.readBoolean(); + this._guildHasReadableForum = wrapper.readBoolean(); + + return true; + } + + public get objectId(): number + { + return this._objectId; + } + + public get guildId(): number + { + return this._guildId; + } + + public get guildName(): string + { + return this._guildName; + } + + public get guildHomeRoomId(): number + { + return this._guildHomeRoomId; + } + + public get userIsMember(): boolean + { + return this._userIsMember; + } + + public get guildHasReadableForum(): boolean + { + return this._guildHasReadableForum; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/ItemDataUpdateMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/ItemDataUpdateMessageParser.ts new file mode 100644 index 0000000..6655aba --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/ItemDataUpdateMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ItemDataUpdateMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/LoveLockFurniFinishedParser.ts b/packages/communication/src/messages/parser/room/furniture/LoveLockFurniFinishedParser.ts new file mode 100644 index 0000000..92177da --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/LoveLockFurniFinishedParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/room/furniture/LoveLockFurniFriendConfirmedParser.ts b/packages/communication/src/messages/parser/room/furniture/LoveLockFurniFriendConfirmedParser.ts new file mode 100644 index 0000000..c1be162 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/LoveLockFurniFriendConfirmedParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/room/furniture/LoveLockFurniStartParser.ts b/packages/communication/src/messages/parser/room/furniture/LoveLockFurniStartParser.ts new file mode 100644 index 0000000..81d587d --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/LoveLockFurniStartParser.ts @@ -0,0 +1,31 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/room/furniture/OneWayDoorStatusMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/OneWayDoorStatusMessageParser.ts new file mode 100644 index 0000000..5eb6283 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/OneWayDoorStatusMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class OneWayDoorStatusMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/RentableSpaceRentFailedMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/RentableSpaceRentFailedMessageParser.ts new file mode 100644 index 0000000..a31533c --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/RentableSpaceRentFailedMessageParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RentableSpaceRentFailedMessageParser implements IMessageParser +{ + private _reason: number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._reason = wrapper.readInt(); + + return true; + } + + public get reason(): number + { + return this._reason; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/RentableSpaceRentOkMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/RentableSpaceRentOkMessageParser.ts new file mode 100644 index 0000000..db3e03d --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/RentableSpaceRentOkMessageParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RentableSpaceRentOkMessageParser implements IMessageParser +{ + private _expiryTime: number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._expiryTime = wrapper.readInt(); + + return true; + } + + public get expiryTime(): number + { + return this._expiryTime; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/RentableSpaceStatusMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/RentableSpaceStatusMessageParser.ts new file mode 100644 index 0000000..b9a8cae --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/RentableSpaceStatusMessageParser.ts @@ -0,0 +1,92 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RentableSpaceStatusMessageParser implements IMessageParser +{ + public static readonly SPACE_ALREADY_RENTED = 100; + public static readonly SPACE_EXTEND_NOT_RENTED = 101; + public static readonly SPACE_EXTEND_NOT_RENTED_BY_YOU = 102; + public static readonly CAN_RENT_ONLY_ONE_SPACE = 103; + public static readonly NOT_ENOUGH_CREDITS = 200; + public static readonly NOT_ENOUGH_PIXELS = 201; + public static readonly CANT_RENT_NO_PERMISSION = 202; + public static readonly CANT_RENT_NO_HABBO_CLUB = 203; + public static readonly CANT_RENT = 300; + public static readonly CANT_RENT_GENERIC = 400; + + private _rented: boolean; + private _renterId: number; + private _renterName: string; + private _canRent: boolean; + private _canRentErrorCode: number; + private _timeRemaining: number; + private _price: number; + + public flush(): boolean + { + this._rented = false; + this._renterId = -1; + this._renterName = null; + this._canRent = false; + this._canRentErrorCode = -1; + this._timeRemaining = -1; + this._price = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._rented = wrapper.readBoolean(); + this._canRentErrorCode = wrapper.readInt(); + this._canRent = (this._canRentErrorCode === 0); + this._renterId = wrapper.readInt(); + this._renterName = wrapper.readString(); + this._timeRemaining = wrapper.readInt(); + this._price = wrapper.readInt(); + + if(!this._rented) + { + this._renterId = -1; + this._renterName = ''; + } + + return true; + } + + public get rented(): boolean + { + return this._rented; + } + + public get renterId(): number + { + return this._renterId; + } + + public get renterName(): string + { + return this._renterName; + } + + public get canRent(): boolean + { + return this._canRent; + } + + public get price(): number + { + return this._price; + } + + public get timeRemaining(): number + { + return this._timeRemaining; + } + + public get canRentErrorCode(): number + { + return this._canRentErrorCode; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/RequestSpamWallPostItMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/RequestSpamWallPostItMessageParser.ts new file mode 100644 index 0000000..b4cfbcd --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/RequestSpamWallPostItMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RequestSpamWallPostItMessageParser implements IMessageParser +{ + private _itemId: number; + private _location: string; + + public flush(): boolean + { + this._itemId = -1; + this._location = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = wrapper.readInt(); + this._location = wrapper.readString(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } + + public get location(): string + { + return this._location; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/RoomDimmerPresetsMessageData.ts b/packages/communication/src/messages/parser/room/furniture/RoomDimmerPresetsMessageData.ts new file mode 100644 index 0000000..9264b72 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/RoomDimmerPresetsMessageData.ts @@ -0,0 +1,9 @@ +export class RoomDimmerPresetsMessageData +{ + constructor( + public id: number, + public type: number, + public color: number, + public brightness: number) + {} +} diff --git a/packages/communication/src/messages/parser/room/furniture/RoomDimmerPresetsMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/RoomDimmerPresetsMessageParser.ts new file mode 100644 index 0000000..d69e04d --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/RoomDimmerPresetsMessageParser.ts @@ -0,0 +1,57 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { RoomDimmerPresetsMessageData } from './RoomDimmerPresetsMessageData'; + +export class RoomDimmerPresetsMessageParser implements IMessageParser +{ + private _selectedPresetId: number; + private _presets: RoomDimmerPresetsMessageData[]; + + constructor() + { + this._selectedPresetId = 0; + this._presets = []; + } + + public flush(): boolean + { + this._presets = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + const totalPresets = wrapper.readInt(); + + this._selectedPresetId = wrapper.readInt(); + + for(let i = 0; i < totalPresets; i++) + { + const presetId = wrapper.readInt(); + const type = wrapper.readInt(); + const color = parseInt(wrapper.readString().substr(1), 16); + const brightness = wrapper.readInt(); + + this._presets.push(new RoomDimmerPresetsMessageData(presetId, type, color, brightness)); + } + + return true; + } + + public getPreset(id: number): RoomDimmerPresetsMessageData + { + if((id < 0) || (id >= this.presetCount)) return null; + + return this._presets[id]; + } + + public get presetCount(): number + { + return this._presets.length; + } + + public get selectedPresetId(): number + { + return this._selectedPresetId; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/RoomMessageNotificationMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/RoomMessageNotificationMessageParser.ts new file mode 100644 index 0000000..4b19c0e --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/RoomMessageNotificationMessageParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomMessageNotificationMessageParser implements IMessageParser +{ + private _roomId: number; + private _roomName: string; + private _messageCount: number; + + public flush(): boolean + { + this._roomId = -1; + this._roomName = null; + this._messageCount = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._roomName = wrapper.readString(); + this._messageCount = wrapper.readInt(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get roomName(): string + { + return this._roomName; + } + + public get messageCount(): number + { + return this._messageCount; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/WelcomeGiftStatusParser.ts b/packages/communication/src/messages/parser/room/furniture/WelcomeGiftStatusParser.ts new file mode 100644 index 0000000..b7ffc5d --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/WelcomeGiftStatusParser.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class WelcomeGiftStatusParser implements IMessageParser +{ + private _email: string; + private _isVerified: boolean; + private _allowChange: boolean; + private _furniId: number; + private _requestedByUser: boolean; + + public flush(): boolean + { + this._email = null; + this._isVerified = false; + this._allowChange = false; + this._furniId = -1; + this._requestedByUser = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._email = wrapper.readString(); + this._isVerified = wrapper.readBoolean(); + this._allowChange = wrapper.readBoolean(); + this._furniId = wrapper.readInt(); + this._requestedByUser = wrapper.readBoolean(); + + return true; + } + + public get email(): string + { + return this._email; + } + + public get isVerified(): boolean + { + return this._isVerified; + } + + public get allowChange(): boolean + { + return this._allowChange; + } + + public get furniId(): number + { + return this._furniId; + } + + public get requestedByUser(): boolean + { + return this._requestedByUser; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorAddParser.ts b/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorAddParser.ts new file mode 100644 index 0000000..6125e16 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorAddParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorDataParser.ts b/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorDataParser.ts new file mode 100644 index 0000000..f8340d1 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorDataParser.ts @@ -0,0 +1,159 @@ +import { IMessageDataWrapper, IObjectData } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorParser.ts b/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorParser.ts new file mode 100644 index 0000000..0a2f3c4 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorParser.ts @@ -0,0 +1,68 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorRemoveParser.ts b/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorRemoveParser.ts new file mode 100644 index 0000000..e5f4b77 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorRemoveParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorUpdateParser.ts b/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorUpdateParser.ts new file mode 100644 index 0000000..8f5b1e2 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/floor/FurnitureFloorUpdateParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/floor/index.ts b/packages/communication/src/messages/parser/room/furniture/floor/index.ts new file mode 100644 index 0000000..710c755 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/floor/index.ts @@ -0,0 +1,5 @@ +export * from './FurnitureFloorAddParser'; +export * from './FurnitureFloorDataParser'; +export * from './FurnitureFloorParser'; +export * from './FurnitureFloorRemoveParser'; +export * from './FurnitureFloorUpdateParser'; diff --git a/packages/communication/src/messages/parser/room/furniture/index.ts b/packages/communication/src/messages/parser/room/furniture/index.ts new file mode 100644 index 0000000..8cebe4b --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/index.ts @@ -0,0 +1,23 @@ +export * from './CustomUserNotificationMessageParser'; +export * from './DiceValueMessageParser'; +export * from './floor'; +export * from './FurniRentOrBuyoutOfferMessageParser'; +export * from './FurnitureAliasesParser'; +export * from './FurnitureDataParser'; +export * from './FurnitureStackHeightParser'; +export * from './GroupFurniContextMenuInfoMessageParser'; +export * from './ItemDataUpdateMessageParser'; +export * from './LoveLockFurniFinishedParser'; +export * from './LoveLockFurniFriendConfirmedParser'; +export * from './LoveLockFurniStartParser'; +export * from './OneWayDoorStatusMessageParser'; +export * from './RentableSpaceRentFailedMessageParser'; +export * from './RentableSpaceRentOkMessageParser'; +export * from './RentableSpaceStatusMessageParser'; +export * from './RequestSpamWallPostItMessageParser'; +export * from './RoomDimmerPresetsMessageData'; +export * from './RoomDimmerPresetsMessageParser'; +export * from './RoomMessageNotificationMessageParser'; +export * from './wall'; +export * from './WelcomeGiftStatusParser'; +export * from './youtube'; diff --git a/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallAddParser.ts b/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallAddParser.ts new file mode 100644 index 0000000..be52de9 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallAddParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallDataParser.ts b/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallDataParser.ts new file mode 100644 index 0000000..a716e74 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallDataParser.ts @@ -0,0 +1,228 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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 _isOldFormat: 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._isOldFormat = 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 = Math.trunc(state); + + if(this._location.indexOf(':') === 0) + { + this._isOldFormat = 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._isOldFormat = 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 isOldFormat(): boolean + { + return this._isOldFormat; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallParser.ts b/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallParser.ts new file mode 100644 index 0000000..b017bcf --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallParser.ts @@ -0,0 +1,68 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallRemoveParser.ts b/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallRemoveParser.ts new file mode 100644 index 0000000..a0442ee --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallRemoveParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallUpdateParser.ts b/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallUpdateParser.ts new file mode 100644 index 0000000..475061c --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/wall/FurnitureWallUpdateParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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); + + return true; + } + + public get item(): FurnitureWallDataParser + { + return this._item; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/wall/index.ts b/packages/communication/src/messages/parser/room/furniture/wall/index.ts new file mode 100644 index 0000000..2b085b2 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/wall/index.ts @@ -0,0 +1,5 @@ +export * from './FurnitureWallAddParser'; +export * from './FurnitureWallDataParser'; +export * from './FurnitureWallParser'; +export * from './FurnitureWallRemoveParser'; +export * from './FurnitureWallUpdateParser'; diff --git a/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeControlVideoMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeControlVideoMessageParser.ts new file mode 100644 index 0000000..d18451f --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeControlVideoMessageParser.ts @@ -0,0 +1,31 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class YoutubeControlVideoMessageParser implements IMessageParser +{ + private _furniId: number; + private _commandId: number; + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._furniId = wrapper.readInt(); + this._commandId = wrapper.readInt(); + return true; + } + + public flush(): boolean + { + this._furniId = -1; + this._commandId = -1; + return true; + } + + public get furniId(): number + { + return this._furniId; + } + + public get commandId(): number + { + return this._commandId; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayPlaylist.ts b/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayPlaylist.ts new file mode 100644 index 0000000..f47c5ee --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayPlaylist.ts @@ -0,0 +1,28 @@ +export class YoutubeDisplayPlaylist +{ + private _video: string; + private _title: string; + private _description: string; + + constructor(k: string, _arg_2: string, _arg_3: string) + { + this._video = k; + this._title = _arg_2; + this._description = _arg_3; + } + + public get video():string + { + return this._video; + } + + public get title():string + { + return this._title; + } + + public get description():string + { + return this._description; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayPlaylistsMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayPlaylistsMessageParser.ts new file mode 100644 index 0000000..dcbcb96 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayPlaylistsMessageParser.ts @@ -0,0 +1,45 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { YoutubeDisplayPlaylist } from './YoutubeDisplayPlaylist'; + +export class YoutubeDisplayPlaylistsMessageParser implements IMessageParser +{ + private _furniId: number; + private _playlists: YoutubeDisplayPlaylist[]; + private _selectedPlaylistId: string; + + flush(): boolean + { + this._furniId = -1; + this._playlists = null; + this._selectedPlaylistId = null; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._furniId = wrapper.readInt(); + const count = wrapper.readInt(); + this._playlists = []; + for(let i = 0; i < count; i++) + { + this._playlists.push(new YoutubeDisplayPlaylist(wrapper.readString(), wrapper.readString(), wrapper.readString())); + } + this._selectedPlaylistId = wrapper.readString(); + return true; + } + + public get furniId(): number + { + return this._furniId; + } + + public get playlists(): YoutubeDisplayPlaylist[] + { + return this._playlists; + } + + public get selectedPlaylistId(): string + { + return this._selectedPlaylistId; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayVideoMessageParser.ts b/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayVideoMessageParser.ts new file mode 100644 index 0000000..221fedd --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/youtube/YoutubeDisplayVideoMessageParser.ts @@ -0,0 +1,50 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class YoutubeDisplayVideoMessageParser implements IMessageParser +{ + private _furniId: number; + private _videoId: string; + private _startAtSeconds: number; + private _endAtSeconds: number; + private _state: number; + + flush(): boolean + { + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._furniId = wrapper.readInt(); + this._videoId = wrapper.readString(); + this._startAtSeconds = wrapper.readInt(); + this._endAtSeconds = wrapper.readInt(); + this._state = wrapper.readInt(); + return true; + } + + public get furniId(): number + { + return this._furniId; + } + + public get videoId(): string + { + return this._videoId; + } + + public get state(): number + { + return this._state; + } + + public get startAtSeconds(): number + { + return this._startAtSeconds; + } + + public get endAtSeconds(): number + { + return this._endAtSeconds; + } +} diff --git a/packages/communication/src/messages/parser/room/furniture/youtube/index.ts b/packages/communication/src/messages/parser/room/furniture/youtube/index.ts new file mode 100644 index 0000000..9339473 --- /dev/null +++ b/packages/communication/src/messages/parser/room/furniture/youtube/index.ts @@ -0,0 +1,4 @@ +export * from './YoutubeControlVideoMessageParser'; +export * from './YoutubeDisplayPlaylist'; +export * from './YoutubeDisplayPlaylistsMessageParser'; +export * from './YoutubeDisplayVideoMessageParser'; diff --git a/packages/communication/src/messages/parser/room/index.ts b/packages/communication/src/messages/parser/room/index.ts new file mode 100644 index 0000000..81b327b --- /dev/null +++ b/packages/communication/src/messages/parser/room/index.ts @@ -0,0 +1,15 @@ +export * from './access'; +export * from './access/doorbell'; +export * from './access/rights'; +export * from './bots'; +export * from './data'; +export * from './engine'; +export * from './furniture'; +export * from './furniture/floor'; +export * from './furniture/wall'; +export * from './furniture/youtube'; +export * from './mapping'; +export * from './pet'; +export * from './session'; +export * from './unit'; +export * from './unit/chat'; diff --git a/packages/communication/src/messages/parser/room/mapping/FloorHeightMapMessageParser.ts b/packages/communication/src/messages/parser/room/mapping/FloorHeightMapMessageParser.ts new file mode 100644 index 0000000..3100840 --- /dev/null +++ b/packages/communication/src/messages/parser/room/mapping/FloorHeightMapMessageParser.ts @@ -0,0 +1,167 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FloorHeightMapMessageParser implements IMessageParser +{ + public static TILE_BLOCKED: number = -110; + + 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(FloorHeightMapMessageParser.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 = FloorHeightMapMessageParser.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/packages/communication/src/messages/parser/room/mapping/RoomEntryTileMessageParser.ts b/packages/communication/src/messages/parser/room/mapping/RoomEntryTileMessageParser.ts new file mode 100644 index 0000000..a3bda84 --- /dev/null +++ b/packages/communication/src/messages/parser/room/mapping/RoomEntryTileMessageParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomEntryTileMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/room/mapping/RoomHeightMapParser.ts b/packages/communication/src/messages/parser/room/mapping/RoomHeightMapParser.ts new file mode 100644 index 0000000..763419f --- /dev/null +++ b/packages/communication/src/messages/parser/room/mapping/RoomHeightMapParser.ts @@ -0,0 +1,88 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/mapping/RoomHeightMapUpdateParser.ts b/packages/communication/src/messages/parser/room/mapping/RoomHeightMapUpdateParser.ts new file mode 100644 index 0000000..58234b2 --- /dev/null +++ b/packages/communication/src/messages/parser/room/mapping/RoomHeightMapUpdateParser.ts @@ -0,0 +1,75 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/room/mapping/RoomOccupiedTilesMessageParser.ts b/packages/communication/src/messages/parser/room/mapping/RoomOccupiedTilesMessageParser.ts new file mode 100644 index 0000000..6887aed --- /dev/null +++ b/packages/communication/src/messages/parser/room/mapping/RoomOccupiedTilesMessageParser.ts @@ -0,0 +1,39 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomOccupiedTilesMessageParser implements IMessageParser +{ + private _blockedTilesMap: boolean[][]; + + public flush(): boolean + { + this._blockedTilesMap = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let tilesCount = wrapper.readInt(); + + while(tilesCount > 0) + { + const x = wrapper.readInt(); + const y = wrapper.readInt(); + + if(!this._blockedTilesMap[y]) this._blockedTilesMap[y] = []; + + this._blockedTilesMap[y][x] = true; + + tilesCount--; + } + + return true; + } + + public get blockedTilesMap(): boolean[][] + { + return this._blockedTilesMap; + } +} diff --git a/packages/communication/src/messages/parser/room/mapping/RoomPaintParser.ts b/packages/communication/src/messages/parser/room/mapping/RoomPaintParser.ts new file mode 100644 index 0000000..82d54b4 --- /dev/null +++ b/packages/communication/src/messages/parser/room/mapping/RoomPaintParser.ts @@ -0,0 +1,65 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/mapping/RoomReadyMessageParser.ts b/packages/communication/src/messages/parser/room/mapping/RoomReadyMessageParser.ts new file mode 100644 index 0000000..72b4add --- /dev/null +++ b/packages/communication/src/messages/parser/room/mapping/RoomReadyMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomReadyMessageParser 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; + } +} diff --git a/packages/communication/src/messages/parser/room/mapping/RoomVisualizationSettingsParser.ts b/packages/communication/src/messages/parser/room/mapping/RoomVisualizationSettingsParser.ts new file mode 100644 index 0000000..ea0e203 --- /dev/null +++ b/packages/communication/src/messages/parser/room/mapping/RoomVisualizationSettingsParser.ts @@ -0,0 +1,50 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomVisualizationSettingsParser 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; + } +} diff --git a/packages/communication/src/messages/parser/room/mapping/index.ts b/packages/communication/src/messages/parser/room/mapping/index.ts new file mode 100644 index 0000000..11846fd --- /dev/null +++ b/packages/communication/src/messages/parser/room/mapping/index.ts @@ -0,0 +1,8 @@ +export * from './FloorHeightMapMessageParser'; +export * from './RoomEntryTileMessageParser'; +export * from './RoomHeightMapParser'; +export * from './RoomHeightMapUpdateParser'; +export * from './RoomOccupiedTilesMessageParser'; +export * from './RoomPaintParser'; +export * from './RoomReadyMessageParser'; +export * from './RoomVisualizationSettingsParser'; diff --git a/packages/communication/src/messages/parser/room/pet/PetBreedingResultParser.ts b/packages/communication/src/messages/parser/room/pet/PetBreedingResultParser.ts new file mode 100644 index 0000000..a8f7c14 --- /dev/null +++ b/packages/communication/src/messages/parser/room/pet/PetBreedingResultParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser, PetBreedingResultData } from '@nitrots/api'; + +export class PetBreedingResultParser implements IMessageParser +{ + private _resultData: PetBreedingResultData; + private _otherResultData: PetBreedingResultData; + + public flush(): boolean + { + this._resultData = null; + this._otherResultData = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._resultData = new PetBreedingResultData(wrapper); + this._otherResultData = new PetBreedingResultData(wrapper); + + return true; + } + + public get resultData(): PetBreedingResultData + { + return this._resultData; + } + + public get otherResultData(): PetBreedingResultData + { + return this._otherResultData; + } +} diff --git a/packages/communication/src/messages/parser/room/pet/PetExperienceParser.ts b/packages/communication/src/messages/parser/room/pet/PetExperienceParser.ts new file mode 100644 index 0000000..0b86bbc --- /dev/null +++ b/packages/communication/src/messages/parser/room/pet/PetExperienceParser.ts @@ -0,0 +1,42 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PetExperienceParser implements IMessageParser +{ + private _petId: number; + private _roomIndex: number; + private _gainedExperience: number; + + public flush(): boolean + { + this._petId = -1; + this._roomIndex = -1; + this._gainedExperience = 0; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._petId = wrapper.readInt(); + this._roomIndex = wrapper.readInt(); + this._gainedExperience = wrapper.readInt(); + + return true; + } + + public get petId(): number + { + return this._petId; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get gainedExperience(): number + { + return this._gainedExperience; + } +} diff --git a/packages/communication/src/messages/parser/room/pet/PetFigureUpdateParser.ts b/packages/communication/src/messages/parser/room/pet/PetFigureUpdateParser.ts new file mode 100644 index 0000000..435de5b --- /dev/null +++ b/packages/communication/src/messages/parser/room/pet/PetFigureUpdateParser.ts @@ -0,0 +1,54 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PetFigureDataParser } from '../../inventory'; + +export class PetFigureUpdateParser implements IMessageParser +{ + private _roomIndex: number; + private _petId: number; + private _figureData: PetFigureDataParser; + 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 PetFigureDataParser(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(): PetFigureDataParser + { + return this._figureData; + } + + public get hasSaddle(): boolean + { + return this._hasSaddle; + } + + public get isRiding(): boolean + { + return this._isRiding; + } +} diff --git a/packages/communication/src/messages/parser/room/pet/PetInfoParser.ts b/packages/communication/src/messages/parser/room/pet/PetInfoParser.ts new file mode 100644 index 0000000..774d651 --- /dev/null +++ b/packages/communication/src/messages/parser/room/pet/PetInfoParser.ts @@ -0,0 +1,220 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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 _skillThresholds: number[]; + private _publiclyRideable: number; + private _unknownRarity: number; + private _publiclyBreedable: boolean; + + public flush(): boolean + { + this._id = -1; + this._skillThresholds = []; + + 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._skillThresholds.push(wrapper.readInt()); + + total--; + } + + this._skillThresholds.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 skillTresholds(): number[] + { + return this._skillThresholds; + } + + public get publiclyRideable(): number + { + return this._publiclyRideable; + } + + public get unknownRarity(): number + { + return this._unknownRarity; + } + + public get publiclyBreedable(): boolean + { + return this._publiclyBreedable; + } +} diff --git a/packages/communication/src/messages/parser/room/pet/PetStatusUpdateParser.ts b/packages/communication/src/messages/parser/room/pet/PetStatusUpdateParser.ts new file mode 100644 index 0000000..56ee0a8 --- /dev/null +++ b/packages/communication/src/messages/parser/room/pet/PetStatusUpdateParser.ts @@ -0,0 +1,67 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PetStatusUpdateParser implements IMessageParser +{ + private _roomIndex: number; + private _petId: number; + private _canBreed: boolean; + private _canHarvest: boolean; + private _canRevive: boolean; + private _hasBreedingPermission: boolean; + + public flush(): boolean + { + this._roomIndex = -1; + this._petId = -1; + this._canBreed = false; + this._canHarvest = false; + this._canRevive = false; + this._hasBreedingPermission = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomIndex = wrapper.readInt(); + this._petId = wrapper.readInt(); + this._canBreed = wrapper.readBoolean(); + this._canHarvest = wrapper.readBoolean(); + this._canRevive = wrapper.readBoolean(); + this._hasBreedingPermission = wrapper.readBoolean(); + + return true; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get petId(): number + { + return this._petId; + } + + public get canBreed(): boolean + { + return this._canBreed; + } + + public get canHarvest(): boolean + { + return this._canHarvest; + } + + public get canRevive(): boolean + { + return this._canRevive; + } + + public get hasBreedingPermission(): boolean + { + return this._hasBreedingPermission; + } +} diff --git a/packages/communication/src/messages/parser/room/pet/index.ts b/packages/communication/src/messages/parser/room/pet/index.ts new file mode 100644 index 0000000..5e187c2 --- /dev/null +++ b/packages/communication/src/messages/parser/room/pet/index.ts @@ -0,0 +1,5 @@ +export * from './PetBreedingResultParser'; +export * from './PetExperienceParser'; +export * from './PetFigureUpdateParser'; +export * from './PetInfoParser'; +export * from './PetStatusUpdateParser'; diff --git a/packages/communication/src/messages/parser/room/session/YouArePlayingGameParser.ts b/packages/communication/src/messages/parser/room/session/YouArePlayingGameParser.ts new file mode 100644 index 0000000..093d295 --- /dev/null +++ b/packages/communication/src/messages/parser/room/session/YouArePlayingGameParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/session/YouAreSpectatorMessageParser.ts b/packages/communication/src/messages/parser/room/session/YouAreSpectatorMessageParser.ts new file mode 100644 index 0000000..07c351a --- /dev/null +++ b/packages/communication/src/messages/parser/room/session/YouAreSpectatorMessageParser.ts @@ -0,0 +1,14 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class YouAreSpectatorMessageParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + return true; + } +} diff --git a/packages/communication/src/messages/parser/room/session/index.ts b/packages/communication/src/messages/parser/room/session/index.ts new file mode 100644 index 0000000..4624934 --- /dev/null +++ b/packages/communication/src/messages/parser/room/session/index.ts @@ -0,0 +1,2 @@ +export * from './YouArePlayingGameParser'; +export * from './YouAreSpectatorMessageParser'; diff --git a/packages/communication/src/messages/parser/room/unit/RoomUnitDanceParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitDanceParser.ts new file mode 100644 index 0000000..915052c --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitDanceParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/RoomUnitEffectParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitEffectParser.ts new file mode 100644 index 0000000..77fb9a8 --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitEffectParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/RoomUnitExpressionParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitExpressionParser.ts new file mode 100644 index 0000000..043e5fe --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitExpressionParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/RoomUnitHandItemParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitHandItemParser.ts new file mode 100644 index 0000000..b6f7e0f --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitHandItemParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/RoomUnitHandItemReceivedParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitHandItemReceivedParser.ts new file mode 100644 index 0000000..54556fe --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitHandItemReceivedParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/room/unit/RoomUnitIdleParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitIdleParser.ts new file mode 100644 index 0000000..fa2940b --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitIdleParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/RoomUnitInfoParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitInfoParser.ts new file mode 100644 index 0000000..2fed182 --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitInfoParser.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/RoomUnitNumberParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitNumberParser.ts new file mode 100644 index 0000000..7868f22 --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitNumberParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/RoomUnitParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitParser.ts new file mode 100644 index 0000000..dbd5976 --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitParser.ts @@ -0,0 +1,186 @@ +import { IMessageDataWrapper, IMessageParser, RoomObjectType } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/RoomUnitRemoveParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitRemoveParser.ts new file mode 100644 index 0000000..8032a0a --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitRemoveParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/RoomUnitStatusAction.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitStatusAction.ts new file mode 100644 index 0000000..f49e657 --- /dev/null +++ b/packages/communication/src/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/packages/communication/src/messages/parser/room/unit/RoomUnitStatusMessage.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitStatusMessage.ts new file mode 100644 index 0000000..5bc7d58 --- /dev/null +++ b/packages/communication/src/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/packages/communication/src/messages/parser/room/unit/RoomUnitStatusParser.ts b/packages/communication/src/messages/parser/room/unit/RoomUnitStatusParser.ts new file mode 100644 index 0000000..3ba39e1 --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/RoomUnitStatusParser.ts @@ -0,0 +1,119 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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 statusActions: RoomUnitStatusAction[] = []; + + for(const action of actionParts) + { + const parts = action.split(' '); + + if(parts[0] === '') continue; + + if(parts.length >= 2) + { + switch(parts[0]) + { + case 'mv': { + const values = parts[1].split(','); + + if(values.length >= 3) + { + targetX = parseInt(values[0]); + targetY = parseInt(values[1]); + targetZ = parseFloat(values[2]); + didMove = true; + } + + break; + } + case 'sit': { + const sitHeight = parseFloat(parts[1]); + + if(parts.length >= 3) canStandUp = (parts[2] === '1'); + + height = sitHeight; + + break; + } + case 'lay': { + const layHeight = parseFloat(parts[1]); + + height = Math.abs(layHeight); + + break; + } + } + + statusActions.push(new RoomUnitStatusAction(parts[0], parts[1])); + } + } + + 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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/UserMessageData.ts b/packages/communication/src/messages/parser/room/unit/UserMessageData.ts new file mode 100644 index 0000000..b6a944d --- /dev/null +++ b/packages/communication/src/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: number = 0; + 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 setReadOnly(): 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(): number + { + return this._groupID; + } + + public set groupID(groupId: number) + { + if(!this._isReadOnly) + { + this._groupID = groupId; + } + } + + 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; + } + } +} diff --git a/packages/communication/src/messages/parser/room/unit/chat/FloodControlParser.ts b/packages/communication/src/messages/parser/room/unit/chat/FloodControlParser.ts new file mode 100644 index 0000000..a29e9f7 --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/chat/FloodControlParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/room/unit/chat/RemainingMuteParser.ts b/packages/communication/src/messages/parser/room/unit/chat/RemainingMuteParser.ts new file mode 100644 index 0000000..299ab5a --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/chat/RemainingMuteParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/room/unit/chat/RoomUnitChatParser.ts b/packages/communication/src/messages/parser/room/unit/chat/RoomUnitChatParser.ts new file mode 100644 index 0000000..571f9b9 --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/chat/RoomUnitChatParser.ts @@ -0,0 +1,87 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/chat/RoomUnitTypingParser.ts b/packages/communication/src/messages/parser/room/unit/chat/RoomUnitTypingParser.ts new file mode 100644 index 0000000..1879fe4 --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/chat/RoomUnitTypingParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/room/unit/chat/index.ts b/packages/communication/src/messages/parser/room/unit/chat/index.ts new file mode 100644 index 0000000..e9ab87f --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/chat/index.ts @@ -0,0 +1,4 @@ +export * from './FloodControlParser'; +export * from './RemainingMuteParser'; +export * from './RoomUnitChatParser'; +export * from './RoomUnitTypingParser'; diff --git a/packages/communication/src/messages/parser/room/unit/index.ts b/packages/communication/src/messages/parser/room/unit/index.ts new file mode 100644 index 0000000..9728961 --- /dev/null +++ b/packages/communication/src/messages/parser/room/unit/index.ts @@ -0,0 +1,15 @@ +export * from './chat'; +export * from './RoomUnitDanceParser'; +export * from './RoomUnitEffectParser'; +export * from './RoomUnitExpressionParser'; +export * from './RoomUnitHandItemParser'; +export * from './RoomUnitHandItemReceivedParser'; +export * from './RoomUnitIdleParser'; +export * from './RoomUnitInfoParser'; +export * from './RoomUnitNumberParser'; +export * from './RoomUnitParser'; +export * from './RoomUnitRemoveParser'; +export * from './RoomUnitStatusAction'; +export * from './RoomUnitStatusMessage'; +export * from './RoomUnitStatusParser'; +export * from './UserMessageData'; diff --git a/packages/communication/src/messages/parser/roomevents/ConditionDefinition.ts b/packages/communication/src/messages/parser/roomevents/ConditionDefinition.ts new file mode 100644 index 0000000..cc1b8dc --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/ConditionDefinition.ts @@ -0,0 +1,24 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/TriggerDefinition.ts b/packages/communication/src/messages/parser/roomevents/TriggerDefinition.ts new file mode 100644 index 0000000..d2f8645 --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/TriggerDefinition.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +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 code(): number + { + return this._triggerConf; + } + + public get conflictingActions(): number[] + { + return this._conflictingActions; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/Triggerable.ts b/packages/communication/src/messages/parser/roomevents/Triggerable.ts new file mode 100644 index 0000000..705343b --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/Triggerable.ts @@ -0,0 +1,100 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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 stuffTypeSelectionEnabled(): boolean + { + return this._stuffTypeSelectionEnabled; + } + + public get stuffTypeSelectionCode(): number + { + return this._stuffTypeSelectionCode; + } + + public set stuffTypeSelectionCode(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; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/WiredActionDefinition.ts b/packages/communication/src/messages/parser/roomevents/WiredActionDefinition.ts new file mode 100644 index 0000000..be1db47 --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/WiredActionDefinition.ts @@ -0,0 +1,47 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { Triggerable } from './Triggerable'; + +export class WiredActionDefinition 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; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/WiredFurniActionParser.ts b/packages/communication/src/messages/parser/roomevents/WiredFurniActionParser.ts new file mode 100644 index 0000000..6d7aa91 --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/WiredFurniActionParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { WiredActionDefinition } from './WiredActionDefinition'; + +export class WiredFurniActionParser implements IMessageParser +{ + private _definition: WiredActionDefinition; + + public flush(): boolean + { + this._definition = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._definition = new WiredActionDefinition(wrapper); + + return true; + } + + public get definition(): WiredActionDefinition + { + return this._definition; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/WiredFurniConditionParser.ts b/packages/communication/src/messages/parser/roomevents/WiredFurniConditionParser.ts new file mode 100644 index 0000000..9470d6c --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/WiredFurniConditionParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { ConditionDefinition } from './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; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/WiredFurniTriggerParser.ts b/packages/communication/src/messages/parser/roomevents/WiredFurniTriggerParser.ts new file mode 100644 index 0000000..dc6c664 --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/WiredFurniTriggerParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { TriggerDefinition } from './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; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/WiredOpenParser.ts b/packages/communication/src/messages/parser/roomevents/WiredOpenParser.ts new file mode 100644 index 0000000..8179cb1 --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/WiredOpenParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/WiredRewardResultMessageParser.ts b/packages/communication/src/messages/parser/roomevents/WiredRewardResultMessageParser.ts new file mode 100644 index 0000000..46be100 --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/WiredRewardResultMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/WiredSaveSuccessParser.ts b/packages/communication/src/messages/parser/roomevents/WiredSaveSuccessParser.ts new file mode 100644 index 0000000..ef98439 --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/WiredSaveSuccessParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class WiredSaveSuccessParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/WiredValidationErrorParser.ts b/packages/communication/src/messages/parser/roomevents/WiredValidationErrorParser.ts new file mode 100644 index 0000000..1a4ace0 --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/WiredValidationErrorParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/roomevents/index.ts b/packages/communication/src/messages/parser/roomevents/index.ts new file mode 100644 index 0000000..cca201e --- /dev/null +++ b/packages/communication/src/messages/parser/roomevents/index.ts @@ -0,0 +1,11 @@ +export * from './ConditionDefinition'; +export * from './Triggerable'; +export * from './TriggerDefinition'; +export * from './WiredActionDefinition'; +export * from './WiredFurniActionParser'; +export * from './WiredFurniConditionParser'; +export * from './WiredFurniTriggerParser'; +export * from './WiredOpenParser'; +export * from './WiredRewardResultMessageParser'; +export * from './WiredSaveSuccessParser'; +export * from './WiredValidationErrorParser'; diff --git a/packages/communication/src/messages/parser/roomsettings/BannedUserData.ts b/packages/communication/src/messages/parser/roomsettings/BannedUserData.ts new file mode 100644 index 0000000..8481cdc --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/BannedUserData.ts @@ -0,0 +1,24 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { IFlatUser } from './IFlatUser'; + +export class BannedUserData implements IFlatUser +{ + private _userId: number; + private _userName: string; + + constructor(wrapper: IMessageDataWrapper) + { + this._userId = wrapper.readInt(); + this._userName = wrapper.readString(); + } + + public get userId(): number + { + return this._userId; + } + + public get userName(): string + { + return this._userName; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/BannedUsersFromRoomParser.ts b/packages/communication/src/messages/parser/roomsettings/BannedUsersFromRoomParser.ts new file mode 100644 index 0000000..528905e --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/BannedUsersFromRoomParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { BannedUserData } from './BannedUserData'; + +export class BannedUsersFromRoomParser implements IMessageParser +{ + private _roomId: number; + private _bannedUsers: BannedUserData[]; + + public flush(): boolean + { + this._roomId = 0; + this._bannedUsers = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + + let totalBans = wrapper.readInt(); + + while(totalBans > 0) + { + this._bannedUsers.push(new BannedUserData(wrapper)); + + totalBans--; + } + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get bannedUsers(): BannedUserData[] + { + return this._bannedUsers; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/FlatControllerAddedParser.ts b/packages/communication/src/messages/parser/roomsettings/FlatControllerAddedParser.ts new file mode 100644 index 0000000..6c8e1c6 --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/FlatControllerAddedParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { FlatControllerData } from './FlatControllerData'; + +export class FlatControllerAddedParser implements IMessageParser +{ + private _roomId: number; + private _data: FlatControllerData; + + public flush(): boolean + { + this._roomId = 0; + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._data = new FlatControllerData(wrapper); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get data(): FlatControllerData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/FlatControllerData.ts b/packages/communication/src/messages/parser/roomsettings/FlatControllerData.ts new file mode 100644 index 0000000..d6df1bf --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/FlatControllerData.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper } from '@nitrots/api'; +import { IFlatUser } from './IFlatUser'; + +export class FlatControllerData implements IFlatUser +{ + private _userId: number; + private _userName: string; + private _selected: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + this._userId = wrapper.readInt(); + this._userName = wrapper.readString(); + } + + public get userId(): number + { + return this._userId; + } + + public get userName(): string + { + return this._userName; + } + + public get selected(): boolean + { + return this._selected; + } + + public set selected(selected: boolean) + { + this._selected = selected; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/FlatControllerRemovedParser.ts b/packages/communication/src/messages/parser/roomsettings/FlatControllerRemovedParser.ts new file mode 100644 index 0000000..a8af4cc --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/FlatControllerRemovedParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FlatControllerRemovedParser implements IMessageParser +{ + private _roomId: number; + private _userId: number; + + public flush(): boolean + { + this._roomId = 0; + this._userId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._userId = wrapper.readInt(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get userId(): number + { + return this._userId; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/FlatControllersParser.ts b/packages/communication/src/messages/parser/roomsettings/FlatControllersParser.ts new file mode 100644 index 0000000..893b0f0 --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/FlatControllersParser.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class FlatControllersParser 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; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/IFlatUser.ts b/packages/communication/src/messages/parser/roomsettings/IFlatUser.ts new file mode 100644 index 0000000..60c133d --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/IFlatUser.ts @@ -0,0 +1,5 @@ +export interface IFlatUser +{ + userId: number; + userName: string; +} diff --git a/packages/communication/src/messages/parser/roomsettings/MuteAllInRoomParser.ts b/packages/communication/src/messages/parser/roomsettings/MuteAllInRoomParser.ts new file mode 100644 index 0000000..6b0508f --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/MuteAllInRoomParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class MuteAllInRoomParser 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; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/NoSuchFlatParser.ts b/packages/communication/src/messages/parser/roomsettings/NoSuchFlatParser.ts new file mode 100644 index 0000000..80c440c --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/NoSuchFlatParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class NoSuchFlatParser 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; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/RoomChatSettings.ts b/packages/communication/src/messages/parser/roomsettings/RoomChatSettings.ts new file mode 100644 index 0000000..fc3d1e5 --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/RoomChatSettings.ts @@ -0,0 +1,57 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class RoomChatSettings +{ + public static CHAT_MODE_FREE_FLOW: number = 0; + public static CHAT_MODE_LINE_BY_LINE: number = 1; + public static CHAT_BUBBLE_WIDTH_WIDE: number = 0; + public static CHAT_BUBBLE_WIDTH_NORMAL: number = 1; + public static CHAT_BUBBLE_WIDTH_THIN: number = 2; + public static CHAT_SCROLL_SPEED_FAST: number = 0; + public static CHAT_SCROLL_SPEED_NORMAL: number = 1; + public static CHAT_SCROLL_SPEED_SLOW: number = 2; + public static FLOOD_FILTER_STRICT: number = 0; + public static FLOOD_FILTER_NORMAL: number = 1; + public static FLOOD_FILTER_LOOSE: 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._mode = wrapper.readInt(); + this._weight = wrapper.readInt(); + this._speed = wrapper.readInt(); + this._distance = wrapper.readInt(); + this._protection = wrapper.readInt(); + } + + 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; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/RoomModerationSettings.ts b/packages/communication/src/messages/parser/roomsettings/RoomModerationSettings.ts new file mode 100644 index 0000000..7b1cb09 --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/RoomModerationSettings.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IRoomModerationSettings } from '@nitrots/api'; + +export class RoomModerationSettings implements IRoomModerationSettings +{ + public static MODERATION_LEVEL_NONE: number = 0; + public static MODERATION_LEVEL_USER_WITH_RIGHTS: number = 1; + public static MODERATION_LEVEL_ALL: number = 2; + + private _allowMute: number; + private _allowKick: number; + private _allowBan: number; + + constructor(wrapper: IMessageDataWrapper) + { + 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; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/RoomSettingsData.ts b/packages/communication/src/messages/parser/roomsettings/RoomSettingsData.ts new file mode 100644 index 0000000..4384e5e --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/RoomSettingsData.ts @@ -0,0 +1,332 @@ +import { BannedUserData } from './BannedUserData'; +import { FlatControllerData } from './FlatControllerData'; +import { RoomChatSettings } from './RoomChatSettings'; +import { RoomModerationSettings } from './RoomModerationSettings'; + +export class RoomSettingsData +{ + public static DOORMODE_OPEN: number = 0; + public static DOORMODE_CLOSED: number = 1; + public static DOORMODE_PASSWORD: number = 2; + public static DOORMODE_INVISIBLE: number = 3; + public static DOORMODE_NOOBS_ONLY: number = 4; + public static TRADEMODE_NOT_ALLOWED: number = 0; + public static TRADEMODE_WITH_CONTROLLER: number = 1; + public static TRADEMODE_ALLOWED: number = 2; + + private _roomId: number = -1; + private _name: string = null; + private _description: string = null; + private _doorMode: number = RoomSettingsData.DOORMODE_OPEN; + private _categoryId: number = -1; + private _maximumVisitors: number = 0; + private _maximumVisitorsLimit: number = 0; + private _tags: string[] = []; + private _tradeMode: number = RoomSettingsData.TRADEMODE_NOT_ALLOWED; + private _allowPets: boolean = false; + private _allowFoodConsume: boolean = false; + private _allowWalkThrough: boolean = false; + private _hideWalls: boolean = false; + private _wallThickness: number = 0; + private _floorThickness: number = 0; + private _controllersById: Map = new Map(); + private _controllerList: FlatControllerData[] = null; + private _highlightedUserId: number = -1; + private _bannedUsersById: Map = new Map(); + private _bannedUsersList: BannedUserData[] = null; + private _roomModerationSettings: RoomModerationSettings = null; + private _chatSettings: RoomChatSettings = null; + private _allowNavigatorDynamicCats: boolean = false; + + public static from(settings: RoomSettingsData) + { + const instance = new RoomSettingsData(); + + instance._roomId = settings._roomId; + instance._name = settings._name; + instance._description = settings._description; + instance._doorMode = settings._doorMode; + instance._categoryId = settings._categoryId; + instance._maximumVisitors = settings._maximumVisitors; + instance._maximumVisitorsLimit = settings._maximumVisitorsLimit; + instance._tags = settings._tags; + instance._tradeMode = settings._tradeMode; + instance._allowPets = settings._allowPets; + instance._allowFoodConsume = settings._allowFoodConsume; + instance._allowWalkThrough = settings._allowWalkThrough; + instance._hideWalls = settings._hideWalls; + instance._wallThickness = settings._wallThickness; + instance._floorThickness = settings._floorThickness; + instance._controllersById = settings._controllersById; + instance._controllerList = settings._controllerList; + instance._highlightedUserId = settings._highlightedUserId; + instance._bannedUsersById = settings._bannedUsersById; + instance._bannedUsersList = settings._bannedUsersList; + instance._roomModerationSettings = settings._roomModerationSettings; + instance._chatSettings = settings._chatSettings; + instance._allowNavigatorDynamicCats = settings._allowNavigatorDynamicCats; + + return instance; + } + + public static getDoorModeLocalizationKey(k: number): string + { + switch(k) + { + case RoomSettingsData.DOORMODE_OPEN: + return '${navigator.door.mode.open}'; + case RoomSettingsData.DOORMODE_CLOSED: + return '${navigator.door.mode.closed}'; + case RoomSettingsData.DOORMODE_PASSWORD: + return '${navigator.door.mode.password}'; + case RoomSettingsData.DOORMODE_INVISIBLE: + return '${navigator.door.mode.invisible}'; + case RoomSettingsData.DOORMODE_NOOBS_ONLY: + return '${navigator.door.mode.noobs_only}'; + } + return ''; + } + + public get tradeMode(): number + { + return this._tradeMode; + } + + public set tradeMode(mode: number) + { + this._tradeMode = mode; + } + + public get allowPets(): boolean + { + return this._allowPets; + } + + public set allowPets(flag: boolean) + { + this._allowPets = flag; + } + + public get allowFoodConsume(): boolean + { + return this._allowFoodConsume; + } + + public set allowFoodConsume(flag: boolean) + { + this._allowFoodConsume = flag; + } + + public get allowWalkThrough(): boolean + { + return this._allowWalkThrough; + } + + public set allowWalkThrough(flag: boolean) + { + this._allowWalkThrough = flag; + } + + public get hideWalls(): boolean + { + return this._hideWalls; + } + + public set hideWalls(flag: boolean) + { + this._hideWalls = flag; + } + + public get wallThickness(): number + { + return this._wallThickness; + } + + public set wallThickness(thickness: number) + { + this._wallThickness = thickness; + } + + public get floorThickness(): number + { + return this._floorThickness; + } + + public set floorThickness(thickness: number) + { + this._floorThickness = thickness; + } + + public get roomId(): number + { + return this._roomId; + } + + public set roomId(id: number) + { + this._roomId = id; + } + + public get name(): string + { + return this._name; + } + + public set name(name: string) + { + this._name = name; + } + + public get description(): string + { + return this._description; + } + + public set description(description: string) + { + this._description = description; + } + + public get doorMode(): number + { + return this._doorMode; + } + + public set doorMode(mode: number) + { + this._doorMode = mode; + } + + public get categoryId(): number + { + return this._categoryId; + } + + public set categoryId(id: number) + { + this._categoryId = id; + } + + public get maximumVisitors(): number + { + return this._maximumVisitors; + } + + public set maximumVisitors(max: number) + { + this._maximumVisitors = max; + } + + public get maximumVisitorsLimit(): number + { + return this._maximumVisitorsLimit; + } + + public set maximumVisitorsLimit(limit: number) + { + this._maximumVisitorsLimit = limit; + } + + public get tags(): string[] + { + return this._tags; + } + + public set tags(tags: string[]) + { + this._tags = tags; + } + + public setFlatController(id: number, data: FlatControllerData): void + { + this._controllersById.set(id, data); + + this._controllerList = null; + this._highlightedUserId = id; + } + + public get roomModerationSettings(): RoomModerationSettings + { + return this._roomModerationSettings; + } + + public set roomModerationSettings(settings: RoomModerationSettings) + { + this._roomModerationSettings = settings; + } + + public get controllersById(): Map + { + return this._controllersById; + } + + public set controllersById(controllers: Map) + { + this._controllersById = controllers; + } + + public get controllerList(): FlatControllerData[] + { + if(!this._controllerList) + { + this._controllerList = []; + + for(const controllerData of this._controllersById.values()) this._controllerList.push(controllerData); + + this._controllerList.sort((a, b) => a.userName.localeCompare(b.userName)); + } + + return this._controllerList; + } + + public get highlightedUserId(): number + { + return this._highlightedUserId; + } + + public setBannedUser(id: number, data: BannedUserData): void + { + this._bannedUsersById.set(id, data); + + this._bannedUsersList = null; + } + + public get bannedUsersById(): Map + { + return this._bannedUsersById; + } + + public get bannedUsersList(): BannedUserData[] + { + if(!this._bannedUsersList) + { + this._bannedUsersList = []; + + for(const bannedUserData of this._bannedUsersById.values()) this._bannedUsersList.push(bannedUserData); + + this._bannedUsersList.sort((a, b) => a.userName.localeCompare(b.userName)); + } + + return this._bannedUsersList; + } + + public get chatSettings(): RoomChatSettings + { + return this._chatSettings; + } + + public set chatSettings(settings: RoomChatSettings) + { + this._chatSettings = settings; + } + + public get allowNavigatorDynamicCats(): boolean + { + return this._allowNavigatorDynamicCats; + } + + public set allowNavigatorDynamicCats(flag: boolean) + { + this._allowNavigatorDynamicCats = flag; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/RoomSettingsDataParser.ts b/packages/communication/src/messages/parser/roomsettings/RoomSettingsDataParser.ts new file mode 100644 index 0000000..ed02587 --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/RoomSettingsDataParser.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { RoomChatSettings } from './RoomChatSettings'; +import { RoomModerationSettings } from './RoomModerationSettings'; +import { RoomSettingsData } from './RoomSettingsData'; + +export class RoomSettingsDataParser implements IMessageParser +{ + private _roomSettingsData: RoomSettingsData; + + public flush(): boolean + { + this._roomSettingsData = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomSettingsData = new RoomSettingsData(); + + this._roomSettingsData.roomId = wrapper.readInt(); + this._roomSettingsData.name = wrapper.readString(); + this._roomSettingsData.description = wrapper.readString(); + this._roomSettingsData.doorMode = wrapper.readInt(); + this._roomSettingsData.categoryId = wrapper.readInt(); + this._roomSettingsData.maximumVisitors = wrapper.readInt(); + this._roomSettingsData.maximumVisitorsLimit = wrapper.readInt(); + this._roomSettingsData.tags = []; + + let totalTags = wrapper.readInt(); + + while(totalTags > 0) + { + this._roomSettingsData.tags.push(wrapper.readString()); + + totalTags--; + } + + this._roomSettingsData.tradeMode = wrapper.readInt(); + this._roomSettingsData.allowPets = (wrapper.readInt() === 1); + this._roomSettingsData.allowFoodConsume = (wrapper.readInt() === 1); + this._roomSettingsData.allowWalkThrough = (wrapper.readInt() === 1); + this._roomSettingsData.hideWalls = (wrapper.readInt() === 1); + this._roomSettingsData.wallThickness = wrapper.readInt(); + this._roomSettingsData.floorThickness = wrapper.readInt(); + this._roomSettingsData.chatSettings = new RoomChatSettings(wrapper); + this._roomSettingsData.allowNavigatorDynamicCats = wrapper.readBoolean(); + this._roomSettingsData.roomModerationSettings = new RoomModerationSettings(wrapper); + + return true; + } + + public get data(): RoomSettingsData + { + return this._roomSettingsData; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/RoomSettingsErrorParser.ts b/packages/communication/src/messages/parser/roomsettings/RoomSettingsErrorParser.ts new file mode 100644 index 0000000..2e6723f --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/RoomSettingsErrorParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomSettingsErrorParser implements IMessageParser +{ + private _roomId: number; + private _code: number; + + public flush(): boolean + { + this._roomId = 0; + this._code = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._code = wrapper.readInt(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get code(): number + { + return this._code; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/RoomSettingsSaveErrorParser.ts b/packages/communication/src/messages/parser/roomsettings/RoomSettingsSaveErrorParser.ts new file mode 100644 index 0000000..aec5520 --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/RoomSettingsSaveErrorParser.ts @@ -0,0 +1,57 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class RoomSettingsSaveErrorParser implements IMessageParser +{ + public static ERROR_ROOM_NOT_FOUND: number = 1; + public static ERROR_NOT_OWNER: number = 2; + public static ERROR_INVALID_DOOR_MODE: number = 3; + public static ERROR_INVALID_USER_LIMIT: number = 4; + public static ERROR_INVALID_PASSWORD: number = 5; + public static ERROR_INVALID_CATEGORY: number = 6; + public static ERROR_INVALID_NAME: number = 7; + public static ERROR_UNACCEPTABLE_NAME: number = 8; + public static ERROR_INVALID_DESCRIPTION: number = 9; + public static ERROR_UNACCEPTABLE_DESCRIPTION: number = 10; + public static ERROR_INVALID_TAG: number = 11; + public static ERROR_NON_USER_CHOOSABLE_TAG: number = 12; + public static ERROR_TOO_MANY_CHARACTERS_IN_TAG: number = 13; + + 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; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/RoomSettingsSavedParser.ts b/packages/communication/src/messages/parser/roomsettings/RoomSettingsSavedParser.ts new file mode 100644 index 0000000..c8652a9 --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/RoomSettingsSavedParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/ShowEnforceRoomCategoryDialogParser.ts b/packages/communication/src/messages/parser/roomsettings/ShowEnforceRoomCategoryDialogParser.ts new file mode 100644 index 0000000..8d3a45a --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/ShowEnforceRoomCategoryDialogParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ShowEnforceRoomCategoryDialogParser implements IMessageParser +{ + private _selectionType: number; + + public flush(): boolean + { + this._selectionType = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._selectionType = wrapper.readInt(); + + return true; + } + + public get selectionType(): number + { + return this._selectionType; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/UserUnbannedFromRoomParser.ts b/packages/communication/src/messages/parser/roomsettings/UserUnbannedFromRoomParser.ts new file mode 100644 index 0000000..54fece8 --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/UserUnbannedFromRoomParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class UserUnbannedFromRoomParser implements IMessageParser +{ + private _roomId: number; + private _userId: number; + + public flush(): boolean + { + this._roomId = 0; + this._userId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._userId = wrapper.readInt(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get userId(): number + { + return this._userId; + } +} diff --git a/packages/communication/src/messages/parser/roomsettings/index.ts b/packages/communication/src/messages/parser/roomsettings/index.ts new file mode 100644 index 0000000..383ff7b --- /dev/null +++ b/packages/communication/src/messages/parser/roomsettings/index.ts @@ -0,0 +1,18 @@ +export * from './BannedUserData'; +export * from './BannedUsersFromRoomParser'; +export * from './FlatControllerAddedParser'; +export * from './FlatControllerData'; +export * from './FlatControllerRemovedParser'; +export * from './FlatControllersParser'; +export * from './IFlatUser'; +export * from './MuteAllInRoomParser'; +export * from './NoSuchFlatParser'; +export * from './RoomChatSettings'; +export * from './RoomModerationSettings'; +export * from './RoomSettingsData'; +export * from './RoomSettingsDataParser'; +export * from './RoomSettingsErrorParser'; +export * from './RoomSettingsSavedParser'; +export * from './RoomSettingsSaveErrorParser'; +export * from './ShowEnforceRoomCategoryDialogParser'; +export * from './UserUnbannedFromRoomParser'; diff --git a/packages/communication/src/messages/parser/security/AuthenticatedParser.ts b/packages/communication/src/messages/parser/security/AuthenticatedParser.ts new file mode 100644 index 0000000..12ec2d9 --- /dev/null +++ b/packages/communication/src/messages/parser/security/AuthenticatedParser.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class AuthenticatedParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} diff --git a/packages/communication/src/messages/parser/security/index.ts b/packages/communication/src/messages/parser/security/index.ts new file mode 100644 index 0000000..9ad83b5 --- /dev/null +++ b/packages/communication/src/messages/parser/security/index.ts @@ -0,0 +1 @@ +export * from './AuthenticatedParser'; diff --git a/packages/communication/src/messages/parser/sound/JukeboxPlayListFullMessageParser.ts b/packages/communication/src/messages/parser/sound/JukeboxPlayListFullMessageParser.ts new file mode 100644 index 0000000..53807ea --- /dev/null +++ b/packages/communication/src/messages/parser/sound/JukeboxPlayListFullMessageParser.ts @@ -0,0 +1,14 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class JukeboxPlayListFullMessageParser implements IMessageParser +{ + flush(): boolean + { + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + return true; + } +} diff --git a/packages/communication/src/messages/parser/sound/JukeboxSongDisksMessageParser.ts b/packages/communication/src/messages/parser/sound/JukeboxSongDisksMessageParser.ts new file mode 100644 index 0000000..83e306a --- /dev/null +++ b/packages/communication/src/messages/parser/sound/JukeboxSongDisksMessageParser.ts @@ -0,0 +1,38 @@ +import { IAdvancedMap, IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AdvancedMap } from '@nitrots/utils'; + +export class JukeboxSongDisksMessageParser implements IMessageParser +{ + private _songDisks: IAdvancedMap = new AdvancedMap(); + private _maxLength: number; + + flush(): boolean + { + this._songDisks.reset(); + this._maxLength = 0; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._maxLength = wrapper.readInt(); + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._songDisks.add(wrapper.readInt(), wrapper.readInt()); + } + + return true; + } + + public get songDisks(): IAdvancedMap + { + return this._songDisks; + } + + public get maxLength(): number + { + return this._maxLength; + } +} diff --git a/packages/communication/src/messages/parser/sound/NowPlayingMessageParser.ts b/packages/communication/src/messages/parser/sound/NowPlayingMessageParser.ts new file mode 100644 index 0000000..963f595 --- /dev/null +++ b/packages/communication/src/messages/parser/sound/NowPlayingMessageParser.ts @@ -0,0 +1,56 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class NowPlayingMessageParser implements IMessageParser +{ + private _currentSongId: number; + private _currentPosition: number; + private _nextSongId: number; + private _nextPosition: number; + private _syncCount: number; + + flush(): boolean + { + this._currentSongId = -1; + this._currentPosition = -1; + this._nextSongId = -1; + this._nextPosition = -1; + this._syncCount = -1; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._currentSongId = wrapper.readInt(); + this._currentPosition = wrapper.readInt(); + this._nextSongId = wrapper.readInt(); + this._nextPosition = wrapper.readInt(); + this._syncCount = wrapper.readInt(); + return true; + } + + public get currentSongId(): number + { + return this._currentSongId; + } + + public get currentPosition(): number + { + return this._currentPosition; + } + + public get nextSongId(): number + { + return this._nextSongId; + } + + public get nextPosition(): number + { + return this._nextPosition; + } + + public get syncCount(): number + { + return this._syncCount; + } + +} diff --git a/packages/communication/src/messages/parser/sound/OfficialSongIdMessageParser.ts b/packages/communication/src/messages/parser/sound/OfficialSongIdMessageParser.ts new file mode 100644 index 0000000..14d16b7 --- /dev/null +++ b/packages/communication/src/messages/parser/sound/OfficialSongIdMessageParser.ts @@ -0,0 +1,31 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class OfficialSongIdMessageParser implements IMessageParser +{ + private _songId: number; + private _officialSongId: string; + + flush(): boolean + { + this._songId = 0; + this._officialSongId = ''; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._officialSongId = wrapper.readString(); + this._songId = wrapper.readInt(); + return true; + } + + public get songId(): number + { + return this._songId; + } + + public get officialSongId(): string + { + return this._officialSongId; + } +} diff --git a/packages/communication/src/messages/parser/sound/PlayListEntry.ts b/packages/communication/src/messages/parser/sound/PlayListEntry.ts new file mode 100644 index 0000000..6a0f447 --- /dev/null +++ b/packages/communication/src/messages/parser/sound/PlayListEntry.ts @@ -0,0 +1,46 @@ +export class PlayListEntry +{ + protected _id: number; + protected _length: number; + protected _name: string; + protected _creator: string; + private _startPlayHead: number = 0; + + constructor(id: number, length: number, name: string, creator: string) + { + this._id = id; + this._length = length; + this._name = name; + this._creator = creator; + } + + public get id(): number + { + return this._id; + } + + public get length(): number + { + return this._length; + } + + public get name(): string + { + return this._name; + } + + public get creator(): string + { + return this._creator; + } + + public get startPlayHeadPos(): number + { + return this._startPlayHead; + } + + public set startPlayHeadPos(k: number) + { + this._startPlayHead = k; + } +} diff --git a/packages/communication/src/messages/parser/sound/PlayListMessageParser.ts b/packages/communication/src/messages/parser/sound/PlayListMessageParser.ts new file mode 100644 index 0000000..4b8c63f --- /dev/null +++ b/packages/communication/src/messages/parser/sound/PlayListMessageParser.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PlayListEntry } from './PlayListEntry'; + +export class PlayListMessageParser implements IMessageParser +{ + private _synchronizationCount: number; + private _playlist: PlayListEntry[]; + + flush(): boolean + { + this._synchronizationCount = -1; + this._playlist = []; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._synchronizationCount = wrapper.readInt(); + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._playlist.push(new PlayListEntry( + wrapper.readInt(), wrapper.readInt(), wrapper.readString(), wrapper.readString() + )); + } + return true; + } + + public get synchronizationCount(): number + { + return this._synchronizationCount; + } + + public get playList(): PlayListEntry[] + { + return this._playlist; + } + +} diff --git a/packages/communication/src/messages/parser/sound/PlayListSongAddedMessageParser.ts b/packages/communication/src/messages/parser/sound/PlayListSongAddedMessageParser.ts new file mode 100644 index 0000000..42294d8 --- /dev/null +++ b/packages/communication/src/messages/parser/sound/PlayListSongAddedMessageParser.ts @@ -0,0 +1,24 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { PlayListEntry } from './PlayListEntry'; + +export class PlayListSongAddedMessageParser implements IMessageParser +{ + private _entry: PlayListEntry; + + flush(): boolean + { + this._entry = null; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + this._entry = new PlayListEntry(wrapper.readInt(), wrapper.readInt(), wrapper.readString(), wrapper.readString()); + return true; + } + + public get entry(): PlayListEntry + { + return this._entry; + } +} diff --git a/packages/communication/src/messages/parser/sound/SongInfoEntry.ts b/packages/communication/src/messages/parser/sound/SongInfoEntry.ts new file mode 100644 index 0000000..0bef665 --- /dev/null +++ b/packages/communication/src/messages/parser/sound/SongInfoEntry.ts @@ -0,0 +1,17 @@ +import { PlayListEntry } from './PlayListEntry'; + +export class SongInfoEntry extends PlayListEntry +{ + private _data: string = ''; + + constructor(id: number, length: number, name: string, creator: string, data: string) + { + super(id, length, name, creator); + this._data = data; + } + + public get data(): string + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/sound/TraxSongInfoMessageParser.ts b/packages/communication/src/messages/parser/sound/TraxSongInfoMessageParser.ts new file mode 100644 index 0000000..cd51b32 --- /dev/null +++ b/packages/communication/src/messages/parser/sound/TraxSongInfoMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { SongInfoEntry } from './SongInfoEntry'; + +export class TraxSongInfoMessageParser implements IMessageParser +{ + private _songs: SongInfoEntry[]; + + flush(): boolean + { + this._songs = []; + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + const count = wrapper.readInt(); + for(let i = 0; i < count; i++) + { + const id = wrapper.readInt(); + const _local_3 = wrapper.readString(); + const name = wrapper.readString(); + const data = wrapper.readString(); + const length = wrapper.readInt(); + const creator = wrapper.readString(); + const _local_10 = new SongInfoEntry(id, length, name, creator, data); + this._songs.push(_local_10); + } + return true; + } + + public get songs(): SongInfoEntry[] + { + return this._songs; + } +} diff --git a/packages/communication/src/messages/parser/sound/UserSongDisksInventoryMessageParser.ts b/packages/communication/src/messages/parser/sound/UserSongDisksInventoryMessageParser.ts new file mode 100644 index 0000000..4d96630 --- /dev/null +++ b/packages/communication/src/messages/parser/sound/UserSongDisksInventoryMessageParser.ts @@ -0,0 +1,47 @@ +import { IAdvancedMap, IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AdvancedMap } from '@nitrots/utils'; + +export class UserSongDisksInventoryMessageParser implements IMessageParser +{ + private _songDiskInventory: IAdvancedMap = new AdvancedMap(); + + flush(): boolean + { + this._songDiskInventory.reset(); + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + const count = wrapper.readInt(); + + for(let i = 0; i < count; i++) + { + this._songDiskInventory.add(wrapper.readInt(), wrapper.readInt()); + } + return true; + } + + public getDiskId(k: number): number + { + if(((k >= 0) && (k < this._songDiskInventory.length))) + { + return this._songDiskInventory.getKey(k); + } + return -1; + } + + public getSongId(k: number): number + { + if(((k >= 0) && (k < this._songDiskInventory.length))) + { + return this._songDiskInventory.getWithIndex(k); + } + return -1; + } + + public get songDiskCount(): number + { + return this._songDiskInventory.length; + } +} diff --git a/packages/communication/src/messages/parser/sound/index.ts b/packages/communication/src/messages/parser/sound/index.ts new file mode 100644 index 0000000..2fc0d7a --- /dev/null +++ b/packages/communication/src/messages/parser/sound/index.ts @@ -0,0 +1,10 @@ +export * from './JukeboxPlayListFullMessageParser'; +export * from './JukeboxSongDisksMessageParser'; +export * from './NowPlayingMessageParser'; +export * from './OfficialSongIdMessageParser'; +export * from './PlayListEntry'; +export * from './PlayListMessageParser'; +export * from './PlayListSongAddedMessageParser'; +export * from './SongInfoEntry'; +export * from './TraxSongInfoMessageParser'; +export * from './UserSongDisksInventoryMessageParser'; diff --git a/packages/communication/src/messages/parser/talent/TalentLevelUpMessageParser.ts b/packages/communication/src/messages/parser/talent/TalentLevelUpMessageParser.ts new file mode 100644 index 0000000..18a6130 --- /dev/null +++ b/packages/communication/src/messages/parser/talent/TalentLevelUpMessageParser.ts @@ -0,0 +1,75 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { TalentTrackRewardPerk } from './TalentTrackRewardPerk'; +import { TalentTrackRewardProduct } from './TalentTrackRewardProduct'; + +export class TalentLevelUpMessageParser implements IMessageParser +{ + private _talentTrackName: string; + private _level: number; + private _rewardPerks: TalentTrackRewardPerk[]; + private _rewardProducts: TalentTrackRewardProduct[]; + + public flush(): boolean + { + this._talentTrackName = null; + this._level = -1; + this._rewardPerks = []; + this._rewardProducts = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalRewards = 0; + + this._talentTrackName = wrapper.readString(); + this._level = wrapper.readInt(); + + const totalRewardsPerks = wrapper.readInt(); + + while(totalRewards < totalRewardsPerks) + { + this._rewardPerks.push(new TalentTrackRewardPerk(wrapper)); + totalRewards++; + } + + const totalRewardsProducts = wrapper.readInt(); + + if(totalRewards < totalRewardsProducts) + { + for(let i = 0; i < totalRewardsProducts; i++) + { + const name = wrapper.readString(); + const vipDays = wrapper.readInt(); + + this._rewardProducts.push(new TalentTrackRewardProduct(name, vipDays)); + totalRewards++; + } + } + + return true; + } + + public get talentTrackName(): string + { + return this._talentTrackName; + } + + public get level(): number + { + return this._level; + } + + public get rewardPerks(): TalentTrackRewardPerk[] + { + return this._rewardPerks; + } + + public get rewardProducts(): TalentTrackRewardProduct[] + { + return this._rewardProducts; + } +} diff --git a/packages/communication/src/messages/parser/talent/TalentTrackLevel.ts b/packages/communication/src/messages/parser/talent/TalentTrackLevel.ts new file mode 100644 index 0000000..03a6eb0 --- /dev/null +++ b/packages/communication/src/messages/parser/talent/TalentTrackLevel.ts @@ -0,0 +1,45 @@ +import { TalentTrackRewardProduct } from './TalentTrackRewardProduct'; +import { TalentTrackTask } from './TalentTrackTask'; + +export class TalentTrackLevel +{ + private _level: number; + private _state: number; + private _tasks: TalentTrackTask[]; + private _rewardPerks: string[]; + private _rewardProducts: TalentTrackRewardProduct[]; + + constructor(level: number, state: number, achievements: TalentTrackTask[], perks: string[], items: TalentTrackRewardProduct[]) + { + this._level = level; + this._state = state; + this._tasks = achievements; + this._rewardPerks = perks; + this._rewardProducts = items; + } + + public get level(): number + { + return this._level; + } + + public get state(): number + { + return this._state; + } + + public get tasks(): TalentTrackTask[] + { + return this._tasks; + } + + public get perks(): string[] + { + return this._rewardPerks; + } + + public get items(): TalentTrackRewardProduct[] + { + return this._rewardProducts; + } +} diff --git a/packages/communication/src/messages/parser/talent/TalentTrackLevelMessageParser.ts b/packages/communication/src/messages/parser/talent/TalentTrackLevelMessageParser.ts new file mode 100644 index 0000000..b8f6cc2 --- /dev/null +++ b/packages/communication/src/messages/parser/talent/TalentTrackLevelMessageParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class TalentTrackLevelMessageParser implements IMessageParser +{ + private _talentTrackName: string; + private _level: number; + private _maxLevel: number; + + public flush(): boolean + { + this._talentTrackName = null; + this._level = -1; + this._maxLevel = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._talentTrackName = wrapper.readString(); + this._level = wrapper.readInt(); + this._maxLevel = wrapper.readInt(); + + return true; + } + + public get talentTrackName(): string + { + return this._talentTrackName; + } + + public get level(): number + { + return this._level; + } + + public get maxLevel(): number + { + return this._maxLevel; + } +} diff --git a/packages/communication/src/messages/parser/talent/TalentTrackParser.ts b/packages/communication/src/messages/parser/talent/TalentTrackParser.ts new file mode 100644 index 0000000..06297d4 --- /dev/null +++ b/packages/communication/src/messages/parser/talent/TalentTrackParser.ts @@ -0,0 +1,79 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { TalentTrackLevel } from './TalentTrackLevel'; +import { TalentTrackRewardProduct } from './TalentTrackRewardProduct'; +import { TalentTrackTask } from './TalentTrackTask'; + +export class TalentTrackParser implements IMessageParser +{ + private _type: string; + private _levels: TalentTrackLevel[]; + + public flush(): boolean + { + this._type = null; + this._levels = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._type = wrapper.readString(); + + this._levels = []; + const levelsCount = wrapper.readInt(); + + for(let i = 0; i < levelsCount; i++) + { + const levelId = wrapper.readInt(); + const levelState = wrapper.readInt(); + + const levelAchievements: TalentTrackTask[] = []; + const achievementsCount = wrapper.readInt(); + + for(let j = 0; j < achievementsCount; j++) + { + const id = wrapper.readInt(); + const index = wrapper.readInt(); + const code = wrapper.readString(); + const state = wrapper.readInt(); + const progress = wrapper.readInt(); + const achievementProgress = wrapper.readInt(); + + levelAchievements.push(new TalentTrackTask(id, index, code, state, progress, achievementProgress)); + } + + const levelPerks: string[] = []; + const perksCount = wrapper.readInt(); + + for(let j = 0; j < perksCount; j++) levelPerks.push(wrapper.readString()); + + const levelItems: TalentTrackRewardProduct[] = []; + const itemsCount = wrapper.readInt(); + + for(let j = 0; j < itemsCount; j++) + { + const name = wrapper.readString(); + const unknownInt = wrapper.readInt(); + + levelItems.push(new TalentTrackRewardProduct(name, unknownInt)); + } + + this._levels.push(new TalentTrackLevel(levelId, levelState, levelAchievements, levelPerks, levelItems)); + } + + return true; + } + + public get type(): string + { + return this._type; + } + + public get levels(): TalentTrackLevel[] + { + return this._levels; + } +} diff --git a/packages/communication/src/messages/parser/talent/TalentTrackRewardPerk.ts b/packages/communication/src/messages/parser/talent/TalentTrackRewardPerk.ts new file mode 100644 index 0000000..9a0cbd5 --- /dev/null +++ b/packages/communication/src/messages/parser/talent/TalentTrackRewardPerk.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class TalentTrackRewardPerk +{ + private _perkId: number; + + constructor(wrapper: IMessageDataWrapper) + { + this._perkId = wrapper.readInt(); + } + + public get perkId(): number + { + return this._perkId; + } +} diff --git a/packages/communication/src/messages/parser/talent/TalentTrackRewardProduct.ts b/packages/communication/src/messages/parser/talent/TalentTrackRewardProduct.ts new file mode 100644 index 0000000..d45c46d --- /dev/null +++ b/packages/communication/src/messages/parser/talent/TalentTrackRewardProduct.ts @@ -0,0 +1,21 @@ +export class TalentTrackRewardProduct +{ + private _productCode: string; + private _vipDays: number; + + constructor(name: string, vipDays: number) + { + this._productCode = name; + this._vipDays = vipDays; + } + + public get productCode(): string + { + return this._productCode; + } + + public get vipDays(): number + { + return this._vipDays; + } +} diff --git a/packages/communication/src/messages/parser/talent/TalentTrackTask.ts b/packages/communication/src/messages/parser/talent/TalentTrackTask.ts new file mode 100644 index 0000000..a249b11 --- /dev/null +++ b/packages/communication/src/messages/parser/talent/TalentTrackTask.ts @@ -0,0 +1,49 @@ +export class TalentTrackTask +{ + private _id: number; + private _requiredLevel: number; + private _badgeCode: string; + private _state: number; + private _currentScore: number; + private _totalScore: number; + + constructor(id: number, requiredLevel: number, badgeCode: string, state: number, currentScore: number, totalScore: number) + { + this._id = id; + this._requiredLevel = requiredLevel; + this._badgeCode = badgeCode; + this._state = state; + this._currentScore = currentScore; + this._totalScore = totalScore; + } + + public get id(): number + { + return this._id; + } + + public get requiredLevel(): number + { + return this._requiredLevel; + } + + public get badgeCode(): string + { + return this._badgeCode; + } + + public get state(): number + { + return this._state; + } + + public get currentScore(): number + { + return this._currentScore; + } + + public get totalScore(): number + { + return this._totalScore; + } +} diff --git a/packages/communication/src/messages/parser/talent/index.ts b/packages/communication/src/messages/parser/talent/index.ts new file mode 100644 index 0000000..d48e436 --- /dev/null +++ b/packages/communication/src/messages/parser/talent/index.ts @@ -0,0 +1,7 @@ +export * from './TalentLevelUpMessageParser'; +export * from './TalentTrackLevel'; +export * from './TalentTrackLevelMessageParser'; +export * from './TalentTrackParser'; +export * from './TalentTrackRewardPerk'; +export * from './TalentTrackRewardProduct'; +export * from './TalentTrackTask'; diff --git a/packages/communication/src/messages/parser/user/AccountSafetyLockStatusChangeParser.ts b/packages/communication/src/messages/parser/user/AccountSafetyLockStatusChangeParser.ts new file mode 100644 index 0000000..9c01c81 --- /dev/null +++ b/packages/communication/src/messages/parser/user/AccountSafetyLockStatusChangeParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class AccountSafetyLockStatusChangeParser implements IMessageParser +{ + public static SAFETY_LOCK_STATUS_LOCKED: number = 0; + public static SAFETY_LOCK_STATUS_UNLOCKED: number = 1; + + private _status: number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._status = wrapper.readInt(); + + return true; + } + + public get status(): number + { + return this._status; + } +} diff --git a/packages/communication/src/messages/parser/user/ApproveNameResultParser.ts b/packages/communication/src/messages/parser/user/ApproveNameResultParser.ts new file mode 100644 index 0000000..6ca40ca --- /dev/null +++ b/packages/communication/src/messages/parser/user/ApproveNameResultParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ApproveNameResultParser implements IMessageParser +{ + private _result: number; + private _validationInfo: string; + + public flush(): boolean + { + this._result = -1; + this._validationInfo = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._result = wrapper.readInt(); + this._validationInfo = wrapper.readString(); + + return true; + } + + public get result(): number + { + return this._result; + } + + public get validationInfo(): string + { + return this._validationInfo; + } +} diff --git a/packages/communication/src/messages/parser/user/ChangeEmailResultParser.ts b/packages/communication/src/messages/parser/user/ChangeEmailResultParser.ts new file mode 100644 index 0000000..3ac78fa --- /dev/null +++ b/packages/communication/src/messages/parser/user/ChangeEmailResultParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ChangeEmailResultParser implements IMessageParser +{ + public static readonly EMAIL_STATUS_OK: number = 0; + + private _result: number; + + public flush(): boolean + { + this._result = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._result = wrapper.readInt(); + + return true; + } + + public get result(): number + { + return this._result; + } +} diff --git a/packages/communication/src/messages/parser/user/EmailStatusParser.ts b/packages/communication/src/messages/parser/user/EmailStatusParser.ts new file mode 100644 index 0000000..765b235 --- /dev/null +++ b/packages/communication/src/messages/parser/user/EmailStatusParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class EmailStatusParser implements IMessageParser +{ + private _email: string; + private _isVerified: boolean; + private _allowChange: boolean; + + public flush(): boolean + { + this._email = null; + this._isVerified = false; + this._allowChange = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._email = wrapper.readString(); + this._isVerified = wrapper.readBoolean(); + this._allowChange = wrapper.readBoolean(); + + return true; + } + + public get email(): string + { + return this._email; + } + + public get isVerified(): boolean + { + return this._isVerified; + } + + public get allowChange(): boolean + { + return this._allowChange; + } +} diff --git a/packages/communication/src/messages/parser/user/ExtendedProfileChangedMessageParser.ts b/packages/communication/src/messages/parser/user/ExtendedProfileChangedMessageParser.ts new file mode 100644 index 0000000..41a54e5 --- /dev/null +++ b/packages/communication/src/messages/parser/user/ExtendedProfileChangedMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class ExtendedProfileChangedMessageParser implements IMessageParser +{ + private _userId: number; + + public flush(): boolean + { + this._userId = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userId = wrapper.readInt(); + + return true; + } + + public get userId(): number + { + return this._userId; + } +} diff --git a/packages/communication/src/messages/parser/user/GroupDetailsChangedMessageParser.ts b/packages/communication/src/messages/parser/user/GroupDetailsChangedMessageParser.ts new file mode 100644 index 0000000..adbe3b1 --- /dev/null +++ b/packages/communication/src/messages/parser/user/GroupDetailsChangedMessageParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GroupDetailsChangedMessageParser implements IMessageParser +{ + private _groupId: number; + + public flush(): boolean + { + this._groupId = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._groupId = wrapper.readInt(); + + return true; + } + + public get groupId(): number + { + return this._groupId; + } +} diff --git a/packages/communication/src/messages/parser/user/GroupMembershipRequestedMessageParser.ts b/packages/communication/src/messages/parser/user/GroupMembershipRequestedMessageParser.ts new file mode 100644 index 0000000..8140470 --- /dev/null +++ b/packages/communication/src/messages/parser/user/GroupMembershipRequestedMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { MemberData } from '../../incoming'; + +export class GroupMembershipRequestedMessageParser implements IMessageParser +{ + private _groupId: number; + private _requester: MemberData; + + public flush(): boolean + { + this._groupId = -1; + this._requester = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._groupId = wrapper.readInt(); + this._requester = new MemberData(wrapper); + + return true; + } + + public get groupId(): number + { + return this._groupId; + } + + public get requester(): MemberData + { + return this._requester; + } +} diff --git a/packages/communication/src/messages/parser/user/GuildEditFailedMessageParser.ts b/packages/communication/src/messages/parser/user/GuildEditFailedMessageParser.ts new file mode 100644 index 0000000..ba5af25 --- /dev/null +++ b/packages/communication/src/messages/parser/user/GuildEditFailedMessageParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuildEditFailedMessageParser implements IMessageParser +{ + public static readonly INSUFFICIENT_SUBSCRIPTION_LEVEL: number = 2; + + private _reason: number; + + public flush(): boolean + { + this._reason = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._reason = wrapper.readInt(); + + return true; + } + + public get reason(): number + { + return this._reason; + } +} diff --git a/packages/communication/src/messages/parser/user/GuildMemberMgmtFailedMessageParser.ts b/packages/communication/src/messages/parser/user/GuildMemberMgmtFailedMessageParser.ts new file mode 100644 index 0000000..cd206dc --- /dev/null +++ b/packages/communication/src/messages/parser/user/GuildMemberMgmtFailedMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class GuildMemberMgmtFailedMessageParser implements IMessageParser +{ + private _guildId: number; + private _reason: number; + + public flush(): boolean + { + this._guildId = -1; + this._reason = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._guildId = wrapper.readInt(); + this._reason = wrapper.readInt(); + + return true; + } + + public get guildId(): number + { + return this._guildId; + } + + public get reason(): number + { + return this._reason; + } +} diff --git a/packages/communication/src/messages/parser/user/GuildMembershipsMessageParser.ts b/packages/communication/src/messages/parser/user/GuildMembershipsMessageParser.ts new file mode 100644 index 0000000..6d73a9d --- /dev/null +++ b/packages/communication/src/messages/parser/user/GuildMembershipsMessageParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { HabboGroupEntryData } from './HabboGroupEntryData'; + +export class GuildMembershipsMessageParser implements IMessageParser +{ + private _groups: HabboGroupEntryData[]; + + 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 HabboGroupEntryData(wrapper)); + + totalOffers--; + } + + return true; + } + + public get groups(): HabboGroupEntryData[] + { + return this._groups; + } +} diff --git a/packages/communication/src/messages/parser/user/HabboGroupBadgesMessageParser.ts b/packages/communication/src/messages/parser/user/HabboGroupBadgesMessageParser.ts new file mode 100644 index 0000000..aafef6d --- /dev/null +++ b/packages/communication/src/messages/parser/user/HabboGroupBadgesMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class HabboGroupBadgesMessageParser implements IMessageParser +{ + private _badges: Map; + + flush(): boolean + { + this._badges = new Map(); + + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let badgesCount = wrapper.readInt(); + + while(badgesCount > 0) + { + const id = wrapper.readInt(); + const badge = wrapper.readString(); + + this._badges.set(id, badge); + badgesCount--; + } + + return true; + } + + public get badges(): Map + { + return this._badges; + } +} diff --git a/packages/communication/src/messages/parser/user/HabboGroupEntryData.ts b/packages/communication/src/messages/parser/user/HabboGroupEntryData.ts new file mode 100644 index 0000000..9882f43 --- /dev/null +++ b/packages/communication/src/messages/parser/user/HabboGroupEntryData.ts @@ -0,0 +1,65 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class HabboGroupEntryData +{ + private _groupId: number; + private _groupName: string; + private _badgeCode: string; + private _colorA: string; + private _colorB: string; + private _favourite: boolean; + private _ownerId: number; + private _hasForum: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + this._groupId = wrapper.readInt(); + this._groupName = wrapper.readString(); + this._badgeCode = wrapper.readString(); + this._colorA = wrapper.readString(); + this._colorB = wrapper.readString(); + this._favourite = wrapper.readBoolean(); + this._ownerId = wrapper.readInt(); + this._hasForum = wrapper.readBoolean(); + } + + public get groupId(): number + { + return this._groupId; + } + + public get groupName(): string + { + return this._groupName; + } + + public get badgeCode(): string + { + return this._badgeCode; + } + + public get colorA(): string + { + return this._colorA; + } + + public get colorB(): string + { + return this._colorB; + } + + public get favourite(): boolean + { + return this._favourite; + } + + public get ownerId(): number + { + return this._ownerId; + } + + public get hasForum(): boolean + { + return this._hasForum; + } +} diff --git a/packages/communication/src/messages/parser/user/HabboGroupJoinFailedMessageParser.ts b/packages/communication/src/messages/parser/user/HabboGroupJoinFailedMessageParser.ts new file mode 100644 index 0000000..62241b2 --- /dev/null +++ b/packages/communication/src/messages/parser/user/HabboGroupJoinFailedMessageParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class HabboGroupJoinFailedMessageParser implements IMessageParser +{ + public static readonly INSUFFICIENT_SUBSCRIPTION_LEVEL: number = 4; + + private _reason: number; + + public flush(): boolean + { + this._reason = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._reason = wrapper.readInt(); + + return true; + } + + public get reason(): number + { + return this._reason; + } +} diff --git a/packages/communication/src/messages/parser/user/IgnoreResultParser.ts b/packages/communication/src/messages/parser/user/IgnoreResultParser.ts new file mode 100644 index 0000000..b180635 --- /dev/null +++ b/packages/communication/src/messages/parser/user/IgnoreResultParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/user/IgnoredUsersParser.ts b/packages/communication/src/messages/parser/user/IgnoredUsersParser.ts new file mode 100644 index 0000000..6420927 --- /dev/null +++ b/packages/communication/src/messages/parser/user/IgnoredUsersParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/user/InClientLinkParser.ts b/packages/communication/src/messages/parser/user/InClientLinkParser.ts new file mode 100644 index 0000000..e48f4b5 --- /dev/null +++ b/packages/communication/src/messages/parser/user/InClientLinkParser.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/user/PetRespectNotificationParser.ts b/packages/communication/src/messages/parser/user/PetRespectNotificationParser.ts new file mode 100644 index 0000000..631c851 --- /dev/null +++ b/packages/communication/src/messages/parser/user/PetRespectNotificationParser.ts @@ -0,0 +1,49 @@ +import { IMessageDataWrapper, IMessageParser, PetType } from '@nitrots/api'; +import { PetData } from '../inventory'; + +export class PetRespectNotificationParser implements IMessageParser +{ + private _respect: number; + private _petOwnerId: number; + private _petData: PetData; + + public flush(): boolean + { + this._respect = 0; + this._petOwnerId = 0; + this._petData = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._respect = wrapper.readInt(); + this._petOwnerId = wrapper.readInt(); + this._petData = new PetData(wrapper); + + return true; + } + + public get respect(): number + { + return this._respect; + } + + public get petOwnerId(): number + { + return this._petOwnerId; + } + + public get petData(): PetData + { + return this._petData; + } + + public get isTreat(): boolean + { + return (this._petData.typeId === PetType.MONSTERPLANT); + } +} diff --git a/packages/communication/src/messages/parser/user/PetSupplementTypeEnum.ts b/packages/communication/src/messages/parser/user/PetSupplementTypeEnum.ts new file mode 100644 index 0000000..d111209 --- /dev/null +++ b/packages/communication/src/messages/parser/user/PetSupplementTypeEnum.ts @@ -0,0 +1,8 @@ +export class PetSupplementTypeEnum +{ + public static WATER: number = 0; + public static LIGHT: number = 1; + public static REVIVE: number = 2; + public static REBREED_FERTILIZER: number = 3; + public static SPEED_FERTILIZER: number = 4; +} diff --git a/packages/communication/src/messages/parser/user/PetSupplementedNotificationParser.ts b/packages/communication/src/messages/parser/user/PetSupplementedNotificationParser.ts new file mode 100644 index 0000000..3c22f1d --- /dev/null +++ b/packages/communication/src/messages/parser/user/PetSupplementedNotificationParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class PetSupplementedNotificationParser implements IMessageParser +{ + private _petId: number; + private _userId: number; + private _supplementType: number; + + public flush(): boolean + { + this._petId = 0; + this._userId = 0; + this._supplementType = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._petId = wrapper.readInt(); + this._userId = wrapper.readInt(); + this._supplementType = wrapper.readInt(); + + return true; + } + + public get petId(): number + { + return this._petId; + } + + public get userId(): number + { + return this._userId; + } + + public get supplementType(): number + { + return this._supplementType; + } +} diff --git a/packages/communication/src/messages/parser/user/RespectReceivedParser.ts b/packages/communication/src/messages/parser/user/RespectReceivedParser.ts new file mode 100644 index 0000000..15527b4 --- /dev/null +++ b/packages/communication/src/messages/parser/user/RespectReceivedParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/user/RoomEntryData.ts b/packages/communication/src/messages/parser/user/RoomEntryData.ts new file mode 100644 index 0000000..4f9ee0b --- /dev/null +++ b/packages/communication/src/messages/parser/user/RoomEntryData.ts @@ -0,0 +1,28 @@ +export class RoomEntryData +{ + private _roomId: number; + private _roomName: string; + private _hasControllers: boolean = false; + + constructor(roomId: number, roomName: string, hasControllers: boolean) + { + this._roomId = roomId; + this._roomName = roomName; + this._hasControllers = hasControllers; + } + + public get roomId(): number + { + return this._roomId; + } + + public get roomName(): string + { + return this._roomName; + } + + public get hasControllers(): boolean + { + return this._hasControllers; + } +} diff --git a/packages/communication/src/messages/parser/user/ScrKickbackData.ts b/packages/communication/src/messages/parser/user/ScrKickbackData.ts new file mode 100644 index 0000000..d95900d --- /dev/null +++ b/packages/communication/src/messages/parser/user/ScrKickbackData.ts @@ -0,0 +1,72 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +export class ScrKickbackData +{ + private _currentHcStreak: number; + private _firstSubscriptionDate: string; + private _kickbackPercentage: number; + private _totalCreditsMissed: number; + private _totalCreditsRewarded: number; + private _totalCreditsSpent: number; + private _creditRewardForStreakBonus: number; + private _creditRewardForMonthlySpent: number; + private _timeUntilPayday: number; + + constructor(k: IMessageDataWrapper) + { + this._currentHcStreak = k.readInt(); + this._firstSubscriptionDate = k.readString(); + this._kickbackPercentage = k.readDouble(); + this._totalCreditsMissed = k.readInt(); + this._totalCreditsRewarded = k.readInt(); + this._totalCreditsSpent = k.readInt(); + this._creditRewardForStreakBonus = k.readInt(); + this._creditRewardForMonthlySpent = k.readInt(); + this._timeUntilPayday = k.readInt(); + } + + public get currentHcStreak(): number + { + return this._currentHcStreak; + } + + public get firstSubscriptionDate(): string + { + return this._firstSubscriptionDate; + } + + public get kickbackPercentage(): number + { + return this._kickbackPercentage; + } + + public get totalCreditsMissed(): number + { + return this._totalCreditsMissed; + } + + public get totalCreditsRewarded(): number + { + return this._totalCreditsRewarded; + } + + public get totalCreditsSpent(): number + { + return this._totalCreditsSpent; + } + + public get creditRewardForStreakBonus(): number + { + return this._creditRewardForStreakBonus; + } + + public get creditRewardForMonthlySpent(): number + { + return this._creditRewardForMonthlySpent; + } + + public get timeUntilPayday(): number + { + return this._timeUntilPayday; + } +} diff --git a/packages/communication/src/messages/parser/user/ScrSendKickbackInfoMessageParser.ts b/packages/communication/src/messages/parser/user/ScrSendKickbackInfoMessageParser.ts new file mode 100644 index 0000000..0af2fa4 --- /dev/null +++ b/packages/communication/src/messages/parser/user/ScrSendKickbackInfoMessageParser.ts @@ -0,0 +1,23 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { ScrKickbackData } from './ScrKickbackData'; + +export class ScrSendKickbackInfoMessageParser implements IMessageParser +{ + private _data: ScrKickbackData; + + flush(): boolean + { + this._data = null; + return true; + } + parse(wrapper: IMessageDataWrapper): boolean + { + this._data = new ScrKickbackData(wrapper); + return true; + } + + public get data(): ScrKickbackData + { + return this._data; + } +} diff --git a/packages/communication/src/messages/parser/user/WelcomeGiftChangeEmailResultParser.ts b/packages/communication/src/messages/parser/user/WelcomeGiftChangeEmailResultParser.ts new file mode 100644 index 0000000..7167010 --- /dev/null +++ b/packages/communication/src/messages/parser/user/WelcomeGiftChangeEmailResultParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class WelcomeGiftChangeEmailResultParser implements IMessageParser +{ + private _result: number; + + public flush(): boolean + { + this._result = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._result = wrapper.readInt(); + + return true; + } + + public get result(): number + { + return this._result; + } +} diff --git a/packages/communication/src/messages/parser/user/access/UserPermissionsParser.ts b/packages/communication/src/messages/parser/user/access/UserPermissionsParser.ts new file mode 100644 index 0000000..4f40f45 --- /dev/null +++ b/packages/communication/src/messages/parser/user/access/UserPermissionsParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/user/access/index.ts b/packages/communication/src/messages/parser/user/access/index.ts new file mode 100644 index 0000000..7cb9b64 --- /dev/null +++ b/packages/communication/src/messages/parser/user/access/index.ts @@ -0,0 +1 @@ +export * from './UserPermissionsParser'; diff --git a/packages/communication/src/messages/parser/user/data/RelationshipStatusInfo.ts b/packages/communication/src/messages/parser/user/data/RelationshipStatusInfo.ts new file mode 100644 index 0000000..f13baac --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/RelationshipStatusInfo.ts @@ -0,0 +1,67 @@ +import { IMessageDataWrapper, RelationshipStatusEnum } from '@nitrots/api'; + +export class RelationshipStatusInfo +{ + private _relationshipStatusType: number; + private _friendCount: number; + private _randomFriendId: number; + private _randomFriendName: string; + private _randomFriendFigure: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._relationshipStatusType = RelationshipStatusEnum.NONE; + this._friendCount = 0; + this._randomFriendId = 0; + this._randomFriendFigure = null; + this._randomFriendName = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._relationshipStatusType = wrapper.readInt(); + this._friendCount = wrapper.readInt(); + this._randomFriendId = wrapper.readInt(); + this._randomFriendName = wrapper.readString(); + this._randomFriendFigure = wrapper.readString(); + + return true; + } + + public get relationshipStatusType(): number + { + return this._relationshipStatusType; + } + + public get friendCount(): number + { + return this._friendCount; + } + + public get randomFriendId(): number + { + return this._randomFriendId; + } + + public get randomFriendName(): string + { + return this._randomFriendName; + } + + public get randomFriendFigure(): string + { + return this._randomFriendFigure; + } +} diff --git a/packages/communication/src/messages/parser/user/data/RelationshipStatusInfoMessageParser.ts b/packages/communication/src/messages/parser/user/data/RelationshipStatusInfoMessageParser.ts new file mode 100644 index 0000000..dda716a --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/RelationshipStatusInfoMessageParser.ts @@ -0,0 +1,46 @@ +import { IAdvancedMap, IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { AdvancedMap } from '@nitrots/utils'; +import { RelationshipStatusInfo } from './RelationshipStatusInfo'; + +export class RelationshipStatusInfoMessageParser implements IMessageParser +{ + private _userId: number; + private _relationshipStatusMap: IAdvancedMap; + + public flush(): boolean + { + this._userId = 0; + this._relationshipStatusMap = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userId = wrapper.readInt(); + this._relationshipStatusMap = new AdvancedMap(); + + const relationshipsCount = wrapper.readInt(); + + for(let i = 0; i < relationshipsCount; i++) + { + const relationship = new RelationshipStatusInfo(wrapper); + + this._relationshipStatusMap.add(relationship.relationshipStatusType, relationship); + } + + return true; + } + + public get userId(): number + { + return this._userId; + } + + public get relationshipStatusMap(): IAdvancedMap + { + return this._relationshipStatusMap; + } +} diff --git a/packages/communication/src/messages/parser/user/data/UserCurrentBadgesParser.ts b/packages/communication/src/messages/parser/user/data/UserCurrentBadgesParser.ts new file mode 100644 index 0000000..e794704 --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/UserCurrentBadgesParser.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/user/data/UserFigureParser.ts b/packages/communication/src/messages/parser/user/data/UserFigureParser.ts new file mode 100644 index 0000000..88a61a9 --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/UserFigureParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/user/data/UserInfoDataParser.ts b/packages/communication/src/messages/parser/user/data/UserInfoDataParser.ts new file mode 100644 index 0000000..559848e --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/UserInfoDataParser.ts @@ -0,0 +1,139 @@ +import { IMessageDataWrapper } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/user/data/UserInfoParser.ts b/packages/communication/src/messages/parser/user/data/UserInfoParser.ts new file mode 100644 index 0000000..387d601 --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/UserInfoParser.ts @@ -0,0 +1,30 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +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; + } +} diff --git a/packages/communication/src/messages/parser/user/data/UserNameChangeMessageParser.ts b/packages/communication/src/messages/parser/user/data/UserNameChangeMessageParser.ts new file mode 100644 index 0000000..33ce7eb --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/UserNameChangeMessageParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/user/data/UserProfileParser.ts b/packages/communication/src/messages/parser/user/data/UserProfileParser.ts new file mode 100644 index 0000000..5abb303 --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/UserProfileParser.ts @@ -0,0 +1,130 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; +import { HabboGroupEntryData } from '../HabboGroupEntryData'; + +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: HabboGroupEntryData[]; + private _secondsSinceLastVisit: number; + private _openProfileWindow: boolean; + + 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._secondsSinceLastVisit = 0; + this._openProfileWindow = false; + + 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(); + const groupsCount = wrapper.readInt(); + + for(let i = 0; i < groupsCount; i++) + { + this._groups.push(new HabboGroupEntryData(wrapper)); + } + + this._secondsSinceLastVisit = wrapper.readInt(); + this._openProfileWindow = wrapper.readBoolean(); + + 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(): HabboGroupEntryData[] + { + return this._groups; + } + + public get secondsSinceLastVisit(): number + { + return this._secondsSinceLastVisit; + } + + public get openProfileWindow(): boolean + { + return this._openProfileWindow; + } +} diff --git a/packages/communication/src/messages/parser/user/data/UserSettingsParser.ts b/packages/communication/src/messages/parser/user/data/UserSettingsParser.ts new file mode 100644 index 0000000..8283e45 --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/UserSettingsParser.ts @@ -0,0 +1,83 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/user/data/UserTagsParser.ts b/packages/communication/src/messages/parser/user/data/UserTagsParser.ts new file mode 100644 index 0000000..188ebd4 --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/UserTagsParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class UserTagsParser implements IMessageParser +{ + private _roomUnitId: number; + private _tags: string[]; + + public flush(): boolean + { + this._roomUnitId = -1; + this._tags = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomUnitId = wrapper.readInt(); + + let totalTags = wrapper.readInt(); + + while(totalTags > 0) + { + this._tags.push(wrapper.readString()); + + totalTags--; + } + + return true; + } + + public get roomUnitId(): number + { + return this._roomUnitId; + } + + public get tags(): string[] + { + return this._tags; + } +} diff --git a/packages/communication/src/messages/parser/user/data/index.ts b/packages/communication/src/messages/parser/user/data/index.ts new file mode 100644 index 0000000..ad707bf --- /dev/null +++ b/packages/communication/src/messages/parser/user/data/index.ts @@ -0,0 +1,10 @@ +export * from './RelationshipStatusInfo'; +export * from './RelationshipStatusInfoMessageParser'; +export * from './UserCurrentBadgesParser'; +export * from './UserFigureParser'; +export * from './UserInfoDataParser'; +export * from './UserInfoParser'; +export * from './UserNameChangeMessageParser'; +export * from './UserProfileParser'; +export * from './UserSettingsParser'; +export * from './UserTagsParser'; diff --git a/packages/communication/src/messages/parser/user/index.ts b/packages/communication/src/messages/parser/user/index.ts new file mode 100644 index 0000000..82dfb33 --- /dev/null +++ b/packages/communication/src/messages/parser/user/index.ts @@ -0,0 +1,30 @@ +export * from './access'; +export * from './AccountSafetyLockStatusChangeParser'; +export * from './ApproveNameResultParser'; +export * from './ChangeEmailResultParser'; +export * from './data'; +export * from './EmailStatusParser'; +export * from './ExtendedProfileChangedMessageParser'; +export * from './GroupDetailsChangedMessageParser'; +export * from './GroupMembershipRequestedMessageParser'; +export * from './GuildEditFailedMessageParser'; +export * from './GuildMemberMgmtFailedMessageParser'; +export * from './GuildMembershipsMessageParser'; +export * from './HabboGroupBadgesMessageParser'; +export * from './HabboGroupEntryData'; +export * from './HabboGroupJoinFailedMessageParser'; +export * from './IgnoredUsersParser'; +export * from './IgnoreResultParser'; +export * from './InClientLinkParser'; +export * from './inventory'; +export * from './inventory/currency'; +export * from './inventory/subscription'; +export * from './PetRespectNotificationParser'; +export * from './PetSupplementedNotificationParser'; +export * from './PetSupplementTypeEnum'; +export * from './RespectReceivedParser'; +export * from './RoomEntryData'; +export * from './ScrKickbackData'; +export * from './ScrSendKickbackInfoMessageParser'; +export * from './wardrobe'; +export * from './WelcomeGiftChangeEmailResultParser'; diff --git a/packages/communication/src/messages/parser/user/inventory/currency/UserCreditsParser.ts b/packages/communication/src/messages/parser/user/inventory/currency/UserCreditsParser.ts new file mode 100644 index 0000000..c9ed9b1 --- /dev/null +++ b/packages/communication/src/messages/parser/user/inventory/currency/UserCreditsParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/user/inventory/currency/UserCurrencyParser.ts b/packages/communication/src/messages/parser/user/inventory/currency/UserCurrencyParser.ts new file mode 100644 index 0000000..38e8403 --- /dev/null +++ b/packages/communication/src/messages/parser/user/inventory/currency/UserCurrencyParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/communication/src/messages/parser/user/inventory/currency/index.ts b/packages/communication/src/messages/parser/user/inventory/currency/index.ts new file mode 100644 index 0000000..a6e0537 --- /dev/null +++ b/packages/communication/src/messages/parser/user/inventory/currency/index.ts @@ -0,0 +1,2 @@ +export * from './UserCreditsParser'; +export * from './UserCurrencyParser'; diff --git a/packages/communication/src/messages/parser/user/inventory/index.ts b/packages/communication/src/messages/parser/user/inventory/index.ts new file mode 100644 index 0000000..e25bf08 --- /dev/null +++ b/packages/communication/src/messages/parser/user/inventory/index.ts @@ -0,0 +1,2 @@ +export * from './currency'; +export * from './subscription'; diff --git a/packages/communication/src/messages/parser/user/inventory/subscription/UserSubscriptionParser.ts b/packages/communication/src/messages/parser/user/inventory/subscription/UserSubscriptionParser.ts new file mode 100644 index 0000000..34e8ed2 --- /dev/null +++ b/packages/communication/src/messages/parser/user/inventory/subscription/UserSubscriptionParser.ts @@ -0,0 +1,113 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class UserSubscriptionParser implements IMessageParser +{ + public static readonly RESPONSE_TYPE_LOGIN: number = 1; + public static readonly RESPONSE_TYPE_PURCHASE: number = 2; + public static readonly RESPONSE_TYPE_DISCOUNT_AVAILABLE: number = 3; + public static readonly RESPONSE_TYPE_CITIZENSHIP_DISCOUNT: number = 4; + + private _productName: string; + private _daysToPeriodEnd: number; + private _memberPeriods: number; + private _periodsSubscribedAhead: number; + private _responseType: number; + private _hasEverBeenMember: boolean; + private _isVip: boolean; + private _pastClubDays: number; + private _pastVipDays: number; + private _minutesUntilExpiration: number; + private _minutesSinceLastModified: number; + + public flush(): boolean + { + this._productName = null; + this._daysToPeriodEnd = 0; + this._memberPeriods = 0; + this._periodsSubscribedAhead = 0; + this._responseType = 0; + this._hasEverBeenMember = false; + this._isVip = false; + this._pastClubDays = 0; + this._pastVipDays = 0; + this._minutesUntilExpiration = 0; + this._minutesSinceLastModified = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._productName = wrapper.readString(); + this._daysToPeriodEnd = wrapper.readInt(); + this._memberPeriods = wrapper.readInt(); + this._periodsSubscribedAhead = wrapper.readInt(); + this._responseType = wrapper.readInt(); + this._hasEverBeenMember = wrapper.readBoolean(); + this._isVip = wrapper.readBoolean(); + this._pastClubDays = wrapper.readInt(); + this._pastVipDays = wrapper.readInt(); + this._minutesUntilExpiration = wrapper.readInt(); + + if(wrapper.bytesAvailable) this._minutesSinceLastModified = wrapper.readInt(); + + return true; + } + + public get productName(): string + { + return this._productName; + } + + public get daysToPeriodEnd(): number + { + return this._daysToPeriodEnd; + } + + public get memberPeriods(): number + { + return this._memberPeriods; + } + + public get periodsSubscribedAhead(): number + { + return this._periodsSubscribedAhead; + } + + public get responseType(): number + { + return this._responseType; + } + + 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 minutesUntilExpiration(): number + { + return this._minutesUntilExpiration; + } + + public get minutesSinceLastModified(): number + { + return this._minutesSinceLastModified; + } +} diff --git a/packages/communication/src/messages/parser/user/inventory/subscription/index.ts b/packages/communication/src/messages/parser/user/inventory/subscription/index.ts new file mode 100644 index 0000000..e88ac0d --- /dev/null +++ b/packages/communication/src/messages/parser/user/inventory/subscription/index.ts @@ -0,0 +1 @@ +export * from './UserSubscriptionParser'; diff --git a/packages/communication/src/messages/parser/user/wardrobe/UserWardrobePageParser.ts b/packages/communication/src/messages/parser/user/wardrobe/UserWardrobePageParser.ts new file mode 100644 index 0000000..d8762bb --- /dev/null +++ b/packages/communication/src/messages/parser/user/wardrobe/UserWardrobePageParser.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +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/packages/communication/src/messages/parser/user/wardrobe/index.ts b/packages/communication/src/messages/parser/user/wardrobe/index.ts new file mode 100644 index 0000000..a2878b4 --- /dev/null +++ b/packages/communication/src/messages/parser/user/wardrobe/index.ts @@ -0,0 +1 @@ +export * from './UserWardrobePageParser'; diff --git a/packages/communication/src/messages/parser/userclassification/UserClassificationMessageParser.ts b/packages/communication/src/messages/parser/userclassification/UserClassificationMessageParser.ts new file mode 100644 index 0000000..0900b0f --- /dev/null +++ b/packages/communication/src/messages/parser/userclassification/UserClassificationMessageParser.ts @@ -0,0 +1,57 @@ +import { IMessageDataWrapper, IMessageParser } from '@nitrots/api'; + +export class UserClassificationMessageParser implements IMessageParser +{ + private _classifiedUsersNames: Map; + private _classifiedUsersClass: Map; + + public flush(): boolean + { + if(this._classifiedUsersNames) + { + this._classifiedUsersNames = new Map(); + } + if(this._classifiedUsersClass) + { + this._classifiedUsersClass = new Map(); + } + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let _local_3: number; + let _local_4: string; + let _local_5: string; + + let count: number = wrapper.readInt(); + + this._classifiedUsersNames = new Map(); + this._classifiedUsersClass = new Map(); + + while(count > 0) + { + _local_3 = wrapper.readInt(); + _local_4 = wrapper.readString(); + _local_5 = wrapper.readString(); + this._classifiedUsersNames.set(_local_3, _local_4); + this._classifiedUsersClass.set(_local_3, _local_5); + count--; + } + + return true; + } + + public get classifiedUsernameMap(): Map + { + return this._classifiedUsersNames; + } + + public get classifiedUserTypeMap(): Map + { + return this._classifiedUsersClass; + } +} diff --git a/packages/communication/src/messages/parser/userclassification/index.ts b/packages/communication/src/messages/parser/userclassification/index.ts new file mode 100644 index 0000000..8779e98 --- /dev/null +++ b/packages/communication/src/messages/parser/userclassification/index.ts @@ -0,0 +1 @@ +export * from './UserClassificationMessageParser'; diff --git a/packages/communication/tsconfig.json b/packages/communication/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/communication/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/configuration/.eslintrc.json b/packages/configuration/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/configuration/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/configuration/.gitignore b/packages/configuration/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/configuration/.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/packages/configuration/index.ts b/packages/configuration/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/configuration/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/configuration/package.json b/packages/configuration/package.json new file mode 100644 index 0000000..7cef9c2 --- /dev/null +++ b/packages/configuration/package.json @@ -0,0 +1,20 @@ +{ + "name": "@nitrots/configuration", + "description": "Nitro configuration module", + "version": "1.0.0", + "type": "module", + "license": "GPL-3.0", + "scripts": { + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "@nitrots/utils": "1.0.0" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/configuration/src/ConfigurationManager.ts b/packages/configuration/src/ConfigurationManager.ts new file mode 100644 index 0000000..a72a04a --- /dev/null +++ b/packages/configuration/src/ConfigurationManager.ts @@ -0,0 +1,167 @@ +import { NitroLogger, NitroVersion } from '@nitrots/utils'; +import { IConfigurationManager } from './IConfigurationManager'; + +export class ConfigurationManager implements IConfigurationManager +{ + private _definitions: Map = new Map(); + private _config: any = {}; + private _missingKeys: string[] = []; + + constructor() + { + NitroVersion.sayHello(); + } + + public async init(): Promise + { + await this.reloadConfiguration(); + } + + public async reloadConfiguration(): Promise + { + try + { + this.resetConfiguration(); + this.parseConfiguration(this.getDefaultConfig(), true); + + const configurationUrls = this.getValue('config.urls').slice(); + + if(!configurationUrls || !configurationUrls.length) throw new Error('Invalid configuration urls'); + + for(const url of configurationUrls) + { + if(!url || !url.length) return; + + const response = await fetch(url); + + if(response.status !== 200) throw new Error('Invalid configuration file'); + + this.parseConfiguration(await response.json()); + } + } + + catch (err) + { + throw new Error(err); + } + } + + public resetConfiguration(): void + { + this._definitions.clear(); + this._config = {}; + this._missingKeys = []; + } + + public parseConfiguration(data: { [index: string]: any }, overrides: boolean = false): 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); + + if(this._definitions.has(key)) + { + if(overrides) this.setValue(key, value); + } + else + { + this.setValue(key, value); + } + } + + return true; + } + + catch (e) + { + NitroLogger.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.get(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.get(key); + + if(existing === undefined) + { + if(this._missingKeys.indexOf(key) >= 0) return value; + + this._missingKeys.push(key); + + NitroLogger.warn(`Missing configuration key: ${key}`); + + existing = value; + } + + return (existing as T); + } + + public setValue(key: string, value: T): void + { + const parts = key.split('.'); + + let last = this._config; + + for(let i = 0; i < parts.length; i++) + { + const part = parts[i].toString(); + + if(i !== (parts.length - 1)) + { + if(!last[part]) last[part] = {}; + + last = last[part]; + + continue; + } + + last[part] = value; + } + + this._definitions.set(key, value); + } + + public getDefaultConfig(): { [index: string]: any } + { + return window.NitroConfig; + } + + public get definitions(): Map + { + return this._definitions; + } +} diff --git a/packages/configuration/src/GetConfiguration.ts b/packages/configuration/src/GetConfiguration.ts new file mode 100644 index 0000000..bcf539b --- /dev/null +++ b/packages/configuration/src/GetConfiguration.ts @@ -0,0 +1,6 @@ +import { ConfigurationManager } from './ConfigurationManager'; +import { IConfigurationManager } from './IConfigurationManager'; + +const configuration = new ConfigurationManager(); + +export const GetConfiguration = (): IConfigurationManager => configuration; diff --git a/packages/configuration/src/IConfigurationManager.ts b/packages/configuration/src/IConfigurationManager.ts new file mode 100644 index 0000000..0b2f5cc --- /dev/null +++ b/packages/configuration/src/IConfigurationManager.ts @@ -0,0 +1,12 @@ +export interface IConfigurationManager +{ + init(): Promise; + reloadConfiguration(): Promise; + resetConfiguration(): void; + parseConfiguration(data: { [index: string]: any }, overrides?: boolean): boolean; + interpolate(value: string, regex?: RegExp): string; + getValue(key: string, value?: T): T; + setValue(key: string, value: T): void; + getDefaultConfig(): { [index: string]: any }; + readonly definitions: Map; +} diff --git a/packages/configuration/src/index.ts b/packages/configuration/src/index.ts new file mode 100644 index 0000000..0f73df7 --- /dev/null +++ b/packages/configuration/src/index.ts @@ -0,0 +1,3 @@ +export * from './ConfigurationManager'; +export * from './GetConfiguration'; +export * from './IConfigurationManager'; diff --git a/packages/configuration/tsconfig.json b/packages/configuration/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/configuration/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/eslint-config/.eslintrc.json b/packages/eslint-config/.eslintrc.json new file mode 100644 index 0000000..1a4901d --- /dev/null +++ b/packages/eslint-config/.eslintrc.json @@ -0,0 +1,128 @@ +{ + "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-multi-spaces": [ + "error" + ], + "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/ban-types": [ + "error", + { + "types": + { + "String": true, + "Boolean": true, + "Number": true, + "Symbol": true, + "{}": false, + "Object": false, + "object": false, + "Function": false + }, + "extendDefaults": true + } + ] + } +} diff --git a/packages/eslint-config/.gitignore b/packages/eslint-config/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/eslint-config/.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/packages/eslint-config/index.js b/packages/eslint-config/index.js new file mode 100644 index 0000000..3b07596 --- /dev/null +++ b/packages/eslint-config/index.js @@ -0,0 +1 @@ +module.exports = require('./.eslintrc.json'); diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json new file mode 100644 index 0000000..68d987d --- /dev/null +++ b/packages/eslint-config/package.json @@ -0,0 +1,15 @@ +{ + "name": "@nitrots/eslint-config", + "description": "Nitro eslint configs", + "version": "1.0.0", + "license": "GPL-3.0", + "main": "./index", + "dependencies": { + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", + "eslint": "^8.57.0" + } +} + \ No newline at end of file diff --git a/packages/events/.eslintrc.json b/packages/events/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/events/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/events/.gitignore b/packages/events/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/events/.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/packages/events/index.ts b/packages/events/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/events/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/events/package.json b/packages/events/package.json new file mode 100644 index 0000000..6fc7394 --- /dev/null +++ b/packages/events/package.json @@ -0,0 +1,21 @@ +{ + "name": "@nitrots/events", + "description": "Nitro events module", + "version": "1.0.0", + "type": "module", + "license": "GPL-3.0", + "scripts": { + "build": "vite build", + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "@nitrots/utils": "1.0.0" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/events/src/EventDispatcher.ts b/packages/events/src/EventDispatcher.ts new file mode 100644 index 0000000..a3bdc84 --- /dev/null +++ b/packages/events/src/EventDispatcher.ts @@ -0,0 +1,97 @@ +import { IEventDispatcher, INitroEvent } from '@nitrots/api'; +import { NitroLogger } from '@nitrots/utils'; + +export class EventDispatcher implements IEventDispatcher +{ + private _listeners: Map = new Map(); + + public dispose(): void + { + this.removeAllListeners(); + } + + public addEventListener(type: string, callback: (event: T) => void): 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: Function): 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: T): boolean + { + if(!event) return false; + + NitroLogger.events('Dispatched Event', event.type); + + this.processEvent(event); + + return true; + } + + private processEvent(event: T): void + { + const existing = this._listeners.get(event.type); + + if(!existing || !existing.length) return; + + const callbacks: Function[] = []; + + for(const callback of existing) + { + if(!callback) continue; + + callbacks.push(callback); + } + + while(callbacks.length) + { + const callback = callbacks.shift(); + + try + { + (callback as Function)(event); + } + + catch (err) + { + NitroLogger.error(err.stack); + + return; + } + } + } + + public removeAllListeners(): void + { + this._listeners.clear(); + } +} diff --git a/packages/events/src/GetEventDispatcher.ts b/packages/events/src/GetEventDispatcher.ts new file mode 100644 index 0000000..a145158 --- /dev/null +++ b/packages/events/src/GetEventDispatcher.ts @@ -0,0 +1,5 @@ +import { EventDispatcher } from './EventDispatcher'; + +const eventDispatcher = new EventDispatcher(); + +export const GetEventDispatcher = () => eventDispatcher; diff --git a/packages/events/src/NitroEventType.ts b/packages/events/src/NitroEventType.ts new file mode 100644 index 0000000..563bcb7 --- /dev/null +++ b/packages/events/src/NitroEventType.ts @@ -0,0 +1,16 @@ +export class NitroEventType +{ + public static readonly CONFIG_LOADED = 'CONFIG_LOADED'; + public static readonly CONFIG_FAILED = 'CONFIG_FAILED'; + public static readonly LOCALIZATION_LOADED = 'LOCALIZATION_LOADED'; + public static readonly LOCALIZATION_FAILED = 'LOCALIZATION_FAILED'; + public static readonly SOCKET_OPENED = 'SOCKET_OPENED'; + public static readonly SOCKET_CLOSED = 'SOCKET_CLOSED'; + public static readonly SOCKET_ERROR = 'SOCKET_ERROR'; + public static readonly SOCKET_CONNECTED = 'SOCKET_CONNECTED'; + public static readonly AVATAR_ASSET_DOWNLOADED = 'AVATAR_ASSET_DOWNLOADED'; + public static readonly AVATAR_ASSET_LOADED = 'AVATAR_ASSET_LOADED'; + public static readonly AVATAR_EFFECT_DOWNLOADED = 'AVATAR_EFFECT_DOWNLOADED'; + public static readonly AVATAR_EFFECT_LOADED = 'AVATAR_EFFECT_LOADED'; + public static readonly FURNITURE_DATA_LOADED = 'FURNITURE_DATA_LOADED'; +} diff --git a/packages/events/src/NitroSettingsEvent.ts b/packages/events/src/NitroSettingsEvent.ts new file mode 100644 index 0000000..62635a0 --- /dev/null +++ b/packages/events/src/NitroSettingsEvent.ts @@ -0,0 +1,116 @@ +import { NitroEvent } from './core'; + +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() + { + super(NitroSettingsEvent.SETTINGS_UPDATED); + } + + public clone(): NitroSettingsEvent + { + const clone = new NitroSettingsEvent(); + + clone._volumeSystem = this._volumeSystem; + clone._volumeFurni = this._volumeFurni; + clone._volumeTrax = this._volumeTrax; + clone._oldChat = this._oldChat; + clone._roomInvites = this._roomInvites; + clone._cameraFollow = this._cameraFollow; + clone._flags = this._flags; + clone._chatType = this._chatType; + + return clone; + } + + 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/packages/events/src/NitroSoundEvent.ts b/packages/events/src/NitroSoundEvent.ts new file mode 100644 index 0000000..5e70223 --- /dev/null +++ b/packages/events/src/NitroSoundEvent.ts @@ -0,0 +1,19 @@ +import { NitroEvent } from './core'; + +export class NitroSoundEvent extends NitroEvent +{ + public static PLAY_SOUND: string = 'NSOE_PLAY_SOUND'; + + private _sampleCode: string; + + constructor(type: string, sampleCode: string) + { + super(type); + this._sampleCode = sampleCode; + } + + public get sampleCode(): string + { + return this._sampleCode; + } +} diff --git a/packages/events/src/NitroToolbarAnimateIconEvent.ts b/packages/events/src/NitroToolbarAnimateIconEvent.ts new file mode 100644 index 0000000..5aa3f7f --- /dev/null +++ b/packages/events/src/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/packages/events/src/NitroToolbarEvent.ts b/packages/events/src/NitroToolbarEvent.ts new file mode 100644 index 0000000..d9cbc63 --- /dev/null +++ b/packages/events/src/NitroToolbarEvent.ts @@ -0,0 +1,35 @@ +import { NitroEvent } from './core'; + +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; + } +} diff --git a/packages/events/src/avatar/AvatarRenderEffectLibraryEvent.ts b/packages/events/src/avatar/AvatarRenderEffectLibraryEvent.ts new file mode 100644 index 0000000..5b0e217 --- /dev/null +++ b/packages/events/src/avatar/AvatarRenderEffectLibraryEvent.ts @@ -0,0 +1,21 @@ +import { IEffectAssetDownloadLibrary } from '@nitrots/api'; +import { NitroEvent } from '../core'; + +export class AvatarRenderEffectLibraryEvent extends NitroEvent +{ + public static DOWNLOAD_COMPLETE: string = 'ARELE_DOWNLOAD_COMPLETE'; + + private _library: IEffectAssetDownloadLibrary; + + constructor(type: string, library: IEffectAssetDownloadLibrary) + { + super(type); + + this._library = library; + } + + public get library(): IEffectAssetDownloadLibrary + { + return this._library; + } +} diff --git a/packages/events/src/avatar/AvatarRenderLibraryEvent.ts b/packages/events/src/avatar/AvatarRenderLibraryEvent.ts new file mode 100644 index 0000000..7fc1cb6 --- /dev/null +++ b/packages/events/src/avatar/AvatarRenderLibraryEvent.ts @@ -0,0 +1,21 @@ +import { IAvatarAssetDownloadLibrary } from '@nitrots/api'; +import { NitroEvent } from '../core'; + +export class AvatarRenderLibraryEvent extends NitroEvent +{ + public static DOWNLOAD_COMPLETE: string = 'ARLE_DOWNLOAD_COMPLETE'; + + private _library: IAvatarAssetDownloadLibrary; + + constructor(type: string, library: IAvatarAssetDownloadLibrary) + { + super(type); + + this._library = library; + } + + public get library(): IAvatarAssetDownloadLibrary + { + return this._library; + } +} diff --git a/packages/events/src/avatar/index.ts b/packages/events/src/avatar/index.ts new file mode 100644 index 0000000..13a1468 --- /dev/null +++ b/packages/events/src/avatar/index.ts @@ -0,0 +1,2 @@ +export * from './AvatarRenderEffectLibraryEvent'; +export * from './AvatarRenderLibraryEvent'; diff --git a/packages/events/src/camera/RoomCameraWidgetManagerEvent.ts b/packages/events/src/camera/RoomCameraWidgetManagerEvent.ts new file mode 100644 index 0000000..5989627 --- /dev/null +++ b/packages/events/src/camera/RoomCameraWidgetManagerEvent.ts @@ -0,0 +1,11 @@ +import { NitroEvent } from '../core'; + +export class RoomCameraWidgetManagerEvent extends NitroEvent +{ + public static INITIALIZED: string = 'RCWM_INITIALIZED'; + + constructor(type: string) + { + super(type); + } +} diff --git a/packages/events/src/camera/index.ts b/packages/events/src/camera/index.ts new file mode 100644 index 0000000..b6e32e2 --- /dev/null +++ b/packages/events/src/camera/index.ts @@ -0,0 +1 @@ +export * from './RoomCameraWidgetManagerEvent'; diff --git a/packages/events/src/communication/NitroCommunicationDemoEvent.ts b/packages/events/src/communication/NitroCommunicationDemoEvent.ts new file mode 100644 index 0000000..ca7a20d --- /dev/null +++ b/packages/events/src/communication/NitroCommunicationDemoEvent.ts @@ -0,0 +1,27 @@ +import { IConnection } from '@nitrots/api'; +import { NitroEvent } from '../core'; + +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; + } +} diff --git a/packages/events/src/communication/index.ts b/packages/events/src/communication/index.ts new file mode 100644 index 0000000..d795b92 --- /dev/null +++ b/packages/events/src/communication/index.ts @@ -0,0 +1 @@ +export * from './NitroCommunicationDemoEvent'; diff --git a/packages/events/src/core/ConfigurationEvent.ts b/packages/events/src/core/ConfigurationEvent.ts new file mode 100644 index 0000000..b7edf79 --- /dev/null +++ b/packages/events/src/core/ConfigurationEvent.ts @@ -0,0 +1,12 @@ +import { NitroEvent } from './NitroEvent'; + +export class ConfigurationEvent extends NitroEvent +{ + public static LOADED: string = 'NCE_LOADED'; + public static FAILED: string = 'NCE_FAILED'; + + constructor(type: string) + { + super(type); + } +} diff --git a/packages/events/src/core/MessageEvent.ts b/packages/events/src/core/MessageEvent.ts new file mode 100644 index 0000000..81d8694 --- /dev/null +++ b/packages/events/src/core/MessageEvent.ts @@ -0,0 +1,55 @@ +import { IConnection, IMessageEvent, IMessageParser } from '@nitrots/api'; + +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; + } +} diff --git a/packages/events/src/core/NitroEvent.ts b/packages/events/src/core/NitroEvent.ts new file mode 100644 index 0000000..b65e5de --- /dev/null +++ b/packages/events/src/core/NitroEvent.ts @@ -0,0 +1,16 @@ +import { INitroEvent } from '@nitrots/api'; + +export class NitroEvent implements INitroEvent +{ + private _type: string; + + constructor(type: string) + { + this._type = type; + } + + public get type(): string + { + return this._type; + } +} diff --git a/packages/events/src/core/SocketConnectionEvent.ts b/packages/events/src/core/SocketConnectionEvent.ts new file mode 100644 index 0000000..a5e20f8 --- /dev/null +++ b/packages/events/src/core/SocketConnectionEvent.ts @@ -0,0 +1,31 @@ +import { IConnection } from '@nitrots/api'; +import { NitroEvent } from './NitroEvent'; + +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; + } +} diff --git a/packages/events/src/core/index.ts b/packages/events/src/core/index.ts new file mode 100644 index 0000000..9a5d80e --- /dev/null +++ b/packages/events/src/core/index.ts @@ -0,0 +1,4 @@ +export * from './ConfigurationEvent'; +export * from './MessageEvent'; +export * from './NitroEvent'; +export * from './SocketConnectionEvent'; diff --git a/packages/events/src/index.ts b/packages/events/src/index.ts new file mode 100644 index 0000000..b5e8de3 --- /dev/null +++ b/packages/events/src/index.ts @@ -0,0 +1,14 @@ +export * from './EventDispatcher'; +export * from './GetEventDispatcher'; +export * from './NitroEventType'; +export * from './NitroSettingsEvent'; +export * from './NitroSoundEvent'; +export * from './NitroToolbarAnimateIconEvent'; +export * from './NitroToolbarEvent'; +export * from './avatar'; +export * from './camera'; +export * from './communication'; +export * from './core'; +export * from './room'; +export * from './session'; +export * from './sound'; diff --git a/packages/events/src/room/RoomBackgroundColorEvent.ts b/packages/events/src/room/RoomBackgroundColorEvent.ts new file mode 100644 index 0000000..03152df --- /dev/null +++ b/packages/events/src/room/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 _brightness: number; + private _bgOnly: boolean; + + constructor(roomId: number, color: number, _arg_3: number, _arg_4: boolean) + { + super(RoomBackgroundColorEvent.ROOM_COLOR, roomId); + + this._color = color; + this._brightness = _arg_3; + this._bgOnly = _arg_4; + } + + public get color(): number + { + return this._color; + } + + public get brightness(): number + { + return this._brightness; + } + + public get bgOnly(): boolean + { + return this._bgOnly; + } +} diff --git a/packages/events/src/room/RoomContentLoadedEvent.ts b/packages/events/src/room/RoomContentLoadedEvent.ts new file mode 100644 index 0000000..1cdc9fb --- /dev/null +++ b/packages/events/src/room/RoomContentLoadedEvent.ts @@ -0,0 +1,22 @@ +import { NitroEvent } from '../core'; + +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; + } +} diff --git a/packages/events/src/room/RoomDragEvent.ts b/packages/events/src/room/RoomDragEvent.ts new file mode 100644 index 0000000..e41931b --- /dev/null +++ b/packages/events/src/room/RoomDragEvent.ts @@ -0,0 +1,27 @@ +import { RoomEngineEvent } from './RoomEngineEvent'; + +export class RoomDragEvent extends RoomEngineEvent +{ + public static ROOM_DRAG: string = 'RDE_ROOM_DRAG'; + + private _offsetX: number; + private _offsetY: number; + + constructor(roomId: number, offsetX: number, offsetY: number) + { + super(RoomDragEvent.ROOM_DRAG, roomId); + + this._offsetX = offsetX; + this._offsetY = offsetY; + } + + public get offsetX(): number + { + return this._offsetX; + } + + public get offsetY(): number + { + return this._offsetY; + } +} diff --git a/packages/events/src/room/RoomEngineDimmerStateEvent.ts b/packages/events/src/room/RoomEngineDimmerStateEvent.ts new file mode 100644 index 0000000..85ca480 --- /dev/null +++ b/packages/events/src/room/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 presetId(): number + { + return this._presetId; + } + + public get effectId(): number + { + return this._effectId; + } + + public get color(): number + { + return this._color; + } + + public get brightness(): number + { + return this._brightness; + } +} diff --git a/packages/events/src/room/RoomEngineEvent.ts b/packages/events/src/room/RoomEngineEvent.ts new file mode 100644 index 0000000..4d90867 --- /dev/null +++ b/packages/events/src/room/RoomEngineEvent.ts @@ -0,0 +1,26 @@ +import { NitroEvent } from '../core'; + +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; + } +} diff --git a/packages/events/src/room/RoomEngineObjectEvent.ts b/packages/events/src/room/RoomEngineObjectEvent.ts new file mode 100644 index 0000000..75ff09b --- /dev/null +++ b/packages/events/src/room/RoomEngineObjectEvent.ts @@ -0,0 +1,39 @@ +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 REQUEST_MANIPULATION: string = 'REOE_REQUEST_MANIPULATION'; + public static MOUSE_ENTER: string = 'REOE_MOUSE_ENTER'; + public static MOUSE_LEAVE: string = 'REOE_MOUSE_LEAVE'; + public static DOUBLE_CLICK: string = 'REOE_DOUBLE_CLICK'; + + 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; + } +} diff --git a/packages/events/src/room/RoomEngineObjectPlacedEvent.ts b/packages/events/src/room/RoomEngineObjectPlacedEvent.ts new file mode 100644 index 0000000..cd008df --- /dev/null +++ b/packages/events/src/room/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 wallLocation(): 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 placedInRoom(): boolean + { + return this._placedInRoom; + } + + public get placedOnFloor(): boolean + { + return this._placedOnFloor; + } + + public get placedOnWall(): boolean + { + return this._placedOnWall; + } + + public get instanceData(): string + { + return this._instanceData; + } +} diff --git a/packages/events/src/room/RoomEngineObjectPlacedOnUserEvent.ts b/packages/events/src/room/RoomEngineObjectPlacedOnUserEvent.ts new file mode 100644 index 0000000..0ccb087 --- /dev/null +++ b/packages/events/src/room/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/packages/events/src/room/RoomEngineObjectPlaySoundEvent.ts b/packages/events/src/room/RoomEngineObjectPlaySoundEvent.ts new file mode 100644 index 0000000..c5e39fd --- /dev/null +++ b/packages/events/src/room/RoomEngineObjectPlaySoundEvent.ts @@ -0,0 +1,28 @@ +import { RoomEngineObjectEvent } from './RoomEngineObjectEvent'; + +export class RoomEngineObjectPlaySoundEvent extends RoomEngineObjectEvent +{ + public static PLAY_SOUND: string = 'REOPSE_PLAY_SOUND'; + public static PLAY_SOUND_AT_PITCH: string = 'REOPSE_PLAY_SOUND_AT_PITCH'; + + private _soundId: string; + private _pitch: number; + + constructor(type: string, roomId: number, objectId: number, objectCategory: number, soundId: string, pitch: number = 1) + { + super(type, roomId, objectId, objectCategory); + + this._soundId = soundId; + this._pitch = pitch; + } + + public get soundId(): string + { + return this._soundId; + } + + public get pitch(): number + { + return this._pitch; + } +} diff --git a/packages/events/src/room/RoomEngineRoomAdEvent.ts b/packages/events/src/room/RoomEngineRoomAdEvent.ts new file mode 100644 index 0000000..3325373 --- /dev/null +++ b/packages/events/src/room/RoomEngineRoomAdEvent.ts @@ -0,0 +1,9 @@ +import { RoomEngineObjectEvent } from './RoomEngineObjectEvent'; + +export class RoomEngineRoomAdEvent extends RoomEngineObjectEvent +{ + public static FURNI_CLICK: string = 'RERAE_FURNI_CLICK'; + public static FURNI_DOUBLE_CLICK: string = 'RERAE_FURNI_DOUBLE_CLICK'; + public static TOOLTIP_SHOW: string = 'RERAE_TOOLTIP_SHOW'; + public static TOOLTIP_HIDE: string = 'RERAE_TOOLTIP_HIDE'; +} diff --git a/packages/events/src/room/RoomEngineSamplePlaybackEvent.ts b/packages/events/src/room/RoomEngineSamplePlaybackEvent.ts new file mode 100644 index 0000000..ba4e04e --- /dev/null +++ b/packages/events/src/room/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/packages/events/src/room/RoomEngineTriggerWidgetEvent.ts b/packages/events/src/room/RoomEngineTriggerWidgetEvent.ts new file mode 100644 index 0000000..ba1c8cb --- /dev/null +++ b/packages/events/src/room/RoomEngineTriggerWidgetEvent.ts @@ -0,0 +1,58 @@ +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_STACK_HEIGHT: string = 'RETWE_REQUEST_STACK_HEIGHT'; + public static REQUEST_EXTERNAL_IMAGE: string = 'RETWE_REQUEST_EXTERNAL_IMAGE'; + 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'; + public static REQUEST_YOUTUBE: string = 'RETWE_REQUEST_YOUTUBE'; + + 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; + } + + public get contextMenu(): string + { + return this._widget; + } +} diff --git a/packages/events/src/room/RoomEngineUseProductEvent.ts b/packages/events/src/room/RoomEngineUseProductEvent.ts new file mode 100644 index 0000000..c8e78aa --- /dev/null +++ b/packages/events/src/room/RoomEngineUseProductEvent.ts @@ -0,0 +1,28 @@ +import { RoomEngineObjectEvent } from './RoomEngineObjectEvent'; + +export class RoomEngineUseProductEvent extends RoomEngineObjectEvent +{ + public static USE_PRODUCT_FROM_ROOM: string = 'REUPE_USE_PRODUCT_FROM_ROOM'; + public static USE_PRODUCT_FROM_INVENTORY: string = 'REUPE_USE_PRODUCT_FROM_INVENTORY'; + + private _inventoryStripId: number; + private _furnitureTypeId: number; + + constructor(type: string, roomId: number, objectId: number, category: number, inventoryStripId = -1, furnitureTypeId = -1) + { + super(type, roomId, objectId, category); + + this._inventoryStripId = inventoryStripId; + this._furnitureTypeId = furnitureTypeId; + } + + public get inventoryStripId(): number + { + return this._inventoryStripId; + } + + public get furnitureTypeId(): number + { + return this._furnitureTypeId; + } +} diff --git a/packages/events/src/room/RoomObjectBadgeAssetEvent.ts b/packages/events/src/room/RoomObjectBadgeAssetEvent.ts new file mode 100644 index 0000000..9734799 --- /dev/null +++ b/packages/events/src/room/RoomObjectBadgeAssetEvent.ts @@ -0,0 +1,28 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +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; + } +} diff --git a/packages/events/src/room/RoomObjectDataRequestEvent.ts b/packages/events/src/room/RoomObjectDataRequestEvent.ts new file mode 100644 index 0000000..b0475a3 --- /dev/null +++ b/packages/events/src/room/RoomObjectDataRequestEvent.ts @@ -0,0 +1,13 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +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/packages/events/src/room/RoomObjectDimmerStateUpdateEvent.ts b/packages/events/src/room/RoomObjectDimmerStateUpdateEvent.ts new file mode 100644 index 0000000..af60673 --- /dev/null +++ b/packages/events/src/room/RoomObjectDimmerStateUpdateEvent.ts @@ -0,0 +1,49 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +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 presetId(): number + { + return this._presetId; + } + + public get effectId(): number + { + return this._effectId; + } + + public get color(): number + { + return this._color; + } + + public get brightness(): number + { + return this._brightness; + } +} diff --git a/packages/events/src/room/RoomObjectEvent.ts b/packages/events/src/room/RoomObjectEvent.ts new file mode 100644 index 0000000..c229648 --- /dev/null +++ b/packages/events/src/room/RoomObjectEvent.ts @@ -0,0 +1,33 @@ +import { IRoomObject } from '@nitrots/api'; +import { NitroEvent } from '../core'; + +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; + } +} diff --git a/packages/events/src/room/RoomObjectFloorHoleEvent.ts b/packages/events/src/room/RoomObjectFloorHoleEvent.ts new file mode 100644 index 0000000..cd51b89 --- /dev/null +++ b/packages/events/src/room/RoomObjectFloorHoleEvent.ts @@ -0,0 +1,13 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +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); + } +} diff --git a/packages/events/src/room/RoomObjectFurnitureActionEvent.ts b/packages/events/src/room/RoomObjectFurnitureActionEvent.ts new file mode 100644 index 0000000..f338e8a --- /dev/null +++ b/packages/events/src/room/RoomObjectFurnitureActionEvent.ts @@ -0,0 +1,20 @@ +import { RoomObjectEvent } from './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'; +} diff --git a/packages/events/src/room/RoomObjectHSLColorEnableEvent.ts b/packages/events/src/room/RoomObjectHSLColorEnableEvent.ts new file mode 100644 index 0000000..e00a4f3 --- /dev/null +++ b/packages/events/src/room/RoomObjectHSLColorEnableEvent.ts @@ -0,0 +1,42 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +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; + } +} diff --git a/packages/events/src/room/RoomObjectHSLColorEnabledEvent.ts b/packages/events/src/room/RoomObjectHSLColorEnabledEvent.ts new file mode 100644 index 0000000..b4a3f9e --- /dev/null +++ b/packages/events/src/room/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/packages/events/src/room/RoomObjectMouseEvent.ts b/packages/events/src/room/RoomObjectMouseEvent.ts new file mode 100644 index 0000000..3c8c34f --- /dev/null +++ b/packages/events/src/room/RoomObjectMouseEvent.ts @@ -0,0 +1,100 @@ +import { IRoomObject } from '@nitrots/api'; +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_DOWN_LONG: string = 'ROE_MOUSE_DOWN_LONG'; + 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; + } +} diff --git a/packages/events/src/room/RoomObjectMoveEvent.ts b/packages/events/src/room/RoomObjectMoveEvent.ts new file mode 100644 index 0000000..483b68b --- /dev/null +++ b/packages/events/src/room/RoomObjectMoveEvent.ts @@ -0,0 +1,13 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +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); + } +} diff --git a/packages/events/src/room/RoomObjectPlaySoundIdEvent.ts b/packages/events/src/room/RoomObjectPlaySoundIdEvent.ts new file mode 100644 index 0000000..815f6c0 --- /dev/null +++ b/packages/events/src/room/RoomObjectPlaySoundIdEvent.ts @@ -0,0 +1,29 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectFurnitureActionEvent } from './RoomObjectFurnitureActionEvent'; + +export class RoomObjectPlaySoundIdEvent extends RoomObjectFurnitureActionEvent +{ + public static PLAY_SOUND: string = 'ROPSIE_PLAY_SOUND'; + public static PLAY_SOUND_AT_PITCH: string = 'ROPSIE_PLAY_SOUND_AT_PITCH'; + + private _soundId: string; + private _pitch: number; + + constructor(type: string, object: IRoomObject, soundId: string, pitch: number = 1) + { + super(type, object); + + this._soundId = soundId; + this._pitch = pitch; + } + + public get soundId(): string + { + return this._soundId; + } + + public get pitch(): number + { + return this._pitch; + } +} diff --git a/packages/events/src/room/RoomObjectRoomAdEvent.ts b/packages/events/src/room/RoomObjectRoomAdEvent.ts new file mode 100644 index 0000000..ac8deaa --- /dev/null +++ b/packages/events/src/room/RoomObjectRoomAdEvent.ts @@ -0,0 +1,32 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +export class RoomObjectRoomAdEvent extends RoomObjectEvent +{ + public static ROOM_AD_LOAD_IMAGE: string = 'RORAE_ROOM_AD_LOAD_IMAGE'; + public static ROOM_AD_FURNI_CLICK: string = 'RORAE_ROOM_AD_FURNI_CLICK'; + public static ROOM_AD_FURNI_DOUBLE_CLICK: string = 'RORAE_ROOM_AD_FURNI_DOUBLE_CLICK'; + public static ROOM_AD_TOOLTIP_SHOW: string = 'RORAE_ROOM_AD_TOOLTIP_SHOW'; + public static ROOM_AD_TOOLTIP_HIDE: string = 'RORAE_ROOM_AD_TOOLTIP_HIDE'; + + private _imageUrl: string = ''; + private _clickUrl: string = ''; + + constructor(type: string, object: IRoomObject, imageUrl: string = '', clickUrl: string = '') + { + super(type, object); + + this._imageUrl = imageUrl; + this._clickUrl = clickUrl; + } + + public get imageUrl(): string + { + return this._imageUrl; + } + + public get clickUrl(): string + { + return this._clickUrl; + } +} diff --git a/packages/events/src/room/RoomObjectSamplePlaybackEvent.ts b/packages/events/src/room/RoomObjectSamplePlaybackEvent.ts new file mode 100644 index 0000000..77384ad --- /dev/null +++ b/packages/events/src/room/RoomObjectSamplePlaybackEvent.ts @@ -0,0 +1,31 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +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/packages/events/src/room/RoomObjectSoundMachineEvent.ts b/packages/events/src/room/RoomObjectSoundMachineEvent.ts new file mode 100644 index 0000000..9576f1e --- /dev/null +++ b/packages/events/src/room/RoomObjectSoundMachineEvent.ts @@ -0,0 +1,13 @@ +import { RoomEngineObjectEvent } from './RoomEngineObjectEvent'; + +export class RoomObjectSoundMachineEvent extends RoomEngineObjectEvent +{ + public static SOUND_MACHINE_INIT: string = 'ROSM_SOUND_MACHINE_INIT'; + public static SOUND_MACHINE_SWITCHED_ON: string = 'ROSM_SOUND_MACHINE_SWITCHED_ON'; + public static SOUND_MACHINE_SWITCHED_OFF: string = 'ROSM_SOUND_MACHINE_SWITCHED_OFF'; + public static SOUND_MACHINE_DISPOSE: string = 'ROSM_SOUND_MACHINE_DISPOSE'; + public static JUKEBOX_INIT: string = 'ROSM_JUKEBOX_INIT'; + public static JUKEBOX_SWITCHED_ON: string = 'ROSM_JUKEBOX_SWITCHED_ON'; + public static JUKEBOX_SWITCHED_OFF: string = 'ROSM_JUKEBOX_SWITCHED_OFF'; + public static JUKEBOX_DISPOSE: string = 'ROSM_JUKEBOX_DISPOSE'; +} diff --git a/packages/events/src/room/RoomObjectStateChangedEvent.ts b/packages/events/src/room/RoomObjectStateChangedEvent.ts new file mode 100644 index 0000000..3f9a57a --- /dev/null +++ b/packages/events/src/room/RoomObjectStateChangedEvent.ts @@ -0,0 +1,22 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +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; + } +} diff --git a/packages/events/src/room/RoomObjectTileMouseEvent.ts b/packages/events/src/room/RoomObjectTileMouseEvent.ts new file mode 100644 index 0000000..0de010c --- /dev/null +++ b/packages/events/src/room/RoomObjectTileMouseEvent.ts @@ -0,0 +1,48 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectMouseEvent } from './RoomObjectMouseEvent'; + +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 tileXAsInt(): number + { + return Math.trunc(this._tileX + 0.499); + } + + public get tileYAsInt(): number + { + return Math.trunc(this._tileY + 0.499); + } + + public get tileZAsInt(): number + { + return Math.trunc(this._tileZ + 0.499); + } +} diff --git a/packages/events/src/room/RoomObjectWallMouseEvent.ts b/packages/events/src/room/RoomObjectWallMouseEvent.ts new file mode 100644 index 0000000..20ef87c --- /dev/null +++ b/packages/events/src/room/RoomObjectWallMouseEvent.ts @@ -0,0 +1,60 @@ +import { IRoomObject, IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { RoomObjectMouseEvent } from './RoomObjectMouseEvent'; + +export class RoomObjectWallMouseEvent extends RoomObjectMouseEvent +{ + private _wallLocation: IVector3D; + private _wallWd: IVector3D; + private _wallHt: IVector3D; + 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; + } +} diff --git a/packages/events/src/room/RoomObjectWidgetRequestEvent.ts b/packages/events/src/room/RoomObjectWidgetRequestEvent.ts new file mode 100644 index 0000000..36d50d1 --- /dev/null +++ b/packages/events/src/room/RoomObjectWidgetRequestEvent.ts @@ -0,0 +1,48 @@ +import { IRoomObject } from '@nitrots/api'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +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 STACK_HEIGHT: string = 'ROWRE_STACK_HEIGHT'; + public static EXTERNAL_IMAGE: string = 'ROWRE_EXTERNAL_IMAGE'; + 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'; + public static YOUTUBE: string = 'ROWRE_YOUTUBE'; + + constructor(type: string, roomObject: IRoomObject) + { + super(type, roomObject); + } +} diff --git a/packages/events/src/room/RoomSpriteMouseEvent.ts b/packages/events/src/room/RoomSpriteMouseEvent.ts new file mode 100644 index 0000000..7a68609 --- /dev/null +++ b/packages/events/src/room/RoomSpriteMouseEvent.ts @@ -0,0 +1,117 @@ +import { IRoomSpriteMouseEvent } from '@nitrots/api'; + +export class RoomSpriteMouseEvent implements IRoomSpriteMouseEvent +{ + 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 eventId(): 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; + } +} diff --git a/packages/events/src/room/RoomToObjectEvent.ts b/packages/events/src/room/RoomToObjectEvent.ts new file mode 100644 index 0000000..fbd5c53 --- /dev/null +++ b/packages/events/src/room/RoomToObjectEvent.ts @@ -0,0 +1,9 @@ +import { NitroEvent } from '../core'; + +export class RoomToObjectEvent extends NitroEvent +{ + public constructor(type: string) + { + super(type); + } +} diff --git a/packages/events/src/room/RoomToObjectOwnAvatarMoveEvent.ts b/packages/events/src/room/RoomToObjectOwnAvatarMoveEvent.ts new file mode 100644 index 0000000..74883e8 --- /dev/null +++ b/packages/events/src/room/RoomToObjectOwnAvatarMoveEvent.ts @@ -0,0 +1,21 @@ +import { IVector3D } from '@nitrots/api'; +import { RoomToObjectEvent } from './RoomToObjectEvent'; + +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; + } +} diff --git a/packages/events/src/room/RoomZoomEvent.ts b/packages/events/src/room/RoomZoomEvent.ts new file mode 100644 index 0000000..1119774 --- /dev/null +++ b/packages/events/src/room/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/packages/events/src/room/index.ts b/packages/events/src/room/index.ts new file mode 100644 index 0000000..6c25618 --- /dev/null +++ b/packages/events/src/room/index.ts @@ -0,0 +1,35 @@ +export * from './RoomBackgroundColorEvent'; +export * from './RoomContentLoadedEvent'; +export * from './RoomDragEvent'; +export * from './RoomEngineDimmerStateEvent'; +export * from './RoomEngineEvent'; +export * from './RoomEngineObjectEvent'; +export * from './RoomEngineObjectPlacedEvent'; +export * from './RoomEngineObjectPlacedOnUserEvent'; +export * from './RoomEngineObjectPlaySoundEvent'; +export * from './RoomEngineRoomAdEvent'; +export * from './RoomEngineSamplePlaybackEvent'; +export * from './RoomEngineTriggerWidgetEvent'; +export * from './RoomEngineUseProductEvent'; +export * from './RoomObjectBadgeAssetEvent'; +export * from './RoomObjectDataRequestEvent'; +export * from './RoomObjectDimmerStateUpdateEvent'; +export * from './RoomObjectEvent'; +export * from './RoomObjectFloorHoleEvent'; +export * from './RoomObjectFurnitureActionEvent'; +export * from './RoomObjectHSLColorEnableEvent'; +export * from './RoomObjectHSLColorEnabledEvent'; +export * from './RoomObjectMouseEvent'; +export * from './RoomObjectMoveEvent'; +export * from './RoomObjectPlaySoundIdEvent'; +export * from './RoomObjectRoomAdEvent'; +export * from './RoomObjectSamplePlaybackEvent'; +export * from './RoomObjectSoundMachineEvent'; +export * from './RoomObjectStateChangedEvent'; +export * from './RoomObjectTileMouseEvent'; +export * from './RoomObjectWallMouseEvent'; +export * from './RoomObjectWidgetRequestEvent'; +export * from './RoomSpriteMouseEvent'; +export * from './RoomToObjectEvent'; +export * from './RoomToObjectOwnAvatarMoveEvent'; +export * from './RoomZoomEvent'; diff --git a/packages/events/src/session/BadgeImageReadyEvent.ts b/packages/events/src/session/BadgeImageReadyEvent.ts new file mode 100644 index 0000000..b9dc8cf --- /dev/null +++ b/packages/events/src/session/BadgeImageReadyEvent.ts @@ -0,0 +1,28 @@ +import { Texture } from 'pixi.js'; +import { NitroEvent } from '../core'; + +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; + } +} diff --git a/packages/events/src/session/MysteryBoxKeysUpdateEvent.ts b/packages/events/src/session/MysteryBoxKeysUpdateEvent.ts new file mode 100644 index 0000000..7f6a073 --- /dev/null +++ b/packages/events/src/session/MysteryBoxKeysUpdateEvent.ts @@ -0,0 +1,27 @@ +import { NitroEvent } from '../core'; + +export class MysteryBoxKeysUpdateEvent extends NitroEvent +{ + public static MYSTERY_BOX_KEYS_UPDATE: string = 'mbke_update'; + + private _boxColor: string; + private _keyColor: string; + + constructor(boxColor: string, keyColor: string) + { + super(MysteryBoxKeysUpdateEvent.MYSTERY_BOX_KEYS_UPDATE); + + this._boxColor = boxColor; + this._keyColor = keyColor; + } + + public get boxColor(): string + { + return this._boxColor; + } + + public get keyColor(): string + { + return this._keyColor; + } +} diff --git a/packages/events/src/session/PerksUpdatedEvent.ts b/packages/events/src/session/PerksUpdatedEvent.ts new file mode 100644 index 0000000..e7b9679 --- /dev/null +++ b/packages/events/src/session/PerksUpdatedEvent.ts @@ -0,0 +1,11 @@ +import { NitroEvent } from '../core'; + +export class PerksUpdatedEvent extends NitroEvent +{ + public static PERKS_UPDATED: string = 'PUE_perks_updated'; + + constructor() + { + super(PerksUpdatedEvent.PERKS_UPDATED); + } +} diff --git a/packages/events/src/session/RoomSessionChatEvent.ts b/packages/events/src/session/RoomSessionChatEvent.ts new file mode 100644 index 0000000..38d5435 --- /dev/null +++ b/packages/events/src/session/RoomSessionChatEvent.ts @@ -0,0 +1,69 @@ +import { IRoomSession } from '@nitrots/api'; +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_TYPE_SPEAK: number = 0; + public static CHAT_TYPE_WHISPER: number = 1; + public static CHAT_TYPE_SHOUT: number = 2; + public static CHAT_TYPE_RESPECT: number = 3; + public static CHAT_TYPE_PETRESPECT: number = 4; + public static CHAT_TYPE_HAND_ITEM_RECEIVED: number = 5; + public static CHAT_TYPE_PETTREAT: number = 6; + public static CHAT_TYPE_PETREVIVE: number = 7; + public static CHAT_TYPE_PET_REBREED_FERTILIZE: number = 8; + public static CHAT_TYPE_PET_SPEED_FERTILIZE: number = 9; + public static CHAT_TYPE_MUTE_REMAINING: 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; + } +} diff --git a/packages/events/src/session/RoomSessionConfirmPetBreedingEvent.ts b/packages/events/src/session/RoomSessionConfirmPetBreedingEvent.ts new file mode 100644 index 0000000..1292409 --- /dev/null +++ b/packages/events/src/session/RoomSessionConfirmPetBreedingEvent.ts @@ -0,0 +1,49 @@ +import { BreedingPetInfo, IRoomSession, RarityCategoryData } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionConfirmPetBreedingEvent extends RoomSessionEvent +{ + public static CONFIRM_PET_BREEDING: string = 'RSPFUE_CONFIRM_PET_BREEDING'; + + private _nestId: number; + private _pet1: BreedingPetInfo; + private _pet2: BreedingPetInfo; + private _rarityCategories: RarityCategoryData[]; + private _resultPetTypeId: number; + + constructor(session: IRoomSession, nestId: number, pet1: BreedingPetInfo, pet2: BreedingPetInfo, rarityCategories: RarityCategoryData[], resultPetTypeId: number) + { + super(RoomSessionConfirmPetBreedingEvent.CONFIRM_PET_BREEDING, session); + + this._nestId = nestId; + this._pet1 = pet1; + this._pet2 = pet2; + this._rarityCategories = rarityCategories; + this._resultPetTypeId = resultPetTypeId; + } + + public get nestId(): number + { + return this._nestId; + } + + public get pet1(): BreedingPetInfo + { + return this._pet1; + } + + public get pet2(): BreedingPetInfo + { + return this._pet2; + } + + public get rarityCategories(): RarityCategoryData[] + { + return this._rarityCategories; + } + + public get resultPetTypeId(): number + { + return this._resultPetTypeId; + } +} diff --git a/packages/events/src/session/RoomSessionConfirmPetBreedingResultEvent.ts b/packages/events/src/session/RoomSessionConfirmPetBreedingResultEvent.ts new file mode 100644 index 0000000..5e57886 --- /dev/null +++ b/packages/events/src/session/RoomSessionConfirmPetBreedingResultEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '@nitrots/api'; +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(session: IRoomSession, breedingNestStuffId: number, result: number) + { + super(RoomSessionConfirmPetBreedingResultEvent.RSPFUE_CONFIRM_PET_BREEDING_RESULT, session); + + this._breedingNestStuffId = breedingNestStuffId; + this._result = result; + } + + public get breedingNestStuffId(): number + { + return this._breedingNestStuffId; + } + + public get result(): number + { + return this._result; + } +} diff --git a/packages/events/src/session/RoomSessionDanceEvent.ts b/packages/events/src/session/RoomSessionDanceEvent.ts new file mode 100644 index 0000000..d7f7b28 --- /dev/null +++ b/packages/events/src/session/RoomSessionDanceEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '@nitrots/api'; +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; + } +} diff --git a/packages/events/src/session/RoomSessionDimmerPresetsEvent.ts b/packages/events/src/session/RoomSessionDimmerPresetsEvent.ts new file mode 100644 index 0000000..86db244 --- /dev/null +++ b/packages/events/src/session/RoomSessionDimmerPresetsEvent.ts @@ -0,0 +1,45 @@ +import { IRoomSession } from '@nitrots/api'; +import { RoomSessionDimmerPresetsEventPresetItem } from './RoomSessionDimmerPresetsEventPresetItem'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionDimmerPresetsEvent extends RoomSessionEvent +{ + public static ROOM_DIMMER_PRESETS: string = 'RSDPE_PRESETS'; + + private _selectedPresetId: number = 0; + private _presets: RoomSessionDimmerPresetsEventPresetItem[]; + + constructor(type: string, session: IRoomSession) + { + super(type, session); + + this._presets = []; + } + + public storePreset(id: number, type: number, color: number, brightness: number): void + { + this._presets[(id - 1)] = new RoomSessionDimmerPresetsEventPresetItem(id, type, color, brightness); + } + + public getPreset(id: number): RoomSessionDimmerPresetsEventPresetItem + { + if((id < 0) || (id >= this._presets.length)) return null; + + return this._presets[id]; + } + + public get presetCount(): number + { + return this._presets.length; + } + + public get selectedPresetId(): number + { + return this._selectedPresetId; + } + + public set selectedPresetId(id: number) + { + this._selectedPresetId = id; + } +} diff --git a/packages/events/src/session/RoomSessionDimmerPresetsEventPresetItem.ts b/packages/events/src/session/RoomSessionDimmerPresetsEventPresetItem.ts new file mode 100644 index 0000000..9a05be0 --- /dev/null +++ b/packages/events/src/session/RoomSessionDimmerPresetsEventPresetItem.ts @@ -0,0 +1,35 @@ +export class RoomSessionDimmerPresetsEventPresetItem +{ + private _id: number; + private _type: number; + private _color: number; + private _brightness: number; + + constructor(id: number, type: number, color: number, brightness: number) + { + this._id = id; + this._type = type; + this._color = color; + this._brightness = brightness; + } + + public get id(): number + { + return this._id; + } + + public get type(): number + { + return this._type; + } + + public get color(): number + { + return this._color; + } + + public get brightness(): number + { + return this._brightness; + } +} diff --git a/packages/events/src/session/RoomSessionDoorbellEvent.ts b/packages/events/src/session/RoomSessionDoorbellEvent.ts new file mode 100644 index 0000000..ff6480b --- /dev/null +++ b/packages/events/src/session/RoomSessionDoorbellEvent.ts @@ -0,0 +1,23 @@ +import { IRoomSession } from '@nitrots/api'; +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; + } +} diff --git a/packages/events/src/session/RoomSessionErrorMessageEvent.ts b/packages/events/src/session/RoomSessionErrorMessageEvent.ts new file mode 100644 index 0000000..50f0630 --- /dev/null +++ b/packages/events/src/session/RoomSessionErrorMessageEvent.ts @@ -0,0 +1,32 @@ +import { IRoomSession } from '@nitrots/api'; +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; + } +} diff --git a/packages/events/src/session/RoomSessionEvent.ts b/packages/events/src/session/RoomSessionEvent.ts new file mode 100644 index 0000000..bf8bde9 --- /dev/null +++ b/packages/events/src/session/RoomSessionEvent.ts @@ -0,0 +1,31 @@ +import { IRoomSession } from '@nitrots/api'; +import { NitroEvent } from '../core'; + +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; + } +} diff --git a/packages/events/src/session/RoomSessionFavoriteGroupUpdateEvent.ts b/packages/events/src/session/RoomSessionFavoriteGroupUpdateEvent.ts new file mode 100644 index 0000000..9f02357 --- /dev/null +++ b/packages/events/src/session/RoomSessionFavoriteGroupUpdateEvent.ts @@ -0,0 +1,42 @@ +import { IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionFavoriteGroupUpdateEvent extends RoomSessionEvent +{ + public static FAVOURITE_GROUP_UPDATE: string = 'RSFGUE_FAVOURITE_GROUP_UPDATE'; + + private _roomIndex: number; + private _habboGroupId: number; + private _habboGroupName: string; + private _status: number; + + constructor(session: IRoomSession, roomIndex: number, groupId: number, status: number, groupName: string) + { + super(RoomSessionFavoriteGroupUpdateEvent.FAVOURITE_GROUP_UPDATE, session); + + this._roomIndex = roomIndex; + this._habboGroupId = groupId; + this._habboGroupName = groupName; + this._status = status; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get habboGroupId(): number + { + return this._habboGroupId; + } + + public get habboGroupName(): string + { + return this._habboGroupName; + } + + public get status(): number + { + return this._status; + } +} diff --git a/packages/events/src/session/RoomSessionFriendRequestEvent.ts b/packages/events/src/session/RoomSessionFriendRequestEvent.ts new file mode 100644 index 0000000..7b72482 --- /dev/null +++ b/packages/events/src/session/RoomSessionFriendRequestEvent.ts @@ -0,0 +1,35 @@ +import { IRoomSession } from '@nitrots/api'; +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/packages/events/src/session/RoomSessionNestBreedingSuccessEvent.ts b/packages/events/src/session/RoomSessionNestBreedingSuccessEvent.ts new file mode 100644 index 0000000..d65bb43 --- /dev/null +++ b/packages/events/src/session/RoomSessionNestBreedingSuccessEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionNestBreedingSuccessEvent extends RoomSessionEvent +{ + public static NEST_BREEDING_SUCCESS: string = 'RSPFUE_NEST_BREEDING_SUCCESS'; + + private _rarityCategory: number; + private _petId: number; + + constructor(session: IRoomSession, petId: number, rarityCategory: number) + { + super(RoomSessionNestBreedingSuccessEvent.NEST_BREEDING_SUCCESS, session); + + this._petId = petId; + this._rarityCategory = rarityCategory; + } + + public get rarityCategory(): number + { + return this._rarityCategory; + } + + public get petId(): number + { + return this._petId; + } +} diff --git a/packages/events/src/session/RoomSessionPetBreedingEvent.ts b/packages/events/src/session/RoomSessionPetBreedingEvent.ts new file mode 100644 index 0000000..5176a57 --- /dev/null +++ b/packages/events/src/session/RoomSessionPetBreedingEvent.ts @@ -0,0 +1,35 @@ +import { IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetBreedingEvent extends RoomSessionEvent +{ + public static PET_BREEDING: string = 'RSPFUE_PET_BREEDING'; + + private _state: number; + private _ownPetId: number; + private _otherPetId: number; + + constructor(session: IRoomSession, state: number, ownPetId: number, otherPetId: number) + { + super(RoomSessionPetBreedingEvent.PET_BREEDING, session); + + this._state = state; + this._ownPetId = ownPetId; + this._otherPetId = otherPetId; + } + + public get state(): number + { + return this._state; + } + + public get ownPetId(): number + { + return this._ownPetId; + } + + public get otherPetId(): number + { + return this._otherPetId; + } +} diff --git a/packages/events/src/session/RoomSessionPetBreedingResultEvent.ts b/packages/events/src/session/RoomSessionPetBreedingResultEvent.ts new file mode 100644 index 0000000..99a1d2c --- /dev/null +++ b/packages/events/src/session/RoomSessionPetBreedingResultEvent.ts @@ -0,0 +1,28 @@ +import { IPetBreedingResultData, IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetBreedingResultEvent extends RoomSessionEvent +{ + public static PET_BREEDING_RESULT: string = 'RSPFUE_PET_BREEDING_RESULT'; + + private _resultData: IPetBreedingResultData; + private _otherResultData: IPetBreedingResultData; + + constructor(session: IRoomSession, resultData: IPetBreedingResultData, otherResultData: IPetBreedingResultData) + { + super(RoomSessionPetBreedingResultEvent.PET_BREEDING_RESULT, session); + + this._resultData = resultData; + this._otherResultData = otherResultData; + } + + public get resultData(): IPetBreedingResultData + { + return this._resultData; + } + + public get otherResultData(): IPetBreedingResultData + { + return this._otherResultData; + } +} diff --git a/packages/events/src/session/RoomSessionPetCommandsUpdateEvent.ts b/packages/events/src/session/RoomSessionPetCommandsUpdateEvent.ts new file mode 100644 index 0000000..100d423 --- /dev/null +++ b/packages/events/src/session/RoomSessionPetCommandsUpdateEvent.ts @@ -0,0 +1,35 @@ +import { IRoomSession } from '@nitrots/api'; +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; + } +} diff --git a/packages/events/src/session/RoomSessionPetFigureUpdateEvent.ts b/packages/events/src/session/RoomSessionPetFigureUpdateEvent.ts new file mode 100644 index 0000000..2ba0fbb --- /dev/null +++ b/packages/events/src/session/RoomSessionPetFigureUpdateEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '@nitrots/api'; +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(roomSession: IRoomSession, id: number, figure: string) + { + super(RoomSessionPetFigureUpdateEvent.PET_FIGURE_UPDATE, roomSession); + + this._petId = id; + this._figure = figure; + } + + public get id(): number + { + return this._petId; + } + + public get figure(): string + { + return this._figure; + } +} diff --git a/packages/events/src/session/RoomSessionPetInfoUpdateEvent.ts b/packages/events/src/session/RoomSessionPetInfoUpdateEvent.ts new file mode 100644 index 0000000..f9c2c28 --- /dev/null +++ b/packages/events/src/session/RoomSessionPetInfoUpdateEvent.ts @@ -0,0 +1,21 @@ +import { IRoomPetData, IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetInfoUpdateEvent extends RoomSessionEvent +{ + public static PET_INFO: string = 'RSPIUE_PET_INFO'; + + private _petInfo: IRoomPetData; + + constructor(k: IRoomSession, _arg_2: IRoomPetData) + { + super(RoomSessionPetInfoUpdateEvent.PET_INFO, k); + + this._petInfo = _arg_2; + } + + public get petInfo(): IRoomPetData + { + return this._petInfo; + } +} diff --git a/packages/events/src/session/RoomSessionPetLevelUpdateEvent.ts b/packages/events/src/session/RoomSessionPetLevelUpdateEvent.ts new file mode 100644 index 0000000..1f3745f --- /dev/null +++ b/packages/events/src/session/RoomSessionPetLevelUpdateEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetLevelUpdateEvent extends RoomSessionEvent +{ + public static PET_LEVEL_UPDATE: string = 'RSPLUE_PET_LEVEL_UPDATE'; + + private _petId: number; + private _level: number; + + constructor(session: IRoomSession, petId: number, level: number) + { + super(RoomSessionPetLevelUpdateEvent.PET_LEVEL_UPDATE, session); + + this._petId = petId; + this._level = level; + } + + public get petId(): number + { + return this._petId; + } + + public get level(): number + { + return this._level; + } +} diff --git a/packages/events/src/session/RoomSessionPetPackageEvent.ts b/packages/events/src/session/RoomSessionPetPackageEvent.ts new file mode 100644 index 0000000..8f751ea --- /dev/null +++ b/packages/events/src/session/RoomSessionPetPackageEvent.ts @@ -0,0 +1,43 @@ +import { IRoomSession, PetFigureData } from '@nitrots/api'; +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(petPackageName: string, session: IRoomSession, objectId: number, figureData: PetFigureData, nameValidationStatus: number, nameValidationInfo: string) + { + super(petPackageName, session); + + this._objectId = objectId; + this._figureData = figureData; + this._nameValidationStatus = nameValidationStatus; + this._nameValidationInfo = nameValidationInfo; + } + + public get objectId(): 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; + } +} diff --git a/packages/events/src/session/RoomSessionPetStatusUpdateEvent.ts b/packages/events/src/session/RoomSessionPetStatusUpdateEvent.ts new file mode 100644 index 0000000..45a805d --- /dev/null +++ b/packages/events/src/session/RoomSessionPetStatusUpdateEvent.ts @@ -0,0 +1,49 @@ +import { IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetStatusUpdateEvent extends RoomSessionEvent +{ + public static PET_STATUS_UPDATE: string = 'RSPFUE_PET_STATUS_UPDATE'; + + private _petId: number; + private _canBreed: boolean; + private _canHarvest: boolean; + private _canRevive: boolean; + private _hasBreedingPermission: boolean; + + constructor(roomSession: IRoomSession, petId: number, canBreed: boolean, canHarvest: boolean, canRevive: boolean, hasBreedingPermission: boolean) + { + super(RoomSessionPetStatusUpdateEvent.PET_STATUS_UPDATE, roomSession); + + this._petId = petId; + this._canBreed = canBreed; + this._canHarvest = canHarvest; + this._canRevive = canRevive; + this._hasBreedingPermission = hasBreedingPermission; + } + + public get petId(): number + { + return this._petId; + } + + public get canBreed(): boolean + { + return this._canBreed; + } + + public get canHarvest(): boolean + { + return this._canHarvest; + } + + public get canRevive(): boolean + { + return this._canRevive; + } + + public get hasBreedingPermission(): boolean + { + return this._hasBreedingPermission; + } +} diff --git a/packages/events/src/session/RoomSessionPollEvent.ts b/packages/events/src/session/RoomSessionPollEvent.ts new file mode 100644 index 0000000..935d2e8 --- /dev/null +++ b/packages/events/src/session/RoomSessionPollEvent.ts @@ -0,0 +1,100 @@ +import { IPollQuestion, IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPollEvent extends RoomSessionEvent +{ + public static OFFER: string = 'RSPE_POLL_OFFER'; + public static ERROR: string = 'RSPE_POLL_ERROR'; + public static CONTENT: string = 'RSPE_POLL_CONTENT'; + + private _id: number = -1; + private _headline: string; + private _summary: string; + private _numQuestions: number = 0; + private _startMessage: string = ''; + private _endMessage: string = ''; + private _questionArray: IPollQuestion[] = null; + private _npsPoll: 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 numQuestions(): number + { + return this._numQuestions; + } + + public set numQuestions(k: number) + { + this._numQuestions = k; + } + + public get startMessage(): string + { + return this._startMessage; + } + + public set startMessage(k: string) + { + this._startMessage = k; + } + + public get endMessage(): string + { + return this._endMessage; + } + + public set endMessage(k: string) + { + this._endMessage = k; + } + + public get questionArray(): IPollQuestion[] + { + return this._questionArray; + } + + public set questionArray(k: IPollQuestion[]) + { + this._questionArray = k; + } + + public get npsPoll(): boolean + { + return this._npsPoll; + } + + public set npsPoll(k: boolean) + { + this._npsPoll = k; + } +} diff --git a/packages/events/src/session/RoomSessionPresentEvent.ts b/packages/events/src/session/RoomSessionPresentEvent.ts new file mode 100644 index 0000000..ae6a954 --- /dev/null +++ b/packages/events/src/session/RoomSessionPresentEvent.ts @@ -0,0 +1,64 @@ +import { IRoomSession } from '@nitrots/api'; +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/packages/events/src/session/RoomSessionPropertyUpdateEvent.ts b/packages/events/src/session/RoomSessionPropertyUpdateEvent.ts new file mode 100644 index 0000000..e9281bb --- /dev/null +++ b/packages/events/src/session/RoomSessionPropertyUpdateEvent.ts @@ -0,0 +1,12 @@ +import { IRoomSession } from '@nitrots/api'; +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); + } +} diff --git a/packages/events/src/session/RoomSessionQueueEvent.ts b/packages/events/src/session/RoomSessionQueueEvent.ts new file mode 100644 index 0000000..0387f87 --- /dev/null +++ b/packages/events/src/session/RoomSessionQueueEvent.ts @@ -0,0 +1,57 @@ +import { IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionQueueEvent extends RoomSessionEvent +{ + public static QUEUE_STATUS: string = 'RSQE_QUEUE_STATUS'; + public static QUEUE_TYPE_CLUB: string = 'c'; + public static QUEUE_TYPE_NORMAL: string = 'd'; + public static QUEUE_TARGET_VISITOR: number = 2; + public static QUEUE_TARGET_SPECTATOR: 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.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 queueSetName(): string + { + return this._name; + } + + public get queueSetTarget(): number + { + return this._target; + } + + public get queueTypes(): string[] + { + return Array.from(this._queues.keys()); + } + + public getQueueSize(k: string): number + { + return this._queues.get(k); + } + + public addQueue(k: string, _arg_2: number): void + { + this._queues.set(k, _arg_2); + } +} diff --git a/packages/events/src/session/RoomSessionSpectatorModeEvent.ts b/packages/events/src/session/RoomSessionSpectatorModeEvent.ts new file mode 100644 index 0000000..0e99623 --- /dev/null +++ b/packages/events/src/session/RoomSessionSpectatorModeEvent.ts @@ -0,0 +1,12 @@ +import { IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionSpectatorModeEvent extends RoomSessionEvent +{ + public static SPECTATOR_MODE: string = 'RSSME_SPECTATOR_MODE'; + + constructor(type: string, session: IRoomSession) + { + super(type, session); + } +} diff --git a/packages/events/src/session/RoomSessionUserBadgesEvent.ts b/packages/events/src/session/RoomSessionUserBadgesEvent.ts new file mode 100644 index 0000000..bcae6bd --- /dev/null +++ b/packages/events/src/session/RoomSessionUserBadgesEvent.ts @@ -0,0 +1,29 @@ +import { IRoomSession } from '@nitrots/api'; +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; + } +} diff --git a/packages/events/src/session/RoomSessionUserDataUpdateEvent.ts b/packages/events/src/session/RoomSessionUserDataUpdateEvent.ts new file mode 100644 index 0000000..4ee8a13 --- /dev/null +++ b/packages/events/src/session/RoomSessionUserDataUpdateEvent.ts @@ -0,0 +1,21 @@ +import { IRoomSession, IRoomUserData } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionUserDataUpdateEvent extends RoomSessionEvent +{ + public static USER_DATA_UPDATED: string = 'RMUDUE_USER_DATA_UPDATED'; + + private _addedUsers: IRoomUserData[]; + + constructor(session: IRoomSession, addedUsers: IRoomUserData[]) + { + super(RoomSessionUserDataUpdateEvent.USER_DATA_UPDATED, session); + + this._addedUsers = addedUsers; + } + + public get addedUsers(): IRoomUserData[] + { + return this._addedUsers; + } +} diff --git a/packages/events/src/session/RoomSessionUserFigureUpdateEvent.ts b/packages/events/src/session/RoomSessionUserFigureUpdateEvent.ts new file mode 100644 index 0000000..3b64a02 --- /dev/null +++ b/packages/events/src/session/RoomSessionUserFigureUpdateEvent.ts @@ -0,0 +1,49 @@ +import { IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionUserFigureUpdateEvent extends RoomSessionEvent +{ + public static USER_FIGURE: string = 'RSUBE_FIGURE'; + + private _roomIndex: number = 0; + private _figure: string = ''; + private _gender: string = ''; + private _customInfo: string = ''; + private _achievementScore: number; + + constructor(session: IRoomSession, roomIndex: number, figure: string, gender: string, customInfo: string, achievementScore: number) + { + super(RoomSessionUserFigureUpdateEvent.USER_FIGURE, session); + + this._roomIndex = roomIndex; + this._figure = figure; + this._gender = gender; + this._customInfo = customInfo; + this._achievementScore = achievementScore; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get figure(): string + { + return this._figure; + } + + public get gender(): string + { + return this._gender; + } + + public get customInfo(): string + { + return this._customInfo; + } + + public get activityPoints(): number + { + return this._achievementScore; + } +} diff --git a/packages/events/src/session/RoomSessionUserTagsEvent.ts b/packages/events/src/session/RoomSessionUserTagsEvent.ts new file mode 100644 index 0000000..057b7bc --- /dev/null +++ b/packages/events/src/session/RoomSessionUserTagsEvent.ts @@ -0,0 +1,27 @@ +import { NitroEvent } from '../core'; + +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; + } +} diff --git a/packages/events/src/session/RoomSessionVoteEvent.ts b/packages/events/src/session/RoomSessionVoteEvent.ts new file mode 100644 index 0000000..4437947 --- /dev/null +++ b/packages/events/src/session/RoomSessionVoteEvent.ts @@ -0,0 +1,50 @@ +import { IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + + +export class RoomSessionVoteEvent 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; + } +} diff --git a/packages/events/src/session/RoomSessionWordQuizEvent.ts b/packages/events/src/session/RoomSessionWordQuizEvent.ts new file mode 100644 index 0000000..5fd629c --- /dev/null +++ b/packages/events/src/session/RoomSessionWordQuizEvent.ts @@ -0,0 +1,111 @@ +import { IQuestion, IRoomSession } from '@nitrots/api'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionWordQuizEvent extends RoomSessionEvent +{ + public static QUESTION: string = 'RWPUW_NEW_QUESTION'; + public static FINISHED: string = 'RWPUW_QUESION_FINSIHED'; + public static 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: IQuestion = 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 pollType(): string + { + return this._pollType; + } + + public set pollType(pollType: string) + { + this._pollType = pollType; + } + + public get pollId(): number + { + return this._pollId; + } + + public set pollId(k: number) + { + this._pollId = k; + } + + public get questionId(): number + { + return this._questionId; + } + + public set questionId(k: number) + { + this._questionId = k; + } + + public get duration(): number + { + return this._duration; + } + + public set duration(k: number) + { + this._duration = k; + } + + public get question(): IQuestion + { + return this._question; + } + + public set question(k: IQuestion) + { + 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(value: string) + { + this._value = value; + } + + public get answerCounts(): Map + { + return this._answerCounts; + } + + public set answerCounts(k: Map) + { + this._answerCounts = k; + } +} diff --git a/packages/events/src/session/SessionDataPreferencesEvent.ts b/packages/events/src/session/SessionDataPreferencesEvent.ts new file mode 100644 index 0000000..7e362d9 --- /dev/null +++ b/packages/events/src/session/SessionDataPreferencesEvent.ts @@ -0,0 +1,20 @@ +import { NitroEvent } from '../core'; + +export class SessionDataPreferencesEvent extends NitroEvent +{ + public static UPDATED: string = 'APUE_UPDATED'; + + private _uiFlags: number; + + constructor(k: number) + { + super(SessionDataPreferencesEvent.UPDATED); + + this._uiFlags = k; + } + + public get uiFlags(): number + { + return this._uiFlags; + } +} diff --git a/packages/events/src/session/UserNameUpdateEvent.ts b/packages/events/src/session/UserNameUpdateEvent.ts new file mode 100644 index 0000000..9b8051e --- /dev/null +++ b/packages/events/src/session/UserNameUpdateEvent.ts @@ -0,0 +1,20 @@ +import { NitroEvent } from '../core'; + +export class UserNameUpdateEvent extends NitroEvent +{ + public static UNUE_NAME_UPDATED: string = 'unue_name_updated'; + + private _name: string; + + constructor(name: string) + { + super(UserNameUpdateEvent.UNUE_NAME_UPDATED); + + this._name = name; + } + + public get name(): string + { + return this._name; + } +} diff --git a/packages/events/src/session/index.ts b/packages/events/src/session/index.ts new file mode 100644 index 0000000..82421b0 --- /dev/null +++ b/packages/events/src/session/index.ts @@ -0,0 +1,36 @@ +export * from './BadgeImageReadyEvent'; +export * from './MysteryBoxKeysUpdateEvent'; +export * from './PerksUpdatedEvent'; +export * from './RoomSessionChatEvent'; +export * from './RoomSessionConfirmPetBreedingEvent'; +export * from './RoomSessionConfirmPetBreedingResultEvent'; +export * from './RoomSessionDanceEvent'; +export * from './RoomSessionDimmerPresetsEvent'; +export * from './RoomSessionDimmerPresetsEventPresetItem'; +export * from './RoomSessionDoorbellEvent'; +export * from './RoomSessionErrorMessageEvent'; +export * from './RoomSessionEvent'; +export * from './RoomSessionFavoriteGroupUpdateEvent'; +export * from './RoomSessionFriendRequestEvent'; +export * from './RoomSessionNestBreedingSuccessEvent'; +export * from './RoomSessionPetBreedingEvent'; +export * from './RoomSessionPetBreedingResultEvent'; +export * from './RoomSessionPetCommandsUpdateEvent'; +export * from './RoomSessionPetFigureUpdateEvent'; +export * from './RoomSessionPetInfoUpdateEvent'; +export * from './RoomSessionPetLevelUpdateEvent'; +export * from './RoomSessionPetPackageEvent'; +export * from './RoomSessionPetStatusUpdateEvent'; +export * from './RoomSessionPollEvent'; +export * from './RoomSessionPresentEvent'; +export * from './RoomSessionPropertyUpdateEvent'; +export * from './RoomSessionQueueEvent'; +export * from './RoomSessionSpectatorModeEvent'; +export * from './RoomSessionUserBadgesEvent'; +export * from './RoomSessionUserDataUpdateEvent'; +export * from './RoomSessionUserFigureUpdateEvent'; +export * from './RoomSessionUserTagsEvent'; +export * from './RoomSessionVoteEvent'; +export * from './RoomSessionWordQuizEvent'; +export * from './SessionDataPreferencesEvent'; +export * from './UserNameUpdateEvent'; diff --git a/packages/events/src/sound/NotifyPlayedSongEvent.ts b/packages/events/src/sound/NotifyPlayedSongEvent.ts new file mode 100644 index 0000000..ef58c5d --- /dev/null +++ b/packages/events/src/sound/NotifyPlayedSongEvent.ts @@ -0,0 +1,27 @@ +import { NitroEvent } from '@nitrots/events'; + +export class NotifyPlayedSongEvent extends NitroEvent +{ + public static readonly NOTIFY_PLAYED_SONG = 'UIEW_NOTIFY_PLAYED_SONG'; + + private _name: string; + private _creator: string; + + constructor(name:string, creator:string) + { + super(NotifyPlayedSongEvent.NOTIFY_PLAYED_SONG); + + this._name = name; + this._creator = creator; + } + + public get name(): string + { + return this._name; + } + + public get creator(): string + { + return this._creator; + } +} diff --git a/packages/events/src/sound/NowPlayingEvent.ts b/packages/events/src/sound/NowPlayingEvent.ts new file mode 100644 index 0000000..0e0dd47 --- /dev/null +++ b/packages/events/src/sound/NowPlayingEvent.ts @@ -0,0 +1,35 @@ +import { NitroEvent } from '@nitrots/events'; + +export class NowPlayingEvent extends NitroEvent +{ + public static readonly NPE_USER_PLAY_SONG = 'NPE_USER_PLAY_SONG'; + public static readonly NPW_USER_STOP_SONG = 'NPW_USER_STOP_SONG'; + public static readonly NPE_SONG_CHANGED = 'NPE_SONG_CHANGED'; + + private _id:number; + private _position:number; + private _priority:number; + + constructor(k:string, priority:number, id:number, position:number) + { + super(k); + this._id = id; + this._position = position; + this._priority = priority; + } + + public get id():number + { + return this._id; + } + + public get position():number + { + return this._position; + } + + public get priority():number + { + return this._priority; + } +} diff --git a/packages/events/src/sound/PlayListStatusEvent.ts b/packages/events/src/sound/PlayListStatusEvent.ts new file mode 100644 index 0000000..8abe8fd --- /dev/null +++ b/packages/events/src/sound/PlayListStatusEvent.ts @@ -0,0 +1,12 @@ +import { NitroEvent } from '@nitrots/events'; + +export class PlayListStatusEvent extends NitroEvent +{ + public static readonly PLUE_PLAY_LIST_UPDATED = 'PLUE_PLAY_LIST_UPDATED'; + public static readonly PLUE_PLAY_LIST_FULL = 'PLUE_PLAY_LIST_FULL'; + + constructor(k:string) + { + super(k); + } +} diff --git a/packages/events/src/sound/SongDiskInventoryReceivedEvent.ts b/packages/events/src/sound/SongDiskInventoryReceivedEvent.ts new file mode 100644 index 0000000..76de576 --- /dev/null +++ b/packages/events/src/sound/SongDiskInventoryReceivedEvent.ts @@ -0,0 +1,11 @@ +import { NitroEvent } from '@nitrots/events'; + +export class SongDiskInventoryReceivedEvent extends NitroEvent +{ + public static readonly SDIR_SONG_DISK_INVENTORY_RECEIVENT_EVENT = 'SDIR_SONG_DISK_INVENTORY_RECEIVENT_EVENT'; + + constructor(k:string) + { + super(k); + } +} diff --git a/packages/events/src/sound/SongInfoReceivedEvent.ts b/packages/events/src/sound/SongInfoReceivedEvent.ts new file mode 100644 index 0000000..557c770 --- /dev/null +++ b/packages/events/src/sound/SongInfoReceivedEvent.ts @@ -0,0 +1,19 @@ +import { NitroEvent } from '@nitrots/events'; + +export class SongInfoReceivedEvent extends NitroEvent +{ + public static readonly SIR_TRAX_SONG_INFO_RECEIVED = 'SIR_TRAX_SONG_INFO_RECEIVED'; + + private _id:number; + + constructor(k:string, _arg_2:number) + { + super(k); + this._id = _arg_2; + } + + public get id():number + { + return this._id; + } +} diff --git a/packages/events/src/sound/SoundManagerEvent.ts b/packages/events/src/sound/SoundManagerEvent.ts new file mode 100644 index 0000000..115170a --- /dev/null +++ b/packages/events/src/sound/SoundManagerEvent.ts @@ -0,0 +1,19 @@ +import { NitroEvent } from '@nitrots/events'; + +export class SoundManagerEvent extends NitroEvent +{ + public static TRAX_SONG_COMPLETE: string = 'SME_TRAX_SONG_COMPLETE'; + + private _id: number; + + constructor(type: string, id: number) + { + super(type); + this._id = id; + } + + public get id(): number + { + return this._id; + } +} diff --git a/packages/events/src/sound/index.ts b/packages/events/src/sound/index.ts new file mode 100644 index 0000000..6ed30e6 --- /dev/null +++ b/packages/events/src/sound/index.ts @@ -0,0 +1,6 @@ +export * from './NotifyPlayedSongEvent'; +export * from './NowPlayingEvent'; +export * from './PlayListStatusEvent'; +export * from './SongDiskInventoryReceivedEvent'; +export * from './SongInfoReceivedEvent'; +export * from './SoundManagerEvent'; diff --git a/packages/events/tsconfig.json b/packages/events/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/events/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/localization/.eslintrc.json b/packages/localization/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/localization/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/localization/.gitignore b/packages/localization/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/localization/.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/packages/localization/index.ts b/packages/localization/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/localization/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/localization/package.json b/packages/localization/package.json new file mode 100644 index 0000000..2d0175a --- /dev/null +++ b/packages/localization/package.json @@ -0,0 +1,23 @@ +{ + "name": "@nitrots/localization", + "description": "Nitro localization module", + "version": "1.0.0", + "type": "module", + "license": "GPL-3.0", + "scripts": { + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/communication": "1.0.0", + "@nitrots/configuration": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "@nitrots/events": "1.0.0", + "pixi.js": "^8.0.4" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/localization/src/BadgeBaseAndLevel.ts b/packages/localization/src/BadgeBaseAndLevel.ts new file mode 100644 index 0000000..f5f7c90 --- /dev/null +++ b/packages/localization/src/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/packages/localization/src/GetLocalization.ts b/packages/localization/src/GetLocalization.ts new file mode 100644 index 0000000..4322e28 --- /dev/null +++ b/packages/localization/src/GetLocalization.ts @@ -0,0 +1,5 @@ +import { LocalizationManager } from './LocalizationManager'; + +const localization = new LocalizationManager(); + +export const GetLocalizationManager = () => localization; diff --git a/packages/localization/src/LocalizationManager.ts b/packages/localization/src/LocalizationManager.ts new file mode 100644 index 0000000..e848953 --- /dev/null +++ b/packages/localization/src/LocalizationManager.ts @@ -0,0 +1,304 @@ +import { ILocalizationManager } from '@nitrots/api'; +import { BadgePointLimitsEvent, GetCommunication } from '@nitrots/communication'; +import { GetConfiguration } from '@nitrots/configuration'; +import { BadgeBaseAndLevel } from './BadgeBaseAndLevel'; + +export class LocalizationManager implements ILocalizationManager +{ + private _definitions: Map = new Map(); + private _parameters: Map> = new Map(); + private _badgePointLimits: Map = new Map(); + private _romanNumerals: string[] = [ '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' ]; + + public async init(): Promise + { + try + { + const urls = GetConfiguration().getValue('external.texts.url').slice(); + + if(!urls || !urls.length) throw new Error('Invalid localization urls'); + + for(let url of urls) + { + if(!url || !url.length) return; + + url = GetConfiguration().interpolate(url); + + const response = await fetch(url); + + if(response.status !== 200) throw new Error('Invalid localization file'); + + this.parseLocalization(await response.json()); + } + + GetCommunication().registerMessageEvent(new BadgePointLimitsEvent(this.onBadgePointLimitsEvent.bind(this))); + } + + catch (err) + { + throw new Error(err); + } + } + + private parseLocalization(data: { [index: string]: any }): boolean + { + if(!data) return false; + + for(const key in data) this._definitions.set(key, data[key]); + + return true; + } + + private onBadgePointLimitsEvent(event: BadgePointLimitsEvent): void + { + const parser = event.getParser(); + + for(const data of parser.data) this.setBadgePointLimit(data.badgeId, data.limit); + } + + public getBadgePointLimit(badge: string): number + { + return (this._badgePointLimits.get(badge) || -1); + } + + public setBadgePointLimit(badge: string, point: number): void + { + this._badgePointLimits.set(badge, point); + } + + public getRomanNumeral(number: number): string + { + return this._romanNumerals[Math.max(0, (number - 1))]; + } + + public getPreviousLevelBadgeId(badgeName: string): string + { + const badge = new BadgeBaseAndLevel(badgeName); + + badge.level--; + + return badge.getBadgeId; + } + + public hasValue(key: string): boolean + { + return this._definitions.has(key); + } + + public getValue(key: string, doParams: boolean = true): string + { + if(!key || !key.length) return null; + + const keys = key.match(/\$\{.[^}]*\}/g); + + if(keys && keys.length) + { + for(const splitKey of keys) key = key.replace(splitKey, this.getValue(splitKey.slice(2, -1), doParams)); + } + + let value = (this._definitions.get(key) || null); + + if(!value) + { + value = (GetConfiguration().definitions.get(key) as any); + + if(value) return value; + } + + 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); + + if(parameters) + { + for(let i = 0; i < parameters.length; i++) + { + const parameter = parameters[i]; + const replacement = replacements[i]; + + if(replacement === undefined) continue; + + value = value.replace('%' + parameter + '%', replacement); + + if(value.startsWith('%{')) + { + const regex = new RegExp('%{' + parameter.toUpperCase() + '\\|([^|]*)\\|([^|]*)\\|([^|]*)}'); + const result = value.match(regex); + + if(!result) continue; + + const replacementAsNumber = parseInt(replacement); + + let indexKey = -1; + let replace = false; + + switch(replacementAsNumber) + { + case 0: + indexKey = 1; + break; + case 1: + indexKey = 2; + break; + case 2: + default: + indexKey = 3; + replace = true; + break; + } + + + if((indexKey === -1) || (typeof result[indexKey] === 'undefined')) continue; + + const valueFromResults = result[indexKey]; + + if(valueFromResults) + { + value = valueFromResults.replace('%%', replacement); + } + } + } + } + + 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 badge = new BadgeBaseAndLevel(key); + const keys = ['badge_name_' + key, 'badge_name_' + badge.base]; + + let name = this.fixBadLocalization(this.getExistingKey(keys)); + + name = name.replace('%roman%', this.getRomanNumeral(badge.level)); + + return name; + } + + public getBadgeDesc(key: string): string + { + const badge = new BadgeBaseAndLevel(key); + const keys = ['badge_desc_' + key, 'badge_desc_' + badge.base]; + + let desc = this.fixBadLocalization(this.getExistingKey(keys)); + + const limit = this.getBadgePointLimit(key); + + if(limit > -1) desc = desc.replace('%limit%', limit.toString()); + + desc = desc.replace('%roman%', this.getRomanNumeral(badge.level)); + + return desc; + } + + private getExistingKey(keys: string[]): string + { + for(const entry of keys) + { + const item = this.getValue(entry); + if(item != entry) return item; + } + + return ''; + } + + private fixBadLocalization(k: string): string + { + return k.replace('${', '$') + .replace('{', '$') + .replace('}', '$'); + } +} diff --git a/packages/localization/src/index.ts b/packages/localization/src/index.ts new file mode 100644 index 0000000..6d87b92 --- /dev/null +++ b/packages/localization/src/index.ts @@ -0,0 +1,3 @@ +export * from './BadgeBaseAndLevel'; +export * from './GetLocalization'; +export * from './LocalizationManager'; diff --git a/packages/localization/tsconfig.json b/packages/localization/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/localization/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/room/.eslintrc.json b/packages/room/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/room/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/room/.gitignore b/packages/room/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/room/.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/packages/room/index.ts b/packages/room/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/room/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/room/package.json b/packages/room/package.json new file mode 100644 index 0000000..367a78d --- /dev/null +++ b/packages/room/package.json @@ -0,0 +1,26 @@ +{ + "name": "@nitrots/room", + "description": "Nitro room module", + "version": "1.0.0", + "type": "module", + "license": "GPL-3.0", + "scripts": { + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/assets": "1.0.0", + "@nitrots/avatar": "1.0.0", + "@nitrots/communication": "1.0.0", + "@nitrots/configuration": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "@nitrots/events": "1.0.0", + "@nitrots/session": "1.0.0", + "pixi.js": "^8.0.4" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/room/src/GetRoomContentLoader.ts b/packages/room/src/GetRoomContentLoader.ts new file mode 100644 index 0000000..e4b5a53 --- /dev/null +++ b/packages/room/src/GetRoomContentLoader.ts @@ -0,0 +1,5 @@ +import { RoomContentLoader } from './RoomContentLoader'; + +const roomContentLoader = new RoomContentLoader(); + +export const GetRoomContentLoader = () => roomContentLoader; diff --git a/packages/room/src/GetRoomEngine.ts b/packages/room/src/GetRoomEngine.ts new file mode 100644 index 0000000..559514d --- /dev/null +++ b/packages/room/src/GetRoomEngine.ts @@ -0,0 +1,5 @@ +import { RoomEngine } from './RoomEngine'; + +const roomEngine = new RoomEngine(); + +export const GetRoomEngine = () => roomEngine; diff --git a/packages/room/src/GetRoomManager.ts b/packages/room/src/GetRoomManager.ts new file mode 100644 index 0000000..48e6a6a --- /dev/null +++ b/packages/room/src/GetRoomManager.ts @@ -0,0 +1,5 @@ +import { RoomManager } from './RoomManager'; + +const roomManager = new RoomManager(); + +export const GetRoomManager = () => roomManager; diff --git a/packages/room/src/GetRoomMessageHandler.ts b/packages/room/src/GetRoomMessageHandler.ts new file mode 100644 index 0000000..0fc3531 --- /dev/null +++ b/packages/room/src/GetRoomMessageHandler.ts @@ -0,0 +1,5 @@ +import { RoomMessageHandler } from './RoomMessageHandler'; + +const roomMessageHandler = new RoomMessageHandler(); + +export const GetRoomMessageHandler = () => roomMessageHandler; diff --git a/packages/room/src/GetRoomObjectLogicFactory.ts b/packages/room/src/GetRoomObjectLogicFactory.ts new file mode 100644 index 0000000..ec62540 --- /dev/null +++ b/packages/room/src/GetRoomObjectLogicFactory.ts @@ -0,0 +1,5 @@ +import { RoomObjectLogicFactory } from './RoomObjectLogicFactory'; + +const roomObjectLogicFactory = new RoomObjectLogicFactory(); + +export const GetRoomObjectLogicFactory = () => roomObjectLogicFactory; diff --git a/packages/room/src/GetRoomObjectVisualizationFactory.ts b/packages/room/src/GetRoomObjectVisualizationFactory.ts new file mode 100644 index 0000000..167d4ca --- /dev/null +++ b/packages/room/src/GetRoomObjectVisualizationFactory.ts @@ -0,0 +1,5 @@ +import { RoomObjectVisualizationFactory } from './RoomObjectVisualizationFactory'; + +const roomObjectVisualizationFactory = new RoomObjectVisualizationFactory(); + +export const GetRoomObjectVisualizationFactory = () => roomObjectVisualizationFactory; diff --git a/packages/room/src/ImageResult.ts b/packages/room/src/ImageResult.ts new file mode 100644 index 0000000..26ac1f4 --- /dev/null +++ b/packages/room/src/ImageResult.ts @@ -0,0 +1,19 @@ +import { IImageResult } from '@nitrots/api'; +import { TextureUtils } from '@nitrots/utils'; +import { Texture } from 'pixi.js'; + +export class ImageResult implements IImageResult +{ + public id: number = 0; + public data: Texture = null; + public image: HTMLImageElement = null; + + public async getImage(): Promise + { + if(this.image) return this.image; + + if(!this.data) return null; + + return await TextureUtils.generateImage(this.data); + } +} diff --git a/packages/room/src/PetColorResult.ts b/packages/room/src/PetColorResult.ts new file mode 100644 index 0000000..178863a --- /dev/null +++ b/packages/room/src/PetColorResult.ts @@ -0,0 +1,61 @@ +import { IPetColorResult } from '@nitrots/api'; + +export class PetColorResult implements IPetColorResult +{ + private static COLOR_TAGS: 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(primaryColor: number, secondaryColor: number, breed: number, tag: number, id: string, isMaster: boolean, layerTags: string[]) + { + this._layerTags = []; + this._primaryColor = (primaryColor & 0xFFFFFF); + this._secondaryColor = (secondaryColor & 0xFFFFFF); + this._breed = breed; + this._tag = (((tag > -1) && (tag < PetColorResult.COLOR_TAGS.length)) ? PetColorResult.COLOR_TAGS[tag] : ''); + this._id = id; + this._isMaster = isMaster; + this._layerTags = layerTags; + } + + public get primaryColor(): number + { + return this._primaryColor; + } + + public get secondaryColor(): 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 isMaster(): boolean + { + return this._isMaster; + } + + public get layerTags(): string[] + { + return this._layerTags; + } +} diff --git a/packages/room/src/RoomContentLoader.ts b/packages/room/src/RoomContentLoader.ts new file mode 100644 index 0000000..687d3c7 --- /dev/null +++ b/packages/room/src/RoomContentLoader.ts @@ -0,0 +1,512 @@ +import { FurnitureType, IEventDispatcher, IFurnitureData, IGraphicAssetCollection, IPetColorResult, IRoomContentListener, IRoomContentLoader, IRoomObject, RoomObjectCategory, RoomObjectUserType, RoomObjectVariable, RoomObjectVisualizationType } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { GetConfiguration } from '@nitrots/configuration'; +import { GetEventDispatcher, RoomContentLoadedEvent } from '@nitrots/events'; +import { GetSessionDataManager } from '@nitrots/session'; +import { NitroLogger } from '@nitrots/utils'; +import { Texture } from 'pixi.js'; +import { PetColorResult } from './PetColorResult'; + +export class RoomContentLoader implements IRoomContentLoader +{ + 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 MANDATORY_LIBRARIES: string[] = [RoomContentLoader.PLACE_HOLDER, RoomContentLoader.PLACE_HOLDER_WALL, RoomContentLoader.PLACE_HOLDER_PET, RoomContentLoader.ROOM, RoomContentLoader.TILE_CURSOR, RoomContentLoader.SELECTION_ARROW]; + + private _iconListener: IRoomContentListener; + private _images: Map = new Map(); + + private _activeObjects: { [index: string]: number } = {}; + private _activeObjectTypes: Map = new Map(); + private _activeObjectTypeIds: Map = new Map(); + private _objectTypeAdUrls: Map = new Map(); + private _wallItems: { [index: string]: number } = {}; + private _wallItemTypes: Map = new Map(); + private _wallItemTypeIds: Map = new Map(); + private _furniRevisions: Map = new Map(); + private _pets: { [index: string]: number } = {}; + private _petColors: Map> = new Map(); + private _objectAliases: Map = new Map(); + private _objectOriginalNames: Map = new Map(); + + private _pendingContentTypes: string[] = []; + + public async init(): Promise + { + this.processFurnitureData(GetSessionDataManager().getAllFurnitureData()); + + for(const [index, name] of GetConfiguration().getValue('pet.types').entries()) this._pets[name] = index; + + await Promise.all(RoomContentLoader.MANDATORY_LIBRARIES.map(value => this.downloadAsset(value))); + } + + public 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 getRoomObjectAdUrl(type: string): string + { + const value = this._objectTypeAdUrls.get(type); + + if(!value) return ''; + + return value; + } + + public getPetColorResult(petIndex: number, paletteIndex: number): IPetColorResult + { + const colorResults = this._petColors.get(petIndex); + + if(!colorResults) return null; + + return colorResults.get(paletteIndex); + } + + public getPetColorResultsForTag(petIndex: number, tagName: string): IPetColorResult[] + { + const colorResults = this._petColors.get(petIndex); + const results: IPetColorResult[] = []; + + if(colorResults) + { + for(const result of colorResults.values()) + { + if(result.tag === tagName) results.push(result); + } + } + + return results; + } + + public getCollection(name: string): IGraphicAssetCollection + { + return GetAssetManager().getCollection(name); + } + + 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, override: boolean = true): boolean + { + return GetAssetManager().addAssetToCollection(collectionName, assetName, texture, override); + } + + 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 === RoomContentLoader.TILE_CURSOR) || (type === RoomContentLoader.SELECTION_ARROW)) return RoomObjectCategory.CURSOR; + + return RoomObjectCategory.MINIMUM; + } + + public getPetNameForType(type: number): string + { + return GetConfiguration().getValue('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; + + NitroLogger.error('Failed to download asset', url); + + this._iconListener.onRoomContentLoaded(id, [type, param].join('_'), false); + }; + + return true; + } + + return false; + } + + public async downloadAsset(type: string): Promise + { + const assetUrl: string = this.getAssetUrls(type)?.[0]; + + if(!assetUrl || !assetUrl.length) return; + + if((this._pendingContentTypes.indexOf(type) >= 0)) return; + + this._pendingContentTypes.push(type); + + if(!await GetAssetManager().downloadAsset(assetUrl)) + { + GetEventDispatcher().dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_FAILURE, type)); + + return; + } + + const petIndex = this._pets[type]; + + if(petIndex !== undefined) + { + const collection = this.getCollection(type); + const keys = collection.getPaletteNames(); + const palettes: Map = new Map(); + + for(const key of keys) + { + const palette = collection.getPalette(key); + const paletteData = collection.data.palettes[key]; + + const primaryColor = palette.primaryColor; + const secondaryColor = palette.secondaryColor; + const breed = ((paletteData.breed !== undefined) ? paletteData.breed : 0); + const tag = ((paletteData.colorTag !== undefined) ? paletteData.colorTag : -1); + const master = ((paletteData.master !== undefined) ? paletteData.master : false); + const layerTags = ((paletteData.tags !== undefined) ? paletteData.tags : []); + + palettes.set(parseInt(key), new PetColorResult(primaryColor, secondaryColor, breed, tag, key, master, layerTags)); + } + + this._petColors.set(petIndex, palettes); + } + + GetEventDispatcher().dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_SUCCESS, type)); + } + + public getAssetAliasName(name: string): string + { + const existing = this._objectAliases.get(name); + + if(!existing) return name; + + return existing; + } + + public setAssetAliasName(name: string, originalName: string): void + { + this._objectAliases.set(name, originalName); + this._objectOriginalNames.set(originalName, name); + } + + 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.getAssetUrlWithGenericBase(RoomContentLoader.PLACE_HOLDER)]; + case RoomContentLoader.PLACE_HOLDER_WALL: + return [this.getAssetUrlWithGenericBase(RoomContentLoader.PLACE_HOLDER_WALL)]; + case RoomContentLoader.PLACE_HOLDER_PET: + return [this.getAssetUrlWithGenericBase(RoomContentLoader.PLACE_HOLDER_PET)]; + case RoomContentLoader.ROOM: + return [this.getAssetUrlWithGenericBase('room')]; + case RoomContentLoader.TILE_CURSOR: + return [this.getAssetUrlWithGenericBase(RoomContentLoader.TILE_CURSOR)]; + case RoomContentLoader.SELECTION_ARROW: + return [this.getAssetUrlWithGenericBase(RoomContentLoader.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 getAssetUrlWithGenericBase(assetName: string): string + { + return (GetConfiguration().getValue('generic.asset.url').replace(/%libname%/gi, assetName)); + } + + public getAssetUrlWithFurniBase(assetName: string): string + { + return (GetConfiguration().getValue('furni.asset.url').replace(/%libname%/gi, assetName)); + } + + public getAssetUrlWithFurniIconBase(assetName: string): string + { + return (GetConfiguration().getValue('furni.asset.icon.url').replace(/%libname%/gi, assetName)); + } + + public getAssetUrlWithPetBase(assetName: string): string + { + return (GetConfiguration().getValue('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); + } + + public setIconListener(listener: IRoomContentListener): void + { + this._iconListener = listener; + } + + public get pets(): { [index: string]: number } + { + return this._pets; + } +} diff --git a/packages/room/src/RoomEngine.ts b/packages/room/src/RoomEngine.ts new file mode 100644 index 0000000..cbc58ef --- /dev/null +++ b/packages/room/src/RoomEngine.ts @@ -0,0 +1,3266 @@ +import { IFurnitureStackingHeightMap, IGetImageListener, IImageResult, ILegacyWallGeometry, IObjectData, IPetColorResult, IPetCustomPart, IRoomContentListener, IRoomContentLoader, IRoomCreator, IRoomEngine, IRoomEngineServices, IRoomGeometry, IRoomInstance, IRoomManager, IRoomManagerListener, IRoomObject, IRoomObjectController, IRoomRenderer, IRoomRenderingCanvas, IRoomSessionManager, ISelectedRoomObjectData, ISessionDataManager, ITileObjectMap, IUpdateReceiver, IVector3D, LegacyDataType, MouseEventType, ObjectDataFactory, PetFigureData, RoomControllerLevel, RoomObjectCategory, RoomObjectUserType, RoomObjectVariable, ToolbarIconEnum } from '@nitrots/api'; +import { GetCommunication, RenderRoomMessageComposer, RenderRoomThumbnailMessageComposer } from '@nitrots/communication'; +import { GetConfiguration } from '@nitrots/configuration'; +import { BadgeImageReadyEvent, GetEventDispatcher, NitroToolbarAnimateIconEvent, RoomBackgroundColorEvent, RoomDragEvent, RoomEngineEvent, RoomEngineObjectEvent, RoomObjectEvent, RoomObjectFurnitureActionEvent, RoomObjectMouseEvent, RoomSessionEvent, RoomToObjectOwnAvatarMoveEvent } from '@nitrots/events'; +import { GetRoomSessionManager, GetSessionDataManager } from '@nitrots/session'; +import { FurniId, GetTickerTime, NitroLogger, NumberBank, TextureUtils, Vector3d } from '@nitrots/utils'; +import { Container, Matrix, Point, Rectangle, RenderTexture, Sprite, Texture, Ticker } from 'pixi.js'; +import { GetRoomContentLoader } from './GetRoomContentLoader'; +import { GetRoomManager } from './GetRoomManager'; +import { GetRoomMessageHandler } from './GetRoomMessageHandler'; +import { GetRoomObjectLogicFactory } from './GetRoomObjectLogicFactory'; +import { ImageResult } from './ImageResult'; +import { RoomInstance } from './RoomInstance'; +import { RoomObjectEventHandler } from './RoomObjectEventHandler'; +import { RoomVariableEnum } from './RoomVariableEnum'; +import { ObjectAvatarCarryObjectUpdateMessage, ObjectAvatarChatUpdateMessage, ObjectAvatarDanceUpdateMessage, ObjectAvatarEffectUpdateMessage, ObjectAvatarExperienceUpdateMessage, ObjectAvatarExpressionUpdateMessage, ObjectAvatarFigureUpdateMessage, ObjectAvatarFlatControlUpdateMessage, ObjectAvatarGestureUpdateMessage, ObjectAvatarGuideStatusUpdateMessage, ObjectAvatarMutedUpdateMessage, ObjectAvatarOwnMessage, ObjectAvatarPetGestureUpdateMessage, ObjectAvatarPlayerValueUpdateMessage, ObjectAvatarPlayingGameUpdateMessage, ObjectAvatarPostureUpdateMessage, ObjectAvatarSignUpdateMessage, ObjectAvatarSleepUpdateMessage, ObjectAvatarTypingUpdateMessage, ObjectAvatarUpdateMessage, ObjectAvatarUseObjectUpdateMessage, ObjectDataUpdateMessage, ObjectGroupBadgeUpdateMessage, ObjectHeightUpdateMessage, ObjectItemDataUpdateMessage, ObjectModelDataUpdateMessage, ObjectMoveUpdateMessage, ObjectRoomColorUpdateMessage, ObjectRoomFloorHoleUpdateMessage, ObjectRoomMaskUpdateMessage, ObjectRoomPlanePropertyUpdateMessage, ObjectRoomPlaneVisibilityUpdateMessage, ObjectRoomUpdateMessage, ObjectStateUpdateMessage, RoomObjectUpdateMessage } from './messages'; +import { RoomLogic, RoomMapData } from './object'; +import { RoomRenderer } from './renderer'; +import { RoomCamera, RoomData, RoomEnterEffect, RoomFurnitureData, RoomGeometry, RoomInstanceData, RoomObjectBadgeImageAssetListener } from './utils'; + +export class RoomEngine implements IRoomEngine, IRoomCreator, IRoomEngineServices, IRoomManagerListener, IRoomContentListener, IUpdateReceiver +{ + 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 _roomContentLoader: IRoomContentLoader = GetRoomContentLoader(); + private _roomSessionManager: IRoomSessionManager = GetRoomSessionManager(); + private _sessionDataManager: ISessionDataManager = GetSessionDataManager(); + private _roomManager: IRoomManager = GetRoomManager(); + + private _roomObjectEventHandler: RoomObjectEventHandler = new RoomObjectEventHandler(this); + private _imageObjectIdBank: NumberBank = new NumberBank(1000); + private _imageCallbacks: Map = new Map(); + private _thumbnailObjectIdBank: NumberBank = new NumberBank(1000); + private _thumbnailCallbacks: Map = new Map(); + private _activeRoomId: number = -1; + private _activeRoomActiveCanvas: number = -1; + private _activeRoomActiveCanvasMouseX: number = 0; + private _activeRoomActiveCanvasMouseY: number = 0; + private _activeRoomIsDragged: boolean = false; + private _activeRoomWasDragged: boolean = false; + private _activeRoomDragStartX: number = 0; + private _activeRoomDragStartY: number = 0; + private _activeRoomDragX: number = 0; + private _activeRoomDragY: number = 0; + private _roomDraggingAlwaysCenters: boolean = false; + private _roomAllowsDragging: boolean = true; + private _roomDatas: Map = new Map(); + private _roomInstanceDatas: Map = new Map(); + private _skipFurnitureCreationForNextFrame: boolean = false; + private _mouseCursorUpdate: boolean = false; + private _badgeListenerObjects: Map = new Map(); + + constructor() + { + this.onBadgeImageReadyEvent = this.onBadgeImageReadyEvent.bind(this); + } + + public async init(): Promise + { + GetRoomObjectLogicFactory().registerEventFunction(this.processRoomObjectEvent.bind(this)); + + GetEventDispatcher().addEventListener(RoomSessionEvent.STARTED, event => this.onRoomSessionEvent(event)); + GetEventDispatcher().addEventListener(RoomSessionEvent.ENDED, event => this.onRoomSessionEvent(event)); + + await GetRoomMessageHandler().init(); + await this._roomContentLoader.init(); + await this._roomManager.init(this); + + for(const roomData of this._roomDatas.values()) + { + if(!roomData) continue; + + this.createRoomInstance(roomData.roomId, roomData.data); + } + + this._roomContentLoader.setIconListener(this); + + 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); + } + + private onRoomSessionEvent(event: RoomSessionEvent): void + { + if(!(event instanceof RoomSessionEvent)) return; + + switch(event.type) + { + case RoomSessionEvent.STARTED: + GetRoomMessageHandler().setRoomId(event.session.roomId); + return; + case RoomSessionEvent.ENDED: + GetRoomMessageHandler().clearRoomId(); + this.removeRoomInstance(event.session.roomId); + return; + } + } + + 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(); + } + + GetEventDispatcher().dispatchEvent(new RoomEngineEvent(RoomEngineEvent.DISPOSED, roomId)); + } + + public createRoomInstance(roomId: number, roomMap: RoomMapData): void + { + let floorType = '111'; + let wallType = '201'; + let landscapeType = '1'; + + if(!roomMap) + { + NitroLogger.warn('Room property messages'); + + 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; + + this._roomAllowsDragging = true; + + GetEventDispatcher().dispatchEvent(new RoomEngineEvent(RoomEngineEvent.INITIALIZED, roomId)); + } + + private setupRoomInstance(roomId: number, roomMap: RoomMapData, floorType: string, wallType: string, landscapeType: string, worldType: string): IRoomInstance + { + if(!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) + { + 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 = Math.trunc((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); + + if(GetConfiguration().getValue('enable.avatar.arrow', false)) 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): Container + { + const instance = this.getRoomInstance(roomId); + + if(!instance) return null; + + let renderer = instance.renderer as IRoomRenderer; + + if(!renderer) + { + renderer = new RoomRenderer(); + + 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; + + 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; + + if(displayObject) + { + const overlay = new Container(); + + overlay.label = RoomEngine.OVERLAY; + + 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) + { + roomCanvas.setScale(scale, point, offsetPoint, override, asDelta); + + GetEventDispatcher().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; + + const x = ~~(point.x); + const y = ~~(point.y); + + if((renderingCanvas.screenOffsetX === x) && (renderingCanvas.screenOffsetY === y)) return; + + GetEventDispatcher().dispatchEvent(new RoomDragEvent(roomId, -(renderingCanvas.screenOffsetX - x), -(renderingCanvas.screenOffsetY - y))); + + renderingCanvas.screenOffsetX = x; + renderingCanvas.screenOffsetY = 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 updateObjectRoomColor(roomId: number, color: number, light: number, backgroundOnly: boolean): boolean + { + const roomObject = this.getRoomOwnObject(roomId); + + if(!roomObject || !roomObject.logic) return false; + + const event = new ObjectRoomColorUpdateMessage(ObjectRoomColorUpdateMessage.BACKGROUND_COLOR, color, light, backgroundOnly); + + roomObject.logic.processUpdateMessage(event); + + GetEventDispatcher().dispatchEvent(new RoomBackgroundColorEvent(roomId, color, light, backgroundOnly)); + + 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) + { + GetEventDispatcher().dispatchEvent(new RoomEngineEvent(RoomEngineEvent.NORMAL_MODE, roomId)); + } + else + { + GetEventDispatcher().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 update(ticker: Ticker): void + { + if(!this._roomManager) return; + + const time = ticker.lastTime; + const update = false; + + RoomEnterEffect.turnVisualizationOn(); + + this.processPendingFurniture(); + + this._roomManager.update(time, update); + + this.updateRoomCameras(time); + + if(this._mouseCursorUpdate) this.setPointer(); + + RoomEnterEffect.turnVisualizationOff(); + } + + private setPointer(): void + { + this._mouseCursorUpdate = false; + + const instanceData = this.getRoomInstanceData(this._activeRoomId); + + if(instanceData && instanceData.hasButtonMouseCursorOwners()) + { + 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: RoomFurnitureData = 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; + } + } + + private processPendingFurnitureFloor(roomId: number, id: number, data: RoomFurnitureData): 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_AD_URL, this.getRoomObjectAdUrl(data.type)); + 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, GetTickerTime()); + 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(GetEventDispatcher()) GetEventDispatcher().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.addObjectToTileMap(roomId, object); + + return true; + } + + private processPendingFurnitureWall(roomId: number, id: number, data: RoomFurnitureData): 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_AD_URL, this.getRoomObjectAdUrl(data.type)); + 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, GetTickerTime()); + 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(GetEventDispatcher()) GetEventDispatcher().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 + { + const session = this._roomSessionManager.getSession(roomId); + + if(session) + { + session.setOwnRoomIndex(objectId); + } + + const camera = this.getRoomCamera(roomId); + + if(camera) + { + camera.targetId = objectId; + camera.targetCategory = RoomObjectCategory.UNIT; + + camera.activateFollowing(this.cameraFollowDuration); + } + } + + private get cameraFollowDuration(): number + { + return 1000; + //return (getBoolean("room.camera.follow_user")) ? 1000 : 0; + } + + private updateRoomCameras(time: number): void + { + for(const instanceData of this._roomInstanceDatas.values()) + { + if(!instanceData) continue; + + const camera = instanceData.roomCamera; + + if(!camera) continue; + + let location: IVector3D = null; + + const object = this.getRoomObject(instanceData.roomId, camera.targetId, camera.targetCategory); + + if(object) location = object.getLocation(); + + if(!location) continue; + + if((instanceData.roomId !== this._activeRoomId) || !this._activeRoomIsDragged) + { + this.updateRoomCamera(instanceData.roomId, 1, location, time); + } + } + + if(this._activeRoomWasDragged) + { + const renderingCanvas = this.getRoomInstanceRenderingCanvas(this._activeRoomId, 1); + + if(renderingCanvas) this.setRoomInstanceRenderingCanvasOffset(this._activeRoomId, 1, new Point((renderingCanvas.screenOffsetX + this._activeRoomDragX), (renderingCanvas.screenOffsetY + this._activeRoomDragY))); + + this._activeRoomDragX = 0; + this._activeRoomDragY = 0; + } + } + + private updateRoomCamera(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.getRoomCanvasRectangle(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.screenWd !== width) || (roomCamera.screenHt !== height) || (roomCamera.scale !== roomGeometry.scale) || (roomCamera.geometryUpdateId !== roomGeometry.updateId) || !Vector3d.isEqual(objectLocation, roomCamera.targetObjectLoc) || roomCamera.isMoving) + { + roomCamera.targetObjectLoc = 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.limitedLocationX) && (roomCamera.screenWd == width)) && (roomCamera.screenHt == height))) + { + _local_42 = 0; + } + if((((roomCamera.limitedLocationY) && (roomCamera.screenWd == width)) && (roomCamera.screenHt == 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.useOffsetScrolling) + { + roomCamera.initializeLocation(new Vector3d(0, 0, 0)); + } + else + { + roomCamera.initializeLocation(_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.centeredLocX))) || (((_local_33.y < canvasRectangle.top) || (_local_33.y > canvasRectangle.bottom)) && (!(roomCamera.centeredLocY)))) || (((_local_36) && (!(roomCamera.centeredLocX))) && (!(roomCamera.screenWd == width)))) || (((_local_37) && (!(roomCamera.centeredLocY))) && (!(roomCamera.screenHt == height)))) || ((!(roomCamera.roomWd == bounds.width)) || (!(roomCamera.roomHt == bounds.height)))) || ((!(roomCamera.screenWd == width)) || (!(roomCamera.screenHt == height))))) + { + roomCamera.limitedLocationX = _local_34; + roomCamera.limitedLocationY = _local_35; + if(this.useOffsetScrolling) + { + roomCamera.target = _local_46; + } + else + { + roomCamera.target = _local_15; + } + } + else + { + if(!_local_34) roomCamera.limitedLocationX = false; + + if(!_local_35) roomCamera.limitedLocationY = false; + } + } + + roomCamera.centeredLocX = _local_36; + roomCamera.centeredLocY = _local_37; + roomCamera.screenWd = width; + roomCamera.screenHt = height; + roomCamera.scale = roomGeometry.scale; + roomCamera.geometryUpdateId = roomGeometry.updateId; + roomCamera.roomWd = bounds.width; + roomCamera.roomHt = bounds.height; + + if(!this._sessionDataManager.isCameraFollowDisabled) + { + if(this.useOffsetScrolling) + { + roomCamera.update(time, 8); + } + else + { + roomCamera.update(time, 0.5); + } + } + + if(this.useOffsetScrolling) + { + this.setRoomInstanceRenderingCanvasOffset(this.activeRoomId, 1, new Point(-(roomCamera.location.x), -(roomCamera.location.y))); + } + else + { + roomGeometry.adjustLocation(roomCamera.location, 25); + } + } + else + { + roomCamera.limitedLocationX = false; + roomCamera.limitedLocationY = false; + roomCamera.centeredLocX = false; + roomCamera.centeredLocY = false; + } + } + + private getRoomCanvasRectangle(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; + + screenPoint.x = Math.round(screenPoint.x); + screenPoint.y = Math.round(screenPoint.y); + + 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 += (Math.round(canvas.width / 2) + canvas.screenOffsetX); + rectangle.y += (Math.round(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 + { + return this._roomContentLoader.getFurnitureFloorNameForTypeId(typeId); + } + + public getFurnitureWallName(typeId: number, extra: string = null): string + { + return this._roomContentLoader.getFurnitureWallNameForTypeId(typeId, extra); + } + + public getFurnitureFloorColorIndex(typeId: number): number + { + return this._roomContentLoader.getFurnitureFloorColorIndex(typeId); + } + + public getFurnitureWallColorIndex(typeId: number): number + { + 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): ITileObjectMap + { + 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): ISelectedRoomObjectData + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + return instanceData.selectedObject; + } + + public setSelectedRoomObjectData(roomId: number, data: ISelectedRoomObjectData): void + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + instanceData.setSelectedObject(data); + + if(data) instanceData.setPlacedObject(null); + } + + public getPlacedRoomObjectData(roomId: number): ISelectedRoomObjectData + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + return instanceData.placedObject; + } + + public setPlacedRoomObjectData(roomId: number, data: ISelectedRoomObjectData): 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): IFurnitureStackingHeightMap + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + return instanceData.furnitureStackingHeightMap; + } + + public setFurnitureStackingHeightMap(roomId: number, heightMap: IFurnitureStackingHeightMap): void + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + instanceData.setFurnitureStackingHeightMap(heightMap); + } + + public getLegacyWallGeometry(roomId: number): ILegacyWallGeometry + { + 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 + { + 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 + { + 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 === 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) + { + (async () => + { + const image = await TextureUtils.generateImage(icon); + const event = new NitroToolbarAnimateIconEvent(image, screenLocation.x, screenLocation.y); + + event.iconName = ToolbarIconEnum.INVENTORY; + + GetEventDispatcher().dispatchEvent(event); + })(); + } + } + } + } + } + + this.removeRoomObject(roomId, objectId, RoomObjectCategory.FLOOR); + this.setMouseDefault(roomId, RoomObjectCategory.FLOOR, objectId); + + if(_arg_4) this.refreshTileObjectMap(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 === 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) + { + (async () => + { + const image = await TextureUtils.generateImage(icon); + + if(GetEventDispatcher()) + { + const event = new NitroToolbarAnimateIconEvent(image, screenLocation.x, screenLocation.y); + + event.iconName = ToolbarIconEnum.INVENTORY; + + GetEventDispatcher().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(GetEventDispatcher()) GetEventDispatcher().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 RoomFurnitureData(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 RoomFurnitureData(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 RoomFurnitureData(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 = null): 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, GetTickerTime()); + + 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, GetTickerTime()); + + 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.REMOVE_MASK, maskName); + } + } + else + { + maskUpdate = new ObjectRoomMaskUpdateMessage(ObjectRoomMaskUpdateMessage.REMOVE_MASK, 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(GetEventDispatcher()) GetEventDispatcher().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.getSession(roomId); + + if(roomSession && (roomSession.ownRoomIndex === objectId)) + { + GetEventDispatcher().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.getFloorAltitude(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)); + } + + GetEventDispatcher().dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.CONTENT_UPDATED, id, objectId, category)); + } + + if(roomId !== RoomEngine.TEMPORARY_ROOM) this.addObjectToTileMap(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 + { + let roomObject: IRoomObjectController = null; + + if(roomId === 0) + { + const room = this._roomManager.getRoomInstance(RoomEngine.TEMPORARY_ROOM); + + if(room) roomObject = (room.getRoomObject(objectId, objectCategory) as IRoomObjectController); + } + else + { + 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) + { + GetEventDispatcher().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 + { + 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) + { + GetEventDispatcher().removeEventListener(BadgeImageReadyEvent.IMAGE_READY, this.onBadgeImageReadyEvent); + } + } + + private putBadgeInObjectAssets(object: IRoomObjectController, badgeId: string, groupBadge: boolean = false): void + { + 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, false); + } + + 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.getOverlayIconSprite(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.handleRoomDragging(canvas, x, y, type, altKey, ctrlKey, shiftKey)) + { + if(!canvas.handleMouseEvent(x, y, type, altKey, ctrlKey, shiftKey, buttonDown)) + { + let eventType: string = null; + + if(type === MouseEventType.MOUSE_CLICK) + { + if(GetEventDispatcher()) + { + GetEventDispatcher().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_DOWN_LONG) eventType = RoomObjectMouseEvent.MOUSE_DOWN_LONG; + + 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 handleRoomDragging(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.useOffsetScrolling) + { + if(!camera.isMoving) + { + camera.centeredLocX = false; + camera.centeredLocY = false; + } + + camera.resetLocation(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 + { + 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.addButtonMouseCursorOwner((category + '_' + objectId))) this._mouseCursorUpdate = true; + } + } + } + + private setMouseDefault(roomId: number, category: number, objectId: number): void + { + const instanceData = this.getRoomInstanceData(roomId); + + if(instanceData) + { + if(instanceData.removeButtonMouseCursorOwner((category + '_' + objectId))) this._mouseCursorUpdate = true; + } + } + + public processRoomObjectOperation(objectId: number, category: number, operation: string): boolean + { + if(!this._roomObjectEventHandler) return false; + + this._roomObjectEventHandler.modifyRoomObject(this._activeRoomId, objectId, category, operation); + } + + public modifyRoomObjectDataWithMap(objectId: number, category: number, operation: string, data: Map): boolean + { + if(!this._roomObjectEventHandler) return false; + + if(category !== RoomObjectCategory.FLOOR) return; + + this._roomObjectEventHandler.modifyRoomObjectDataWithMap(this._activeRoomId, objectId, category, operation, data); + } + + public modifyRoomObjectData(objectId: number, category: number, colorHex: string, data: string): boolean + { + if(!this._roomObjectEventHandler) return false; + + if(category !== RoomObjectCategory.WALL) return; + + this._roomObjectEventHandler.modifyWallItemData(this._activeRoomId, objectId, colorHex, 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); + + screenPoint.x = Math.round(screenPoint.x); + screenPoint.y = Math.round(screenPoint.y); + + return screenPoint; + } + + public selectRoomObject(roomId: number, objectId: number, objectCategory: number): void + { + if(!this._roomObjectEventHandler) return; + + this._roomObjectEventHandler.setSelectedObject(roomId, objectId, objectCategory); + } + + public setSelectedAvatar(roomId: number, objectId: number): void + { + if(this._roomObjectEventHandler) return; + + this._roomObjectEventHandler.setSelectedAvatar(roomId, objectId, true); + } + + public cancelRoomObjectInsert(): void + { + if(!this._roomObjectEventHandler) return; + + this._roomObjectEventHandler.cancelRoomObjectInsert(this._activeRoomId); + } + + private addOverlayIconSprite(container: Container, label: string, texture: Texture, scale: number = 1): Sprite + { + if(!container || !texture) return; + + let sprite = this.getOverlayIconSprite(container, label); + + if(sprite) return null; + + sprite = new Sprite(texture); + + sprite.label = label; + + sprite.scale.set(scale); + + container.addChild(sprite); + + return sprite; + } + + public onRoomContentLoaded(id: number, assetName: string, success: boolean): void + { + if(id === -1) return; + + this._thumbnailObjectIdBank.freeNumber((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 setObjectMoverIconSprite(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: IImageResult = null; + const scale = 1; + + if(_arg_3) + { + imageResult = this.getRoomObjectImage(this._activeRoomId, objectId, category, new Vector3d(), 1, null); + } + else + { + 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.removeOverlayIconSprite(overlay, RoomEngine.OBJECT_ICON_SPRITE); + + const _local_15 = this.addOverlayIconSprite(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): IImageResult + { + 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 + { + const type = this._roomContentLoader.getFurnitureFloorNameForTypeId(typeId); + const color = this._roomContentLoader.getFurnitureFloorColorIndex(typeId).toString(); + + return this._roomContentLoader.getAssetIconUrl(type, color); + } + + public getFurnitureFloorIcon(typeId: number, listener: IGetImageListener, extras: string = null, objectData: IObjectData = null): IImageResult + { + return this.getFurnitureFloorImage(typeId, new Vector3d(), 1, listener, 0, extras, -1, -1, objectData); + } + + public getFurnitureWallIconUrl(typeId: number, extra: string = null): string + { + const type: string = this._roomContentLoader.getFurnitureWallNameForTypeId(typeId, extra); + const color = this._roomContentLoader.getFurnitureWallColorIndex(typeId).toString(); + + return this._roomContentLoader.getAssetIconUrl(type, color); + } + + public getFurnitureWallIcon(typeId: number, listener: IGetImageListener, extras: string = null): IImageResult + { + 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): IImageResult + { + const type: string = this._roomContentLoader.getFurnitureFloorNameForTypeId(typeId); + const 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): IImageResult + { + const type: string = this._roomContentLoader.getFurnitureWallNameForTypeId(typeId); + const 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, headOnly: boolean = false, bgColor: number = 0, customParts: IPetCustomPart[] = null, posture: string = null): IImageResult + { + let type: string = null; + let value = ((((typeId + ' ') + paletteId) + ' ') + color.toString(16)); + + if(headOnly) 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)); + } + } + + 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): IImageResult + { + if(!this._roomManager) return null; + + const imageResult = new ImageResult(); + + imageResult.id = -1; + + if(!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.reserveNumber(); + 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(); + + 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.freeNumber((objectId - 1)); + + imageResult.id = 0; + } + + geometry.dispose(); + + return imageResult; + } + + public getGenericRoomObjectThumbnail(type: string, param: string, listener: IGetImageListener, extraData: string = null, stuffData: IObjectData = null): IImageResult + { + if(!this._roomManager) return null; + + const imageResult = new ImageResult(); + + imageResult.id = -1; + + if(!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.reserveNumber(); + 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.freeNumber((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) 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.freeNumber((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 setObjectMoverIconSpriteVisible(k: boolean): void + { + const canvas = this.getActiveRoomInstanceRenderingCanvas(); + + if(!canvas) return; + + const overlay = this.getRenderingCanvasOverlay(canvas); + const sprite = this.getOverlayIconSprite(overlay, RoomEngine.OBJECT_ICON_SPRITE); + + if(sprite) + { + sprite.visible = k; + } + } + + public removeObjectMoverIconSprite(): void + { + const canvas = this.getActiveRoomInstanceRenderingCanvas(); + + if(!canvas) return; + + const overlayContainer = this.getRenderingCanvasOverlay(canvas); + + this.removeOverlayIconSprite(overlayContainer, RoomEngine.OBJECT_ICON_SPRITE); + } + + private getRenderingCanvasOverlay(canvas: IRoomRenderingCanvas): Container + { + if(!canvas) return null; + + const displayObject = canvas.master; + + if(!displayObject) return null; + + return displayObject.getChildByName(RoomEngine.OVERLAY) ?? null; + } + + private removeOverlayIconSprite(container: Container, label: string): boolean + { + if(!container) return false; + + let index = (container.children.length - 1); + + while(index >= 0) + { + const child = (container.getChildAt(index) as Sprite); + + if(child) + { + if(child.label === label) + { + container.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 getOverlayIconSprite(container: Container, label: string): Sprite + { + if(!container) return null; + + let index = (container.children.length - 1); + + while(index >= 0) + { + const child = (container.getChildAt(index) as Sprite); + + if(child) + { + if(child.label === label) return child; + } + + index--; + } + + return null; + } + + public getRoomObjects(roomId: number, category: number): IRoomObject[] + { + const _local_3 = this.getRoomId(roomId); + const _local_4 = this._roomManager.getRoomInstance(_local_3); + + + if(_local_4) return _local_4.getRoomObjectsForCategory(category); + + return []; + } + + protected addObjectToTileMap(k: number, _arg_2: IRoomObject): void + { + const tileObjectMap = this.getRoomInstanceData(k).tileObjectMap; + + if(tileObjectMap) tileObjectMap.addRoomObject(_arg_2); + } + + public refreshTileObjectMap(k: number, _arg_2: string): void + { + const tileObjectMap = this.getRoomInstanceData(k).tileObjectMap; + + if(tileObjectMap) tileObjectMap.populate(this.getRoomObjects(k, RoomObjectCategory.FLOOR)); + } + + public createTextureFromRoom(roomId: number, canvasId: number = -1, bounds: Rectangle = null): Texture + { + let canvas: IRoomRenderingCanvas = null; + + if(canvasId > -1) + { + canvas = this.getRoomInstanceRenderingCanvas(this._activeRoomId, canvasId); + } + else + { + canvas = this.getActiveRoomInstanceRenderingCanvas(); + } + + let texture: Texture = null; + + if(bounds) + { + texture = TextureUtils.generateTexture({ + target: canvas.master, + frame: bounds + }); + } + else + { + texture = canvas.getDisplayAsTexture(); + } + + return texture; + } + + public async saveTextureAsScreenshot(texture: RenderTexture, saveAsThumbnail: boolean = false): Promise + { + let composer: RenderRoomMessageComposer = null; + + if(saveAsThumbnail) composer = new RenderRoomThumbnailMessageComposer(); + else composer = new RenderRoomMessageComposer(); + + await composer.assignBitmap(texture); + + GetCommunication().connection.send(composer); + } + + public saveBase64AsScreenshot(base64: string, saveAsThumbnail: boolean = false): void + { + let composer: RenderRoomMessageComposer = null; + + if(saveAsThumbnail) composer = new RenderRoomThumbnailMessageComposer(); + else composer = new RenderRoomMessageComposer(); + + composer.assignBase64(base64); + + GetCommunication().connection.send(composer); + } + + public objectsInitialized(k: string): void + { + const roomId = this.getRoomIdFromString(k); + + GetEventDispatcher().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]) || 0); + } + + private getRoomObjectRoomId(object: IRoomObject): string + { + if(!object || !object.model) return null; + + return (object.model.getValue(RoomObjectVariable.OBJECT_ROOM_ID)); + } + + private getRoomObjectAdUrl(type: string): string + { + return this._roomContentLoader.getRoomObjectAdUrl(type); + } + + 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]); + + return this._roomContentLoader.getPetNameForType(typeId); + } + + return null; + } + + public isRoomContentTypeLoaded(name: string): boolean + { + return (this._roomContentLoader.getCollection(name) !== null); + } + + public getPetColorResult(petIndex: number, paletteIndex: number): IPetColorResult + { + return this._roomContentLoader.getPetColorResult(petIndex, paletteIndex); + } + + public getPetColorResultsForTag(petIndex: number, tagName: string): IPetColorResult[] + { + return this._roomContentLoader.getPetColorResultsForTag(petIndex, tagName); + } + + public deleteRoomObject(objectId: number, objectCategory: number): boolean + { + if(!this._roomObjectEventHandler || (objectCategory !== RoomObjectCategory.WALL)) return false; + + return this._roomObjectEventHandler.deleteWallItem(this._activeRoomId, objectId); + } + + public get roomManager(): IRoomManager + { + return this._roomManager; + } + + public set roomManager(manager: IRoomManager) + { + this._roomManager = manager; + } + + public get objectEventHandler(): RoomObjectEventHandler + { + return this._roomObjectEventHandler; + } + + public get activeRoomId(): number + { + return this._activeRoomId; + } + + public get isDecorating(): boolean + { + const session = this._roomSessionManager.getSession(this._activeRoomId); + + return (session && session.isDecorating) || false; + } + + private get useOffsetScrolling(): 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/packages/room/src/RoomInstance.ts b/packages/room/src/RoomInstance.ts new file mode 100644 index 0000000..2cbe78a --- /dev/null +++ b/packages/room/src/RoomInstance.ts @@ -0,0 +1,287 @@ +import { IRoomInstance, IRoomInstanceContainer, IRoomObject, IRoomObjectController, IRoomObjectManager, IRoomObjectModel, IRoomRendererBase } from '@nitrots/api'; +import { RoomObjectModel } from './object'; + +export class RoomInstance implements IRoomInstance +{ + private _id: string; + private _container: IRoomInstanceContainer; + private _renderer: IRoomRendererBase = null; + private _managers: Map = new Map(); + private _updateCategories: number[] = []; + private _model: IRoomObjectModel = new RoomObjectModel(); + + constructor(id: string, container: IRoomInstanceContainer) + { + this._id = id; + this._container = container; + } + + public dispose(): 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; + } +} diff --git a/packages/room/src/RoomManager.ts b/packages/room/src/RoomManager.ts new file mode 100644 index 0000000..c4f00bc --- /dev/null +++ b/packages/room/src/RoomManager.ts @@ -0,0 +1,308 @@ +import { IGraphicAssetCollection, IRoomInstance, IRoomInstanceContainer, IRoomManager, IRoomManagerListener, IRoomObject, IRoomObjectController, IRoomObjectManager } from '@nitrots/api'; +import { GetEventDispatcher, RoomContentLoadedEvent } from '@nitrots/events'; +import { NitroLogger } from '@nitrots/utils'; +import { GetRoomContentLoader } from './GetRoomContentLoader'; +import { GetRoomObjectLogicFactory } from './GetRoomObjectLogicFactory'; +import { GetRoomObjectVisualizationFactory } from './GetRoomObjectVisualizationFactory'; +import { RoomInstance } from './RoomInstance'; +import { RoomObjectManager } from './RoomObjectManager'; + +export class RoomManager implements IRoomManager, IRoomInstanceContainer +{ + private _rooms: Map = new Map(); + private _updateCategories: number[] = []; + + private _listener: IRoomManagerListener; + + private _pendingContentTypes: string[] = []; + private _skipContentProcessing: boolean = false; + + constructor() + { + this.onRoomContentLoadedEvent = this.onRoomContentLoadedEvent.bind(this); + } + + public async init(listener: IRoomManagerListener): Promise + { + this._listener = listener; + + GetEventDispatcher().addEventListener(RoomContentLoadedEvent.RCLE_SUCCESS, this.onRoomContentLoadedEvent); + GetEventDispatcher().addEventListener(RoomContentLoadedEvent.RCLE_FAILURE, this.onRoomContentLoadedEvent); + GetEventDispatcher().addEventListener(RoomContentLoadedEvent.RCLE_CANCEL, this.onRoomContentLoadedEvent); + } + + 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(GetRoomContentLoader().isLoaderType(type)) + { + asset = GetRoomContentLoader().getCollection(type); + + if(!asset) + { + isLoading = true; + + GetRoomContentLoader().downloadAsset(type); + + assetName = GetRoomContentLoader().getPlaceholderName(type); + asset = GetRoomContentLoader().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; + + const visualizationInstance = GetRoomObjectVisualizationFactory().getVisualization(visualization); + + if(!visualizationInstance) + { + instance.removeRoomObject(objectId, category); + + return null; + } + + visualizationInstance.asset = asset; + + const visualizationData = GetRoomObjectVisualizationFactory().getVisualizationData(assetName, visualization, ((asset && asset.data) || null)); + + if(!visualizationData || !visualizationInstance.initialize(visualizationData)) + { + instance.removeRoomObject(objectId, category); + + return null; + } + + object.setVisualization(visualizationInstance); + + const logicInstance = GetRoomObjectLogicFactory().getLogic(logic); + + object.setLogic(logicInstance); + + if(logicInstance) + { + logicInstance.initialize((asset && asset.data) || null); + } + + if(!isLoading) object.isReady = true; + + GetRoomContentLoader().setRoomObjectRoomId(object, roomId); + + return object; + } + + private reinitializeRoomObjectsByType(type: string): void + { + if(!type || !GetRoomContentLoader()) return; + + const asset = GetRoomContentLoader().getCollection(type); + + if(!asset) return; + + const visualization = asset.data.visualizationType; + const logic = asset.data.logicType; + const visualizationData = GetRoomObjectVisualizationFactory().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 = GetRoomObjectVisualizationFactory().getVisualization(visualization); + + if(visualizationInstance) + { + visualizationInstance.asset = asset; + + if(!visualizationData || !visualizationInstance.initialize(visualizationData)) + { + manager.removeObject(object.id); + } + else + { + object.setVisualization(visualizationInstance); + + const logicInstance = GetRoomObjectLogicFactory().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); + } + } + + private processPendingContentTypes(time: number): void + { + if(this._skipContentProcessing) + { + this._skipContentProcessing = false; + + return; + } + + while(this._pendingContentTypes.length) + { + const type = this._pendingContentTypes.shift(); + + const collection = GetRoomContentLoader().getCollection(type); + + if(!collection) + { + if(this._listener) + { + this._listener.initalizeTemporaryObjectsByType(type, false); + } + + NitroLogger.log('Invalid Collection', type); + + continue; + } + + this.reinitializeRoomObjectsByType(type); + + if(this._listener) this._listener.initalizeTemporaryObjectsByType(type, true); + } + } + + private onRoomContentLoadedEvent(event: RoomContentLoadedEvent): void + { + if(!GetRoomContentLoader()) 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; + } +} diff --git a/packages/room/src/RoomMessageHandler.ts b/packages/room/src/RoomMessageHandler.ts new file mode 100644 index 0000000..246702b --- /dev/null +++ b/packages/room/src/RoomMessageHandler.ts @@ -0,0 +1,960 @@ +import { AvatarGuideStatus, IConnection, IRoomCreator, IVector3D, LegacyDataType, ObjectRolling, PetType, RoomObjectType, RoomObjectUserType, RoomObjectVariable } from '@nitrots/api'; +import { DiceValueMessageEvent, FloorHeightMapEvent, FurnitureAliasesComposer, FurnitureAliasesEvent, FurnitureDataEvent, FurnitureFloorAddEvent, FurnitureFloorDataParser, FurnitureFloorEvent, FurnitureFloorRemoveEvent, FurnitureFloorUpdateEvent, FurnitureWallAddEvent, FurnitureWallDataParser, FurnitureWallEvent, FurnitureWallRemoveEvent, FurnitureWallUpdateEvent, GetCommunication, GetRoomEntryDataMessageComposer, GuideSessionEndedMessageEvent, GuideSessionErrorMessageEvent, GuideSessionStartedMessageEvent, IgnoreResultEvent, ItemDataUpdateMessageEvent, ObjectsDataUpdateEvent, ObjectsRollingEvent, OneWayDoorStatusMessageEvent, PetExperienceEvent, PetFigureUpdateEvent, RoomEntryTileMessageEvent, RoomEntryTileMessageParser, RoomHeightMapEvent, RoomHeightMapUpdateEvent, RoomPaintEvent, RoomReadyMessageEvent, RoomUnitChatEvent, RoomUnitChatShoutEvent, RoomUnitChatWhisperEvent, RoomUnitDanceEvent, RoomUnitEffectEvent, RoomUnitEvent, RoomUnitExpressionEvent, RoomUnitHandItemEvent, RoomUnitIdleEvent, RoomUnitInfoEvent, RoomUnitNumberEvent, RoomUnitRemoveEvent, RoomUnitStatusEvent, RoomUnitTypingEvent, RoomVisualizationSettingsEvent, UserInfoEvent, YouArePlayingGameEvent } from '@nitrots/communication'; +import { GetRoomSessionManager, GetSessionDataManager } from '@nitrots/session'; +import { Vector3d } from '@nitrots/utils'; +import { GetRoomEngine } from './GetRoomEngine'; +import { RoomVariableEnum } from './RoomVariableEnum'; +import { RoomPlaneParser } from './object/RoomPlaneParser'; +import { FurnitureStackingHeightMap, LegacyWallGeometry } from './utils'; + +export class RoomMessageHandler +{ + private _connection: IConnection = null; + private _roomEngine: IRoomCreator = null; + private _planeParser = new RoomPlaneParser(); + private _latestEntryTileEvent: RoomEntryTileMessageEvent = null; + + private _currentRoomId: number = 0; + private _ownUserId: number = 0; + private _initialConnection: boolean = true; + private _guideId: number = -1; + private _requesterId: number = -1; + + public async init(): Promise + { + this._connection = GetCommunication().connection; + this._roomEngine = GetRoomEngine(); + + this._connection.addMessageEvent(new UserInfoEvent(this.onUserInfoEvent.bind(this))); + this._connection.addMessageEvent(new RoomReadyMessageEvent(this.onRoomReadyMessageEvent.bind(this))); + this._connection.addMessageEvent(new RoomPaintEvent(this.onRoomPaintEvent.bind(this))); + this._connection.addMessageEvent(new FloorHeightMapEvent(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 RoomVisualizationSettingsEvent(this.onRoomThicknessEvent.bind(this))); + this._connection.addMessageEvent(new RoomEntryTileMessageEvent(this.onRoomDoorEvent.bind(this))); + this._connection.addMessageEvent(new ObjectsRollingEvent(this.onRoomRollingEvent.bind(this))); + this._connection.addMessageEvent(new ObjectsDataUpdateEvent(this.onObjectsDataUpdateEvent.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 ItemDataUpdateMessageEvent(this.onItemDataUpdateMessageEvent.bind(this))); + this._connection.addMessageEvent(new OneWayDoorStatusMessageEvent(this.onOneWayDoorStatusMessageEvent.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 PetExperienceEvent(this.onPetExperienceEvent.bind(this))); + this._connection.addMessageEvent(new YouArePlayingGameEvent(this.onYouArePlayingGameEvent.bind(this))); + this._connection.addMessageEvent(new DiceValueMessageEvent(this.onDiceValueMessageEvent.bind(this))); + this._connection.addMessageEvent(new IgnoreResultEvent(this.onIgnoreResultEvent.bind(this))); + this._connection.addMessageEvent(new GuideSessionStartedMessageEvent(this.onGuideSessionStartedMessageEvent.bind(this))); + this._connection.addMessageEvent(new GuideSessionEndedMessageEvent(this.onGuideSessionEndedMessageEvent.bind(this))); + this._connection.addMessageEvent(new GuideSessionErrorMessageEvent(this.onGuideSessionErrorMessageEvent.bind(this))); + } + + public setRoomId(id: number): void + { + if(this._currentRoomId !== 0) + { + if(this._roomEngine) this._roomEngine.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 onRoomReadyMessageEvent(event: RoomReadyMessageEvent): void + { + const parser = event.getParser(); + + if(this._currentRoomId !== parser.roomId) + { + this.setRoomId(parser.roomId); + } + + if(this._roomEngine) + { + this._roomEngine.setRoomInstanceModelName(parser.roomId, parser.name); + } + + if(this._initialConnection) + { + event.connection.send(new FurnitureAliasesComposer()); + + this._initialConnection = false; + + return; + } + + event.connection.send(new GetRoomEntryDataMessageComposer()); + } + + 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._roomEngine) + { + this._roomEngine.updateRoomInstancePlaneType(this._currentRoomId, floorType, wallType, landscapeType); + } + } + + private onRoomModelEvent(event: FloorHeightMapEvent): void + { + if(!(event instanceof FloorHeightMapEvent) || !event.connection || !this._roomEngine) return; + + const parser = event.getParser(); + + if(!parser) return; + + const wallGeometry = this._roomEngine.getLegacyWallGeometry(this._currentRoomId); + + if(!wallGeometry) return; + + this._planeParser.reset(); + + const width = parser.width; + const height = parser.height; + + this._planeParser.initializeTileMap(width, height); + + let entryTile: RoomEntryTileMessageParser = 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)); + + 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._roomEngine.createRoomInstance(this._currentRoomId, roomMap); + } + + private onRoomHeightMapEvent(event: RoomHeightMapEvent): void + { + if(!(event instanceof RoomHeightMapEvent) || !event.connection || !this._roomEngine) 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._roomEngine.setFurnitureStackingHeightMap(this._currentRoomId, heightMap); + } + + private onRoomHeightMapUpdateEvent(event: RoomHeightMapUpdateEvent): void + { + if(!(event instanceof RoomHeightMapUpdateEvent) || !event.connection || !this._roomEngine) return; + + const parser = event.getParser(); + + if(!parser) return; + + const heightMap = this._roomEngine.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._roomEngine.refreshTileObjectMap(this._currentRoomId, 'RoomMessageHandler.onRoomHeightMapUpdateEvent()'); + } + + private onRoomThicknessEvent(event: RoomVisualizationSettingsEvent): void + { + if(!(event instanceof RoomVisualizationSettingsEvent)) 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._roomEngine) + { + this._roomEngine.updateRoomInstancePlaneVisibility(this._currentRoomId, visibleWall, visibleFloor); + this._roomEngine.updateRoomInstancePlaneThickness(this._currentRoomId, thicknessWall, thicknessFloor); + } + } + + private onRoomDoorEvent(event: RoomEntryTileMessageEvent): void + { + if(!(event instanceof RoomEntryTileMessageEvent)) return; + + this._latestEntryTileEvent = event; + } + + private onRoomRollingEvent(event: ObjectsRollingEvent): void + { + if(!(event instanceof ObjectsRollingEvent) || !event.connection || !this._roomEngine) return; + + const parser = event.getParser(); + + this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.rollerId, null, null, 1, null); + this._roomEngine.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._roomEngine.rollRoomObjectFloor(this._currentRoomId, rollData.id, rollData.location, rollData.targetLocation); + } + } + + const unitRollData = parser.unitRolling; + + if(unitRollData) + { + this._roomEngine.updateRoomObjectUserLocation(this._currentRoomId, unitRollData.id, unitRollData.location, unitRollData.targetLocation); + + const object = this._roomEngine.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._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, unitRollData.id, posture); + } + } + } + + private onObjectsDataUpdateEvent(event: ObjectsDataUpdateEvent): void + { + if(!(event instanceof ObjectsDataUpdateEvent) || !event.connection || !this._roomEngine) return; + + const parser = event.getParser(); + + if(!parser) return; + + for(const object of parser.objects) + { + this._roomEngine.updateRoomObjectFloor(this._currentRoomId, object.id, null, null, object.state, object.data); + } + } + + private onFurnitureAliasesEvent(event: FurnitureAliasesEvent): void + { + if(!(event instanceof FurnitureAliasesEvent) || !event.connection || !this._roomEngine) return; + + const alises = event.getParser().aliases; + + this._connection.send(new GetRoomEntryDataMessageComposer()); + } + + private onFurnitureFloorAddEvent(event: FurnitureFloorAddEvent): void + { + if(!(event instanceof FurnitureFloorAddEvent) || !event.connection || !this._roomEngine) 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._roomEngine) 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._roomEngine) return; + + const parser = event.getParser(); + + if(!parser) return; + + if(parser.delay > 0) + { + setTimeout(() => + { + this._roomEngine.removeRoomObjectFloor(this._currentRoomId, parser.itemId, (parser.isExpired) ? -1 : parser.userId, true); + }, parser.delay); + } + else + { + this._roomEngine.removeRoomObjectFloor(this._currentRoomId, parser.itemId, (parser.isExpired) ? -1 : parser.userId, true); + } + } + + private onFurnitureFloorUpdateEvent(event: FurnitureFloorUpdateEvent): void + { + if(!(event instanceof FurnitureFloorUpdateEvent) || !event.connection || !this._roomEngine) 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._roomEngine.updateRoomObjectFloor(this._currentRoomId, item.itemId, location, direction, item.data.state, item.data, item.extra); + this._roomEngine.updateRoomObjectFloorHeight(this._currentRoomId, item.itemId, item.stackHeight); + this._roomEngine.updateRoomObjectFloorExpiration(this._currentRoomId, item.itemId, item.expires); + } + + private onFurnitureWallAddEvent(event: FurnitureWallAddEvent): void + { + if(!(event instanceof FurnitureWallAddEvent) || !event.connection || !this._roomEngine) 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._roomEngine) 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._roomEngine) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._roomEngine.removeRoomObjectWall(this._currentRoomId, parser.itemId, parser.userId); + } + + private onFurnitureWallUpdateEvent(event: FurnitureWallUpdateEvent): void + { + if(!(event instanceof FurnitureWallUpdateEvent) || !event.connection || !this._roomEngine) return; + + const wallGeometry = this._roomEngine.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._roomEngine.updateRoomObjectWall(this._currentRoomId, item.itemId, location, direction, item.state, item.stuffData); + this._roomEngine.updateRoomObjectWallExpiration(this._currentRoomId, item.itemId, item.secondsToExpiration); + } + + private onFurnitureDataEvent(event: FurnitureDataEvent): void + { + if(!(event instanceof FurnitureDataEvent) || !event.connection || !this._roomEngine) return; + + const parser = event.getParser(); + + this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.furnitureId, null, null, parser.objectData.state, parser.objectData); + } + + private onItemDataUpdateMessageEvent(event: ItemDataUpdateMessageEvent): void + { + if(!(event instanceof ItemDataUpdateMessageEvent) || !event.connection || !this._roomEngine) return; + + const parser = event.getParser(); + + this._roomEngine.updateRoomObjectWallItemData(this._currentRoomId, parser.furnitureId, parser.data); + } + + private onOneWayDoorStatusMessageEvent(event: OneWayDoorStatusMessageEvent): void + { + if(!(event instanceof OneWayDoorStatusMessageEvent) || !event.connection || !this._roomEngine) return; + + const parser = event.getParser(); + + this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.itemId, null, null, parser.state, new LegacyDataType()); + } + + private onDiceValueMessageEvent(event: DiceValueMessageEvent): void + { + if(!(event instanceof DiceValueMessageEvent) || !event.connection || !this._roomEngine) return; + + const parser = event.getParser(); + + this._roomEngine.updateRoomObjectFloor(this._currentRoomId, parser.itemId, null, null, parser.value, new LegacyDataType()); + } + + private onRoomUnitDanceEvent(event: RoomUnitDanceEvent): void + { + if(!(event instanceof RoomUnitDanceEvent) || !event.connection || !this._roomEngine) return; + + this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_DANCE, event.getParser().danceId); + } + + private onRoomUnitEffectEvent(event: RoomUnitEffectEvent): void + { + if(!(event instanceof RoomUnitEffectEvent) || !event.connection || !this._roomEngine) return; + + this._roomEngine.updateRoomObjectUserEffect(this._currentRoomId, event.getParser().unitId, event.getParser().effectId, event.getParser().delay); + } + + private onRoomUnitEvent(event: RoomUnitEvent): void + { + if(!(event instanceof RoomUnitEvent) || !event.connection || !this._roomEngine) 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._roomEngine.addRoomObjectUser(this._currentRoomId, user.roomIndex, location, direction, user.dir, user.userType, user.figure); + + if(user.webID === this._ownUserId) + { + this._roomEngine.setRoomSessionOwnUser(this._currentRoomId, user.roomIndex); + this._roomEngine.updateRoomObjectUserOwn(this._currentRoomId, user.roomIndex); + } + + this._roomEngine.updateRoomObjectUserFigure(this._currentRoomId, user.roomIndex, user.figure, user.sex, user.subType, user.isRiding); + + if(RoomObjectUserType.getTypeString(user.userType) === RoomObjectUserType.PET) + { + if(this._roomEngine.getPetTypeId(user.figure) === PetType.MONSTERPLANT) + { + this._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, user.roomIndex, user.petPosture); + } + } + + this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, user.roomIndex, RoomObjectVariable.FIGURE_IS_MUTED, (GetSessionDataManager().isUserIgnored(user.name) ? 1 : 0)); + } + + this.updateGuideMarker(); + } + + private onRoomUnitExpressionEvent(event: RoomUnitExpressionEvent): void + { + if(!(event instanceof RoomUnitExpressionEvent) || !event.connection || !this._roomEngine) return; + + this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_EXPRESSION, event.getParser().expression); + } + + private onRoomUnitHandItemEvent(event: RoomUnitHandItemEvent): void + { + if(!(event instanceof RoomUnitHandItemEvent) || !event.connection || !this._roomEngine) return; + + this._roomEngine.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._roomEngine) return; + + this._roomEngine.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._roomEngine) return; + + this._roomEngine.updateRoomObjectUserFigure(this._currentRoomId, event.getParser().unitId, event.getParser().figure, event.getParser().gender); + } + + private onRoomUnitNumberEvent(event: RoomUnitNumberEvent): void + { + if(!(event instanceof RoomUnitNumberEvent) || !event.connection || !this._roomEngine) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, parser.unitId, RoomObjectVariable.FIGURE_NUMBER_VALUE, parser.value); + } + + private onRoomUnitRemoveEvent(event: RoomUnitRemoveEvent): void + { + if(!(event instanceof RoomUnitRemoveEvent) || !event.connection || !this._roomEngine) return; + + this._roomEngine.removeRoomObjectUser(this._currentRoomId, event.getParser().unitId); + + this.updateGuideMarker(); + } + + private onRoomUnitStatusEvent(event: RoomUnitStatusEvent): void + { + if(!(event instanceof RoomUnitStatusEvent) || !event.connection || !this._roomEngine) return; + + const statuses = event.getParser().statuses; + + if(!statuses || !statuses.length) return; + + const roomInstance = this._roomEngine.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._roomEngine.updateRoomObjectUserLocation(this._currentRoomId, status.id, location, goal, status.canStandUp, height, direction, status.headDirection); + this._roomEngine.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._roomEngine.updateRoomObjectUserFlatControl(this._currentRoomId, status.id, action.value); + break; + case 'sign': + if(status.actions.length === 1) isPosture = false; + + this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, status.id, RoomObjectVariable.FIGURE_SIGN, parseInt(action.value)); + break; + case 'gst': + if(status.actions.length === 1) isPosture = false; + + this._roomEngine.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._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, status.id, postureType, parameter); + else if(isPosture) this._roomEngine.updateRoomObjectUserPosture(this._currentRoomId, status.id, RoomObjectVariable.STD, ''); + } + + this.updateGuideMarker(); + } + + private onRoomUnitChatEvent(event: RoomUnitChatEvent): void + { + if(!event.connection || !this._roomEngine) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._roomEngine.updateRoomObjectUserGesture(this._currentRoomId, parser.roomIndex, parser.gesture); + this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, parser.roomIndex, RoomObjectVariable.FIGURE_TALK, (parser.message.length / 10)); + } + + private onRoomUnitTypingEvent(event: RoomUnitTypingEvent): void + { + if(!(event instanceof RoomUnitTypingEvent) || !event.connection || !this._roomEngine) return; + + this._roomEngine.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._roomEngine) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._roomEngine.updateRoomObjectUserFigure(this._currentRoomId, parser.roomIndex, parser.figureData.figuredata, '', '', parser.isRiding); + } + + private onPetExperienceEvent(event: PetExperienceEvent): void + { + const parser = event.getParser(); + + if(!parser) return; + + this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, parser.roomIndex, RoomObjectVariable.FIGURE_GAINED_EXPERIENCE, parser.gainedExperience); + } + + private onYouArePlayingGameEvent(event: YouArePlayingGameEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._roomEngine.setRoomEngineGameMode(this._currentRoomId, parser.isPlaying); + } + + private addRoomObjectFurnitureFloor(roomId: number, data: FurnitureFloorDataParser): void + { + if(!data || !this._roomEngine) return; + + const location = new Vector3d(data.x, data.y, data.z); + const direction = new Vector3d(data.direction); + + if(data.spriteName) + { + this._roomEngine.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._roomEngine.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._roomEngine) return; + + const wallGeometry = this._roomEngine.getLegacyWallGeometry(roomId); + + if(!wallGeometry) return; + + let location: IVector3D = null; + + if(!data.isOldFormat) + { + location = wallGeometry.getLocation(data.width, data.height, data.localX, data.localY, data.direction); + } + else + { + //location = wallGeometry.getLocationOldFormat(data.y, data.z, data.direction); + } + + const direction = new Vector3d(wallGeometry.getDirection(data.direction)); + + this._roomEngine.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 = GetRoomSessionManager().getSession(this._currentRoomId); + + if(!roomSession) return; + + const userData = roomSession.userDataManager.getUserDataByName(parser.name); + + if(!userData) return; + + switch(parser.result) + { + case 1: + case 2: + this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, userData.roomIndex, RoomObjectVariable.FIGURE_IS_MUTED, 1); + return; + case 3: + this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, userData.roomIndex, RoomObjectVariable.FIGURE_IS_MUTED, 0); + return; + } + } + + private onGuideSessionStartedMessageEvent(event: GuideSessionStartedMessageEvent): void + { + const parser = event.getParser(); + + this._guideId = parser.guideUserId; + this._requesterId = parser.requesterUserId; + + this.updateGuideMarker(); + } + + private onGuideSessionEndedMessageEvent(k: GuideSessionEndedMessageEvent): void + { + this.removeGuideMarker(); + } + + private onGuideSessionErrorMessageEvent(k: GuideSessionErrorMessageEvent): void + { + this.removeGuideMarker(); + } + + private updateGuideMarker(): void + { + const userId = GetSessionDataManager().userId; + + this.setUserGuideStatus(this._guideId, ((this._requesterId === userId) ? AvatarGuideStatus.GUIDE : AvatarGuideStatus.NONE)); + this.setUserGuideStatus(this._requesterId, ((this._guideId === userId) ? AvatarGuideStatus.REQUESTER : AvatarGuideStatus.NONE)); + } + + private removeGuideMarker(): void + { + this.setUserGuideStatus(this._guideId, AvatarGuideStatus.NONE); + this.setUserGuideStatus(this._requesterId, AvatarGuideStatus.NONE); + + this._guideId = -1; + this._requesterId = -1; + } + + private setUserGuideStatus(userId: number, status: number): void + { + const roomSession = GetRoomSessionManager().getSession(this._currentRoomId); + + if(!roomSession) return; + + const userData = roomSession.userDataManager.getDataByType(userId, RoomObjectType.USER); + + if(!userData) return; + + this._roomEngine.updateRoomObjectUserAction(this._currentRoomId, userData.roomIndex, RoomObjectVariable.FIGURE_GUIDE_STATUS, status); + } + + // public _SafeStr_10580(event:_SafeStr_2242): void + // { + // var arrayIndex: number; + // 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: + // NitroEventDispatcher.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/packages/room/src/RoomObjectEventHandler.ts b/packages/room/src/RoomObjectEventHandler.ts new file mode 100644 index 0000000..3a4c08b --- /dev/null +++ b/packages/room/src/RoomObjectEventHandler.ts @@ -0,0 +1,2190 @@ +import { IFurnitureStackingHeightMap, ILegacyWallGeometry, IObjectData, IRoomCanvasMouseListener, IRoomEngineServices, IRoomGeometry, IRoomObject, IRoomObjectController, IRoomObjectEventManager, ISelectedRoomObjectData, IVector3D, MouseEventType, RoomObjectCategory, RoomObjectOperationType, RoomObjectPlacementSource, RoomObjectType, RoomObjectUserType, RoomObjectVariable } from '@nitrots/api'; +import { BotPlaceComposer, FurnitureColorWheelComposer, FurnitureDiceActivateComposer, FurnitureDiceDeactivateComposer, FurnitureFloorUpdateComposer, FurnitureGroupInfoComposer, FurnitureMultiStateComposer, FurnitureOneWayDoorComposer, FurniturePickupComposer, FurniturePlaceComposer, FurniturePostItPlaceComposer, FurnitureRandomStateComposer, FurnitureWallMultiStateComposer, FurnitureWallUpdateComposer, GetCommunication, GetItemDataComposer, GetResolutionAchievementsMessageComposer, PetMoveComposer, PetPlaceComposer, RemoveWallItemComposer, RoomUnitLookComposer, RoomUnitWalkComposer, SetItemDataMessageComposer, SetObjectDataMessageComposer } from '@nitrots/communication'; +import { GetConfiguration } from '@nitrots/configuration'; +import { GetEventDispatcher, RoomEngineDimmerStateEvent, RoomEngineObjectEvent, RoomEngineObjectPlacedEvent, RoomEngineObjectPlacedOnUserEvent, RoomEngineObjectPlaySoundEvent, RoomEngineRoomAdEvent, RoomEngineSamplePlaybackEvent, RoomEngineTriggerWidgetEvent, RoomEngineUseProductEvent, RoomObjectBadgeAssetEvent, RoomObjectDataRequestEvent, RoomObjectDimmerStateUpdateEvent, RoomObjectEvent, RoomObjectFloorHoleEvent, RoomObjectFurnitureActionEvent, RoomObjectHSLColorEnableEvent, RoomObjectHSLColorEnabledEvent, RoomObjectMouseEvent, RoomObjectMoveEvent, RoomObjectPlaySoundIdEvent, RoomObjectRoomAdEvent, RoomObjectSamplePlaybackEvent, RoomObjectSoundMachineEvent, RoomObjectStateChangedEvent, RoomObjectTileMouseEvent, RoomObjectWallMouseEvent, RoomObjectWidgetRequestEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { GetRoomSessionManager, GetSessionDataManager } from '@nitrots/session'; +import { CreateLinkEvent, NitroLogger, RoomId, Vector3d } from '@nitrots/utils'; +import { RoomEnterEffect, RoomObjectUpdateMessage } from '../../room'; +import { ObjectAvatarSelectedMessage, ObjectDataUpdateMessage, ObjectSelectedMessage, ObjectTileCursorUpdateMessage, ObjectVisibilityUpdateMessage } from './messages'; +import { SelectedRoomObjectData } from './utils'; + +export class RoomObjectEventHandler implements IRoomCanvasMouseListener, IRoomObjectEventManager +{ + private _eventIds: Map> = new Map(); + + private _selectedAvatarId: number = -1; + private _selectedObjectId: number = -1; + private _selectedObjectCategory: number = -2; + private _whereYouClickIsWhereYouGo: boolean = true; + private _objectPlacementSource: string = null; + + constructor( + private readonly _roomEngine: IRoomEngineServices) + { + GetEventDispatcher().addEventListener(RoomEngineObjectEvent.ADDED, event => this.onRoomEngineObjectEvent(event)); + } + + 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.updateSelectedObjectData(event.roomId, selectedData.id, selectedData.category, selectedData.loc, direction, selectedData.operation, selectedData.typeId, selectedData.instanceData, selectedData.stuffData, selectedData.state, selectedData.animFrame, selectedData.posture); + + selectedData = this.getSelectedRoomObjectData(event.roomId); + + if(!selectedData) return; + } + } + } + + this.setFurnitureAlphaMultiplier(roomObject, 0.5); + } + } + + public processRoomCanvasMouseEvent(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.getMouseEventId(category, event.type); + + if(_local_7 === event.eventId) + { + 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.eventId) + { + this.setMouseEventId(category, event.type, event.eventId); + } + } + + 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.setObjectMoverIconSprite(typeId, category, false, extra, stuffData, state, frameNumber, posture); + this._roomEngine.setObjectMoverIconSpriteVisible(false); + } + + return true; + } + + public cancelRoomObjectInsert(k: number): boolean + { + this.resetSelectedObjectData(k); + + return true; + } + + private getMouseEventId(k: number, _arg_2: string): string + { + const existing = this._eventIds.get(k); + + if(!existing) return null; + + return (existing.get(_arg_2) || null); + } + + private setMouseEventId(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.handleSelectedObjectRemove((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.STACK_HEIGHT: + case RoomObjectWidgetRequestEvent.EXTERNAL_IMAGE: + 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: + case RoomObjectWidgetRequestEvent.YOUTUBE: + 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 RoomObjectFurnitureActionEvent.SOUND_MACHINE_INIT: + case RoomObjectFurnitureActionEvent.SOUND_MACHINE_START: + case RoomObjectFurnitureActionEvent.SOUND_MACHINE_STOP: + case RoomObjectFurnitureActionEvent.SOUND_MACHINE_DISPOSE: + this.handleObjectSoundMachineEvent(event, roomId); + return; + case RoomObjectFurnitureActionEvent.JUKEBOX_INIT: + case RoomObjectFurnitureActionEvent.JUKEBOX_START: + case RoomObjectFurnitureActionEvent.JUKEBOX_MACHINE_STOP: + case RoomObjectFurnitureActionEvent.JUKEBOX_DISPOSE: + this.handleObjectJukeboxEvent(event, roomId); + return; + case RoomObjectFloorHoleEvent.ADD_HOLE: + case RoomObjectFloorHoleEvent.REMOVE_HOLE: + this.onRoomObjectFloorHoleEvent((event as RoomObjectFloorHoleEvent), roomId); + return; + case RoomObjectRoomAdEvent.ROOM_AD_FURNI_CLICK: + case RoomObjectRoomAdEvent.ROOM_AD_FURNI_DOUBLE_CLICK: + case RoomObjectRoomAdEvent.ROOM_AD_TOOLTIP_SHOW: + case RoomObjectRoomAdEvent.ROOM_AD_TOOLTIP_HIDE: + case RoomObjectRoomAdEvent.ROOM_AD_LOAD_IMAGE: + this.onRoomObjectRoomAdEvent((event as RoomObjectRoomAdEvent), 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 RoomObjectPlaySoundIdEvent.PLAY_SOUND: + case RoomObjectPlaySoundIdEvent.PLAY_SOUND_AT_PITCH: + this.handleRoomObjectPlaySoundEvent((event as RoomObjectPlaySoundIdEvent), 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.warn('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.DOUBLE_CLICK: + this.handleRoomObjectMouseDoubleClickEvent(event, roomId); + return; + case RoomObjectMouseEvent.MOUSE_MOVE: + this.handleRoomObjectMouseMoveEvent(event, roomId); + return; + case RoomObjectMouseEvent.MOUSE_DOWN: + this.handleRoomObjectMouseDownEvent(event, roomId); + return; + case RoomObjectMouseEvent.MOUSE_DOWN_LONG: + this.handleRoomObjectMouseDownLongEvent(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.handleMoveTargetFurni(roomId, event); + } + } + + const category = this._roomEngine.getRoomObjectCategoryForType(event.objectType); + + switch(operation) + { + case RoomObjectOperationType.OBJECT_MOVE: + if(category === RoomObjectCategory.ROOM) + { + if(selectedData) + { + this.modifyRoomObject(roomId, selectedData.id, selectedData.category, RoomObjectOperationType.OBJECT_MOVE_TO); + } + } + + else if(category === RoomObjectCategory.UNIT) + { + if(selectedData && (event.objectType === RoomObjectUserType.MONSTER_PLANT)) + { + this.modifyRoomObject(roomId, selectedData.id, selectedData.category, RoomObjectOperationType.OBJECT_MOVE_TO); + } + + if(event.eventId) this.setMouseEventId(RoomObjectCategory.ROOM, MouseEventType.MOUSE_CLICK, event.eventId); + + this.placeObjectOnUser(roomId, event.objectId, category); + } + + didMove = true; + + if(event.objectId !== -1) this.setSelectedObject(roomId, event.objectId, category); + + break; + case RoomObjectOperationType.OBJECT_PLACE: + if(category === RoomObjectCategory.ROOM) + { + this.placeObject(roomId, (event instanceof RoomObjectTileMouseEvent), (event instanceof RoomObjectWallMouseEvent)); + } + + else if(category === RoomObjectCategory.UNIT) + { + switch(event.objectType) + { + case RoomObjectUserType.MONSTER_PLANT: + case RoomObjectUserType.RENTABLE_BOT: + this.placeObject(roomId, (event instanceof RoomObjectTileMouseEvent), (event instanceof RoomObjectWallMouseEvent)); + break; + default: + if(event.eventId) + { + this.setMouseEventId(RoomObjectCategory.ROOM, MouseEventType.MOUSE_CLICK, event.eventId); + } + + this.placeObjectOnUser(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.setSelectedObject(roomId, event.objectId, category); + + didMove = false; + + if(category === RoomObjectCategory.UNIT) + { + if(event.ctrlKey && !event.altKey && !event.shiftKey && (event.objectType === RoomObjectUserType.RENTABLE_BOT)) + { + this.modifyRoomObject(roomId, event.objectId, category, RoomObjectOperationType.OBJECT_PICKUP_BOT); + } + + else if(event.ctrlKey && !event.altKey && !event.shiftKey && (event.objectType === RoomObjectUserType.MONSTER_PLANT)) + { + this.modifyRoomObject(roomId, event.objectId, category, RoomObjectOperationType.OBJECT_PICKUP_PET); + } + + else if(!event.ctrlKey && !event.altKey && event.shiftKey && (event.objectType === RoomObjectUserType.MONSTER_PLANT)) + { + this.modifyRoomObject(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(GetEventDispatcher()) + { + GetEventDispatcher().dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.REQUEST_ROTATE, roomId, event.objectId, category)); + } + } + } + + else if(event.ctrlKey && !event.altKey && !event.shiftKey) + { + this.modifyRoomObject(roomId, event.objectId, category, RoomObjectOperationType.OBJECT_PICKUP); + } + + if(!this._roomEngine.isPlayingGame()) + { + didWalk = true; + } + else + { + didMove = true; + } + } + } + + if(event.eventId) + { + if(didWalk) + { + this.setMouseEventId(RoomObjectCategory.ROOM, MouseEventType.MOUSE_CLICK, event.eventId); + } + + if(didMove) + { + this.setMouseEventId(RoomObjectCategory.MINIMUM, MouseEventType.MOUSE_CLICK, event.eventId); + } + } + } + break; + } + + if(category === RoomObjectCategory.ROOM) + { + const _local_15 = this.getMouseEventId(RoomObjectCategory.MINIMUM, MouseEventType.MOUSE_CLICK); + const _local_16 = this.getMouseEventId(RoomObjectCategory.UNIT, MouseEventType.MOUSE_CLICK); + + if((_local_15 !== event.eventId) && (_local_16 !== event.eventId) && !didMove) + { + this.deselectObject(roomId); + + if(GetEventDispatcher()) GetEventDispatcher().dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.DESELECTED, roomId, -1, RoomObjectCategory.MINIMUM)); + + this.setSelectedAvatar(roomId, 0, false); + } + } + } + + private handleRoomObjectMouseDoubleClickEvent(event: RoomObjectMouseEvent, roomId: number): void + { + const id = event.objectId; + const type = event.objectType; + const category = this._roomEngine.getRoomObjectCategoryForType(type); + + if(GetEventDispatcher()) + { + GetEventDispatcher().dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.DOUBLE_CLICK, roomId, id, category)); + } + } + + 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.handleMouseOverTile(event, roomId); + } + + else if(event.object && (event.object.id !== -1)) + { + if(this._whereYouClickIsWhereYouGo) + { + newEvent = this.handleMouseOverObject(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.handleObjectMove(event, roomId); + + return; + case RoomObjectOperationType.OBJECT_PLACE: + if(category === RoomObjectCategory.ROOM) this.handleObjectPlace(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.decorateModeMove(event)) + { + if(GetEventDispatcher()) GetEventDispatcher().dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.REQUEST_MOVE, roomId, event.objectId, category)); + } + } + return; + } + } + + private handleRoomObjectMouseDownLongEvent(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.ctrlKey && !event.shiftKey) || this.decorateModeMove(event)) + { + if(GetEventDispatcher()) GetEventDispatcher().dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.REQUEST_MANIPULATION, 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(GetEventDispatcher()) + { + GetEventDispatcher().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(GetEventDispatcher()) + { + GetEventDispatcher().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.changeObjectState(roomId, event.object.id, event.object.type, event.state, false); + return; + case RoomObjectStateChangedEvent.STATE_RANDOM: + this.changeObjectState(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: + GetEventDispatcher().dispatchEvent(new RoomEngineDimmerStateEvent(roomId, event.state, event.presetId, event.effectId, event.color, event.brightness)); + return; + } + } + + private handleSelectedObjectRemove(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.setSelectedAvatar(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); + + if(RoomId.isRoomPreviewerId(roomId)) return; + + switch(event.type) + { + case RoomObjectWidgetRequestEvent.OPEN_WIDGET: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.OPEN_WIDGET, roomId, objectId, objectCategory, ((event.object as IRoomObjectController).logic.widget))); + return; + case RoomObjectWidgetRequestEvent.CLOSE_WIDGET: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.CLOSE_WIDGET, roomId, objectId, objectCategory, ((event.object as IRoomObjectController).logic.widget))); + return; + case RoomObjectWidgetRequestEvent.OPEN_FURNI_CONTEXT_MENU: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU, roomId, objectId, objectCategory, ((event.object as IRoomObjectController).logic.contextMenu))); + return; + case RoomObjectWidgetRequestEvent.CLOSE_FURNI_CONTEXT_MENU: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.PLACEHOLDER: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_PLACEHOLDER, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.CREDITFURNI: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_CREDITFURNI, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.STACK_HEIGHT: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_STACK_HEIGHT, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.EXTERNAL_IMAGE: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_EXTERNAL_IMAGE, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.STICKIE: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_STICKIE, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.PRESENT: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_PRESENT, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.TROPHY: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_TROPHY, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.TEASER: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_TEASER, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.ECOTRONBOX: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_ECOTRONBOX, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.DIMMER: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_DIMMER, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.WIDGET_REMOVE_DIMMER: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REMOVE_DIMMER, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.CLOTHING_CHANGE: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_CLOTHING_CHANGE, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.JUKEBOX_PLAYLIST_EDITOR: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_PLAYLIST_EDITOR, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.MANNEQUIN: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.PET_PRODUCT_MENU: + GetEventDispatcher().dispatchEvent(new RoomEngineUseProductEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.GUILD_FURNI_CONTEXT_MENU: + GetCommunication().connection.send(new FurnitureGroupInfoComposer(event.objectId, event.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_GUILD_ID))); + return; + case RoomObjectWidgetRequestEvent.MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.BACKGROUND_COLOR: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.MYSTERYBOX_OPEN_DIALOG: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYBOX_OPEN_DIALOG, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.EFFECTBOX_OPEN_DIALOG: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.MYSTERYTROPHY_OPEN_DIALOG: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYTROPHY_OPEN_DIALOG, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_OPEN: + GetCommunication().connection.send(new GetResolutionAchievementsMessageComposer(event.objectId, 0)); + return; + case RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_ENGRAVING: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_FAILED: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_FAILED, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.FRIEND_FURNITURE_CONFIRM: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_FRIEND_FURNITURE_CONFIRM, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.FRIEND_FURNITURE_ENGRAVING: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_FRIEND_FURNITURE_ENGRAVING, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.BADGE_DISPLAY_ENGRAVING: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_BADGE_DISPLAY_ENGRAVING, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.HIGH_SCORE_DISPLAY: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_HIGH_SCORE_DISPLAY, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.HIDE_HIGH_SCORE_DISPLAY: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_HIDE_HIGH_SCORE_DISPLAY, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.INERNAL_LINK: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_INTERNAL_LINK, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.ROOM_LINK: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_ROOM_LINK, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.YOUTUBE: + GetEventDispatcher().dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_YOUTUBE, roomId, objectId, objectCategory)); + return; + } + } + + private onRoomObjectFurnitureActionEvent(event: RoomObjectFurnitureActionEvent, roomId: number): void + { + if(!event) return; + + this.useObject(roomId, event.object.id, event.object.type, event.type); + } + + private handleObjectSoundMachineEvent(event: RoomObjectEvent, roomId: number): void + { + if(!event) return; + + const objectCategory = this._roomEngine.getRoomObjectCategoryForType(event.objectType); + const selectedData = this.getSelectedRoomObjectData(roomId); + + if(selectedData) + { + if((selectedData.category === objectCategory) && (selectedData.id === event.objectId)) + { + if(selectedData.operation === RoomObjectOperationType.OBJECT_PLACE) return; + } + } + + switch(event.type) + { + case RoomObjectFurnitureActionEvent.SOUND_MACHINE_INIT: + GetEventDispatcher().dispatchEvent(new RoomObjectSoundMachineEvent(RoomObjectSoundMachineEvent.SOUND_MACHINE_INIT, roomId, event.objectId, objectCategory)); + return; + case RoomObjectFurnitureActionEvent.SOUND_MACHINE_START: + GetEventDispatcher().dispatchEvent(new RoomObjectSoundMachineEvent(RoomObjectSoundMachineEvent.SOUND_MACHINE_SWITCHED_ON, roomId, event.objectId, objectCategory)); + return; + case RoomObjectFurnitureActionEvent.SOUND_MACHINE_STOP: + GetEventDispatcher().dispatchEvent(new RoomObjectSoundMachineEvent(RoomObjectSoundMachineEvent.SOUND_MACHINE_SWITCHED_OFF, roomId, event.objectId, objectCategory)); + return; + case RoomObjectFurnitureActionEvent.SOUND_MACHINE_DISPOSE: + GetEventDispatcher().dispatchEvent(new RoomObjectSoundMachineEvent(RoomObjectSoundMachineEvent.SOUND_MACHINE_DISPOSE, roomId, event.objectId, objectCategory)); + return; + } + } + + private handleObjectJukeboxEvent(event: RoomObjectEvent, roomId: number): void + { + if(!event) return; + + const objectCategory = this._roomEngine.getRoomObjectCategoryForType(event.objectType); + const selectedData = this.getSelectedRoomObjectData(roomId); + + if(selectedData) + { + if((selectedData.category === objectCategory) && (selectedData.id === event.objectId)) + { + if(selectedData.operation === RoomObjectOperationType.OBJECT_PLACE) return; + } + } + + switch(event.type) + { + case RoomObjectFurnitureActionEvent.JUKEBOX_INIT: + GetEventDispatcher().dispatchEvent(new RoomObjectSoundMachineEvent(RoomObjectSoundMachineEvent.JUKEBOX_INIT, roomId, event.objectId, objectCategory)); + return; + case RoomObjectFurnitureActionEvent.JUKEBOX_START: + GetEventDispatcher().dispatchEvent(new RoomObjectSoundMachineEvent(RoomObjectSoundMachineEvent.JUKEBOX_SWITCHED_ON, roomId, event.objectId, objectCategory)); + return; + case RoomObjectFurnitureActionEvent.JUKEBOX_MACHINE_STOP: + GetEventDispatcher().dispatchEvent(new RoomObjectSoundMachineEvent(RoomObjectSoundMachineEvent.JUKEBOX_SWITCHED_OFF, roomId, event.objectId, objectCategory)); + return; + case RoomObjectFurnitureActionEvent.JUKEBOX_DISPOSE: + GetEventDispatcher().dispatchEvent(new RoomObjectSoundMachineEvent(RoomObjectSoundMachineEvent.JUKEBOX_DISPOSE, roomId, event.objectId, objectCategory)); + return; + } + } + + 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 onRoomObjectRoomAdEvent(event: RoomObjectRoomAdEvent, roomId: number): void + { + if(!event) return; + + let eventType: string = null; + + switch(event.type) + { + case RoomObjectRoomAdEvent.ROOM_AD_FURNI_CLICK: + GetEventDispatcher().dispatchEvent(event); + + if(event.clickUrl && (event.clickUrl.length > 0)) + { + CreateLinkEvent(event.clickUrl); + } + + eventType = RoomEngineRoomAdEvent.FURNI_CLICK; + break; + case RoomObjectRoomAdEvent.ROOM_AD_FURNI_DOUBLE_CLICK: + if(event.clickUrl && (event.clickUrl.length > 0)) + { + const catalogPage = 'CATALOG_PAGE'; + + if(event.clickUrl.indexOf(catalogPage) === 0) CreateLinkEvent(event.clickUrl.substr(catalogPage.length)); + } + + eventType = RoomEngineRoomAdEvent.FURNI_DOUBLE_CLICK; + break; + case RoomObjectRoomAdEvent.ROOM_AD_TOOLTIP_SHOW: + eventType = RoomEngineRoomAdEvent.TOOLTIP_SHOW; + break; + case RoomObjectRoomAdEvent.ROOM_AD_TOOLTIP_HIDE: + eventType = RoomEngineRoomAdEvent.TOOLTIP_HIDE; + break; + } + + if(eventType) GetEventDispatcher().dispatchEvent(new RoomEngineObjectEvent(eventType, roomId, event.objectId, this._roomEngine.getRoomObjectCategoryForType(event.objectType))); + } + + 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 handleRoomObjectPlaySoundEvent(event: RoomObjectPlaySoundIdEvent, roomId: number): void + { + const objectCategory = this._roomEngine.getRoomObjectCategoryForType(event.objectType); + + switch(event.type) + { + case RoomObjectPlaySoundIdEvent.PLAY_SOUND: + GetEventDispatcher().dispatchEvent(new RoomEngineObjectPlaySoundEvent(RoomEngineObjectPlaySoundEvent.PLAY_SOUND, roomId, event.objectId, objectCategory, event.soundId, event.pitch)); + return; + case RoomObjectPlaySoundIdEvent.PLAY_SOUND_AT_PITCH: + GetEventDispatcher().dispatchEvent(new RoomEngineObjectPlaySoundEvent(RoomEngineObjectPlaySoundEvent.PLAY_SOUND_AT_PITCH, roomId, event.objectId, objectCategory, event.soundId, event.pitch)); + return; + } + } + + 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: + GetEventDispatcher().dispatchEvent(new RoomEngineSamplePlaybackEvent(RoomEngineSamplePlaybackEvent.ROOM_OBJECT_INITIALIZED, roomId, event.objectId, objectCategory, event.sampleId, event.pitch)); + break; + case RoomObjectSamplePlaybackEvent.ROOM_OBJECT_DISPOSED: + GetEventDispatcher().dispatchEvent(new RoomEngineSamplePlaybackEvent(RoomEngineSamplePlaybackEvent.ROOM_OBJECT_DISPOSED, roomId, event.objectId, objectCategory, event.sampleId, event.pitch)); + break; + case RoomObjectSamplePlaybackEvent.PLAY_SAMPLE: + GetEventDispatcher().dispatchEvent(new RoomEngineSamplePlaybackEvent(RoomEngineSamplePlaybackEvent.PLAY_SAMPLE, roomId, event.objectId, objectCategory, event.sampleId, event.pitch)); + break; + case RoomObjectSamplePlaybackEvent.CHANGE_PITCH: + GetEventDispatcher().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: + GetEventDispatcher().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, GetSessionDataManager().userId); + return; + case RoomObjectDataRequestEvent.RODRE_URL_PREFIX: + event.object.model.setValue(RoomObjectVariable.SESSION_URL_PREFIX, GetConfiguration().getValue('url.prefix')); + return; + } + } + + private onRoomObjectTileMouseEvent(roomId: number, event: RoomObjectTileMouseEvent): void + { + const session = GetRoomSessionManager().getSession(roomId); + + if(!session || session.isSpectator) return; + + this.sendWalkUpdate(event.tileXAsInt, event.tileYAsInt); + } + + private handleObjectMove(event: RoomObjectMouseEvent, roomId: number): void + { + if(!event || !this._roomEngine) return; + + const eventDispatcher = GetEventDispatcher(); + + 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.handleFurnitureMove(roomObject, selectedData, Math.trunc(event.tileX + 0.5), Math.trunc(event.tileY + 0.5), stackingHeightMap)))) + { + this.handleFurnitureMove(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.handleWallItemMove(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.setObjectMoverIconSpriteVisible(false); + } + else + { + this.setFurnitureAlphaMultiplier(roomObject, 0); + + this._roomEngine.setObjectMoverIconSpriteVisible(true); + } + } + + private handleObjectPlace(event: RoomObjectMouseEvent, roomId: number): void + { + if(!event || !this._roomEngine) return; + + const eventDispatcher = GetEventDispatcher(); + + 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.instanceData), -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.instanceData); + + 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.instanceData, 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.updateSelectedObjectData(roomId, selectedData.id, selectedData.category, selectedData.loc, direction, selectedData.operation, selectedData.typeId, selectedData.instanceData, selectedData.stuffData, selectedData.state, selectedData.animFrame, selectedData.posture); + + selectedData = this.getSelectedRoomObjectData(roomId); + + if(!selectedData) return; + } + } + } + + this.setFurnitureAlphaMultiplier(roomObject, 0.5); + this._roomEngine.setObjectMoverIconSpriteVisible(true); + } + + if(roomObject) + { + let _local_12 = true; + + const stackingHeightMap = this._roomEngine.getFurnitureStackingHeightMap(roomId); + + if(selectedData.category === RoomObjectCategory.FLOOR) + { + if(!((event instanceof RoomObjectTileMouseEvent) && this.handleFurnitureMove(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.handleWallItemMove(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.handleUserPlace(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.setObjectMoverIconSpriteVisible(!_local_12); + } + } + + private handleFurnitureMove(roomObject: IRoomObjectController, selectedObjectData: ISelectedRoomObjectData, x: number, y: number, stackingHeightMap: IFurnitureStackingHeightMap): 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.validateFurnitureLocation(roomObject, _local_7, selectedObjectData.loc, selectedObjectData.dir, stackingHeightMap); + + if(!_local_9) + { + _local_8.x = this.getValidRoomObjectDirection(roomObject, true); + + roomObject.setDirection(_local_8); + + _local_9 = this.validateFurnitureLocation(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 handleWallItemMove(k: IRoomObjectController, _arg_2: ISelectedRoomObjectData, _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.validateWallItemLocation(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 validateFurnitureLocation(k: IRoomObject, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D, _arg_5: IFurnitureStackingHeightMap): 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 validateWallItemLocation(k: IRoomObject, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D, _arg_5: number, _arg_6: number, _arg_7: ISelectedRoomObjectData): 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 changeObjectState(roomId: number, objectId: number, type: string, state: number, isRandom: boolean): void + { + const category = this._roomEngine.getRoomObjectCategoryForType(type); + + this.changeRoomObjectState(roomId, objectId, category, state, isRandom); + } + + private useObject(roomId: number, objectId: number, type: string, action: string): void + { + if(!this._roomEngine || !GetCommunication().connection) return; + switch(action) + { + case RoomObjectFurnitureActionEvent.DICE_ACTIVATE: + GetCommunication().connection.send(new FurnitureDiceActivateComposer(objectId)); + return; + case RoomObjectFurnitureActionEvent.DICE_OFF: + GetCommunication().connection.send(new FurnitureDiceDeactivateComposer(objectId)); + return; + case RoomObjectFurnitureActionEvent.USE_HABBOWHEEL: + GetCommunication().connection.send(new FurnitureColorWheelComposer(objectId)); + return; + case RoomObjectFurnitureActionEvent.STICKIE: + GetCommunication().connection.send(new GetItemDataComposer(objectId)); + return; + case RoomObjectFurnitureActionEvent.ENTER_ONEWAYDOOR: + GetCommunication().connection.send(new FurnitureOneWayDoorComposer(objectId)); + return; + } + } + + private changeRoomObjectState(roomId: number, objectId: number, category: number, state: number, isRandom: boolean): boolean + { + if(!this._roomEngine || !GetCommunication().connection) return true; + + if(category === RoomObjectCategory.FLOOR) + { + if(!isRandom) + { + GetCommunication().connection.send(new FurnitureMultiStateComposer(objectId, state)); + } + else + { + GetCommunication().connection.send(new FurnitureRandomStateComposer(objectId, state)); + } + } + + else if(category === RoomObjectCategory.WALL) + { + GetCommunication().connection.send(new FurnitureWallMultiStateComposer(objectId, state)); + } + + return true; + } + + private sendWalkUpdate(x: number, y: number): void + { + if(!this._roomEngine || !GetCommunication().connection) return; + + GetCommunication().connection.send(new RoomUnitWalkComposer(x, y)); + } + + private handleMouseOverObject(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.getActiveSurfaceLocation(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 handleMoveTargetFurni(k: number, _arg_2: RoomObjectMouseEvent): boolean + { + if((_arg_2.objectType === RoomObjectUserType.USER) || (_arg_2.objectType === RoomObjectUserType.PET) || (_arg_2.objectType === RoomObjectUserType.BOT) || (_arg_2.objectType === RoomObjectUserType.RENTABLE_BOT) || (_arg_2.objectType === RoomObjectUserType.MONSTER_PLANT)) return; + + const _local_3 = this._roomEngine.getRoomObject(k, _arg_2.objectId, RoomObjectCategory.FLOOR); + const _local_4 = this.getActiveSurfaceLocation(_local_3, _arg_2); + + if(_local_4) + { + this.sendWalkUpdate(_local_4.x, _local_4.y); + + return true; + } + + return false; + } + + private getActiveSurfaceLocation(k: IRoomObject, _arg_2: RoomObjectMouseEvent): Vector3d + { + if(!k || !_arg_2) return null; + + const furniData = GetSessionDataManager().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 handleMouseOverTile(k: RoomObjectTileMouseEvent, roomId: number): ObjectTileCursorUpdateMessage + { + if(this._whereYouClickIsWhereYouGo) + { + return new ObjectTileCursorUpdateMessage(new Vector3d(k.tileXAsInt, k.tileYAsInt, k.tileZAsInt), 0, true, k.eventId); + } + + const roomObject = this._roomEngine.getRoomObjectCursor(roomId); + + if(roomObject && roomObject.visualization) + { + const _local_4 = k.tileXAsInt; + const _local_5 = k.tileYAsInt; + const _local_6 = k.tileZAsInt; + 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.getObjectIntTile(_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 placeObject(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 && GetCommunication().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.getOldLocationString(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) + { + GetCommunication().connection.send(new PetPlaceComposer(objectId, Math.trunc(x), Math.trunc(y))); + } + + else if(selectedData.typeId === RoomObjectType.RENTABLE_BOT) + { + GetCommunication().connection.send(new BotPlaceComposer(objectId, Math.trunc(x), Math.trunc(y))); + } + } + + else if(roomObject.model.getValue(RoomObjectVariable.FURNITURE_IS_STICKIE) !== undefined) + { + GetCommunication().connection.send(new FurniturePostItPlaceComposer(objectId, wallLocation)); + } + + else + { + GetCommunication().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.resetSelectedObjectData(roomId); + + if(this._roomEngine && GetEventDispatcher()) + { + const placedInRoom = (roomObject && (roomObject.id === selectedData.id)); + + GetEventDispatcher().dispatchEvent(new RoomEngineObjectPlacedEvent(RoomEngineObjectEvent.PLACED, roomId, objectId, category, wallLocation, x, y, z, direction, placedInRoom, isTileEvent, isWallEvent, selectedData.instanceData)); + } + } + + public modifyRoomObject(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(GetCommunication().connection) + { + let direction = 0; + + if(operation == RoomObjectOperationType.OBJECT_ROTATE_NEGATIVE) + { + direction = this.getValidRoomObjectDirection(roomObject, false); + } + else + { + direction = this.getValidRoomObjectDirection(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 = GetRoomSessionManager().getSession(roomId); + + if(roomSession) + { + const userData = roomSession.userDataManager.getUserDataByIndex(objectId); + + if(userData) + { + GetCommunication().connection.send(new PetMoveComposer(userData.webID, Math.trunc(x), Math.trunc(y), direction)); + } + } + } + else + { + GetCommunication().connection.send(new FurnitureFloorUpdateComposer(objectId, x, y, direction)); + } + } + } + break; + case RoomObjectOperationType.OBJECT_EJECT: + case RoomObjectOperationType.OBJECT_PICKUP: + if(GetCommunication().connection) GetCommunication().connection.send(new FurniturePickupComposer(category, objectId)); + break; + case RoomObjectOperationType.OBJECT_PICKUP_PET: + if(GetCommunication().connection) + { + const session = GetRoomSessionManager().getSession(roomId); + + if(session) + { + const userData = session.userDataManager.getUserDataByIndex(objectId); + + session.pickupPet(userData.webID); + } + } + break; + case RoomObjectOperationType.OBJECT_PICKUP_BOT: + if(GetCommunication().connection) + { + const session = GetRoomSessionManager().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.setObjectMoverIconSprite(roomObject.id, category, true); + this._roomEngine.setObjectMoverIconSpriteVisible(false); + break; + case RoomObjectOperationType.OBJECT_MOVE_TO: { + const selectedData = this.getSelectedRoomObjectData(roomId); + + this.updateSelectedObjectData(roomId, selectedData.id, selectedData.category, selectedData.loc, selectedData.dir, RoomObjectOperationType.OBJECT_MOVE_TO, selectedData.typeId, selectedData.instanceData, selectedData.stuffData, selectedData.state, selectedData.animFrame, selectedData.posture); + this.setFurnitureAlphaMultiplier(roomObject, 1); + this._roomEngine.removeObjectMoverIconSprite(); + + if(GetCommunication().connection) + { + if(category === RoomObjectCategory.FLOOR) + { + const angle = ((roomObject.getDirection().x) % 360); + const location = roomObject.getLocation(); + const direction = (angle / 45); + + GetCommunication().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.getOldLocationString(roomObject.getLocation(), angle); + + if(location) GetCommunication().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 = GetRoomSessionManager().getSession(roomId); + + if(roomSession) + { + const userData = roomSession.userDataManager.getUserDataByIndex(objectId); + + if(userData) GetCommunication().connection.send(new PetMoveComposer(userData.webID, location.x, location.y, direction)); + } + } + } + + break; + } + } + + if(_local_9) this.resetSelectedObjectData(roomId); + + return true; + } + + public modifyRoomObjectDataWithMap(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(GetCommunication().connection) + { + GetCommunication().connection.send(new SetObjectDataMessageComposer(objectId, data)); + } + break; + } + + return true; + } + + public modifyWallItemData(roomId: number, objectId: number, colorHex: string, text: string): boolean + { + if(!this._roomEngine || !GetCommunication().connection) return false; + + GetCommunication().connection.send(new SetItemDataMessageComposer(objectId, colorHex, text)); + + return true; + } + + public deleteWallItem(roomId: number, itemId: number): boolean + { + if(!this._roomEngine || !GetCommunication().connection) return false; + + GetCommunication().connection.send(new RemoveWallItemComposer(itemId)); + + return true; + } + + public getValidRoomObjectDirection(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: IFurnitureStackingHeightMap): 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 placeObjectOnUser(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 || !GetEventDispatcher()) return; + + GetEventDispatcher().dispatchEvent(new RoomEngineObjectPlacedOnUserEvent(RoomEngineObjectEvent.PLACED_ON_USER, roomId, objectId, category, _local_4.id, _local_4.category)); + } + + public setSelectedObject(roomId: number, objectId: number, category: number): void + { + if(!this._roomEngine) return; + + const eventDispatcher = GetEventDispatcher(); + + if(!eventDispatcher) return; + + switch(category) + { + case RoomObjectCategory.UNIT: + case RoomObjectCategory.FLOOR: + case RoomObjectCategory.WALL: + if(category === RoomObjectCategory.UNIT) + { + this.deselectObject(roomId); + this.setSelectedAvatar(roomId, objectId, true); + } + else + { + this.setSelectedAvatar(roomId, 0, false); + + if(objectId !== this._selectedObjectId) + { + this.deselectObject(roomId); + + const roomObject = this._roomEngine.getRoomObject(roomId, objectId, category); + + if(roomObject && roomObject.logic) + { + roomObject.logic.processUpdateMessage(new ObjectSelectedMessage(true)); + + this._selectedObjectId = objectId; + this._selectedObjectCategory = category; + } + } + } + + GetEventDispatcher().dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.SELECTED, roomId, objectId, category)); + + return; + } + } + + private deselectObject(roomId: number): void + { + if(this._selectedObjectId === -1) return; + + const object = this._roomEngine.getRoomObject(roomId, this._selectedObjectId, this._selectedObjectCategory); + + if(object && object.logic) + { + object.logic.processUpdateMessage(new ObjectSelectedMessage(false)); + + this._selectedObjectId = -1; + this._selectedObjectCategory = RoomObjectCategory.MINIMUM; + } + } + + public setSelectedAvatar(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) GetCommunication().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 resetSelectedObjectData(roomId: number): void + { + if(!this._roomEngine) return; + + this._roomEngine.removeObjectMoverIconSprite(); + + 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.updateSelectedObjectData(roomId, selectedData.id, selectedData.category, selectedData.loc, selectedData.dir, RoomObjectOperationType.OBJECT_MOVE, selectedData.typeId, selectedData.instanceData, selectedData.stuffData, selectedData.state, selectedData.animFrame, 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): ISelectedRoomObjectData + { + 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 decorateModeMove(event: RoomObjectMouseEvent): boolean + { + return (this._roomEngine.isDecorating) && (!(event.ctrlKey || event.shiftKey)); + } + + public cancelRoomObjectPlacement(roomId: number): boolean + { + this.resetSelectedObjectData(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.resetSelectedObjectData(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 updateSelectedObjectData(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 handleUserPlace(roomObject: IRoomObjectController, x: number, y: number, wallGeometry: ILegacyWallGeometry): boolean + { + if(!wallGeometry.isRoomTile(x, y)) return false; + + roomObject.setLocation(new Vector3d(x, y, wallGeometry.getHeight(x, y))); + + return true; + } + + public get engine(): IRoomEngineServices + { + return this._roomEngine; + } + + public get selectedAvatarId(): number + { + return this._selectedAvatarId; + } +} diff --git a/packages/room/src/RoomObjectLogicFactory.ts b/packages/room/src/RoomObjectLogicFactory.ts new file mode 100644 index 0000000..2678a57 --- /dev/null +++ b/packages/room/src/RoomObjectLogicFactory.ts @@ -0,0 +1,315 @@ +import { IEventDispatcher, IRoomObjectEventHandler, IRoomObjectLogicFactory, RoomObjectLogicType } from '@nitrots/api'; +import { GetEventDispatcher, RoomObjectEvent } from '@nitrots/events'; +import { NitroLogger } from '@nitrots/utils'; +import { RoomObjectLogicBase } from '../../room'; +import { AvatarLogic, FurnitureAchievementResolutionLogic, FurnitureBadgeDisplayLogic, FurnitureChangeStateWhenStepOnLogic, FurnitureClothingChangeLogic, FurnitureCounterClockLogic, FurnitureCrackableLogic, FurnitureCraftingGizmoLogic, FurnitureCreditLogic, FurnitureCuckooClockLogic, FurnitureCustomStackHeightLogic, FurnitureDiceLogic, FurnitureEcotronBoxLogic, FurnitureEditableInternalLinkLogic, FurnitureEditableRoomLinkLogic, FurnitureEffectBoxLogic, FurnitureExternalImageLogic, FurnitureFireworksLogic, FurnitureFloorHoleLogic, FurnitureGroupForumTerminalLogic, FurnitureGuildCustomizedLogic, FurnitureHabboWheelLogic, FurnitureHighScoreLogic, FurnitureHockeyScoreLogic, FurnitureHweenLovelockLogic, FurnitureIceStormLogic, FurnitureInternalLinkLogic, FurnitureJukeboxLogic, FurnitureLogic, FurnitureLoveLockLogic, FurnitureMannequinLogic, FurnitureMonsterplantSeedLogic, FurnitureMultiHeightLogic, FurnitureMultiStateLogic, FurnitureMysteryBoxLogic, FurnitureMysteryTrophyLogic, FurnitureOneWayDoorLogic, FurniturePetCustomizationLogic, FurniturePlaceholderLogic, FurniturePlanetSystemLogic, FurniturePresentLogic, FurniturePurchaseableClothingLogic, FurniturePushableLogic, FurnitureRandomStateLogic, FurnitureRandomTeleportLogic, FurnitureRentableSpaceLogic, FurnitureRoomBackgroundColorLogic, FurnitureRoomBackgroundLogic, FurnitureRoomBillboardLogic, FurnitureRoomDimmerLogic, FurnitureScoreLogic, FurnitureSongDiskLogic, FurnitureSoundBlockLogic, FurnitureSoundMachineLogic, FurnitureStickieLogic, FurnitureTrophyLogic, FurnitureVoteCounterLogic, FurnitureVoteMajorityLogic, FurnitureWelcomeGiftLogic, FurnitureWindowLogic, FurnitureYoutubeLogic, PetLogic, RoomLogic, SelectionArrowLogic, TileCursorLogic } from './object'; + +export class RoomObjectLogicFactory implements IRoomObjectLogicFactory +{ + private _events: IEventDispatcher = GetEventDispatcher(); + private _cachedEvents: Map = new Map(); + private _registeredEvents: Map = new Map(); + private _functions: ((event: RoomObjectEvent) => void)[] = []; + + 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: (event: RoomObjectEvent) => void): 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: (event: RoomObjectEvent) => void): 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 = FurnitureLoveLockLogic; + break; + case RoomObjectLogicType.FURNITURE_YOUTUBE: + logic = FurnitureYoutubeLogic; + break; + case RoomObjectLogicType.FURNITURE_CRAFTING_GIZMO: + logic = FurnitureCraftingGizmoLogic; + break; + case RoomObjectLogicType.FURNITURE_RENTABLE_SPACE: + logic = FurnitureRentableSpaceLogic; + break; + case RoomObjectLogicType.FURNITURE_EFFECTBOX: + logic = FurnitureEffectBoxLogic; + break; + case RoomObjectLogicType.FURNITURE_MONSTERPLANT_SEED: + logic = FurnitureMonsterplantSeedLogic; + break; + case RoomObjectLogicType.FURNITURE_MYSTERYBOX: + logic = FurnitureMysteryBoxLogic; + break; + case RoomObjectLogicType.FURNITURE_MYSTERYTROPHY: + logic = FurnitureMysteryTrophyLogic; + break; + case RoomObjectLogicType.FURNITURE_RANDOM_TELEPORT: + logic = FurnitureRandomTeleportLogic; + break; + case RoomObjectLogicType.FURNITURE_CLOTHING_CHANGE: + logic = FurnitureClothingChangeLogic; + break; + case RoomObjectLogicType.FURNITURE_CUCKOO_CLOCK: + logic = FurnitureCuckooClockLogic; + break; + case RoomObjectLogicType.FURNITURE_ECOTRON_BOX: + logic = FurnitureEcotronBoxLogic; + break; + case RoomObjectLogicType.FURNITURE_GROUP_FORUM_TERMINAL: + logic = FurnitureGroupForumTerminalLogic; + break; + case RoomObjectLogicType.FURNITURE_HWEEN_LOVELOCK: + logic = FurnitureHweenLovelockLogic; + break; + case RoomObjectLogicType.FURNITURE_INTERNAL_LINK: + logic = FurnitureInternalLinkLogic; + break; + case RoomObjectLogicType.FURNITURE_JUKEBOX: + logic = FurnitureJukeboxLogic; + break; + case RoomObjectLogicType.FURNITURE_PLACEHOLDER: + logic = FurniturePlaceholderLogic; + break; + case RoomObjectLogicType.FURNITURE_PLANET_SYSTEM: + logic = FurniturePlanetSystemLogic; + break; + case RoomObjectLogicType.FURNITURE_RANDOMSTATE: + logic = FurnitureRandomStateLogic; + break; + case RoomObjectLogicType.FURNITURE_SONG_DISK: + logic = FurnitureSongDiskLogic; + break; + case RoomObjectLogicType.FURNITURE_SOUND_MACHINE: + logic = FurnitureSoundMachineLogic; + break; + case RoomObjectLogicType.FURNITURE_WELCOME_GIFT: + logic = FurnitureWelcomeGiftLogic; + break; + case RoomObjectLogicType.FURNITURE_ACHIEVEMENT_RESOLUTION: + logic = FurnitureAchievementResolutionLogic; + break; + case RoomObjectLogicType.FURNITURE_HABBOWHEEL: + logic = FurnitureHabboWheelLogic; + break; + default: + logic = FurnitureLogic; + break; + } + + if(!logic) + { + NitroLogger.warn('Unknown Logic', type); + + return null; + } + + return logic; + } + + public get events(): IEventDispatcher + { + return this._events; + } +} diff --git a/packages/room/src/RoomObjectManager.ts b/packages/room/src/RoomObjectManager.ts new file mode 100644 index 0000000..d4331b0 --- /dev/null +++ b/packages/room/src/RoomObjectManager.ts @@ -0,0 +1,130 @@ +import { IAdvancedMap, IRoomObjectController, IRoomObjectManager } from '@nitrots/api'; +import { AdvancedMap } from '@nitrots/utils'; +import { RoomObject } from './object'; + +export class RoomObjectManager implements IRoomObjectManager +{ + private _objects: IAdvancedMap; + private _objectsPerType: IAdvancedMap>; + + 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): IAdvancedMap + { + let existing = this._objectsPerType.getValue(k); + + if(!existing && _arg_2) + { + existing = new AdvancedMap(); + + this._objectsPerType.add(k, existing); + } + + return existing; + } + + public get objects(): IAdvancedMap + { + return this._objects; + } + + public get totalObjects(): number + { + return this._objects.length; + } +} diff --git a/packages/room/src/RoomObjectVisualizationFactory.ts b/packages/room/src/RoomObjectVisualizationFactory.ts new file mode 100644 index 0000000..0fce7c3 --- /dev/null +++ b/packages/room/src/RoomObjectVisualizationFactory.ts @@ -0,0 +1,225 @@ +import { IAssetData, IObjectVisualizationData, IRoomObjectGraphicVisualization, IRoomObjectVisualizationFactory, RoomObjectVisualizationType } from '@nitrots/api'; +import { NitroLogger } from '@nitrots/utils'; +import { AvatarVisualization, AvatarVisualizationData, FurnitureAnimatedVisualization, FurnitureAnimatedVisualizationData, FurnitureBBVisualization, FurnitureBadgeDisplayVisualization, FurnitureBottleVisualization, FurnitureBuilderPlaceholderVisualization, FurnitureCounterClockVisualization, FurnitureCuboidVisualization, FurnitureExternalImageVisualization, FurnitureFireworksVisualization, FurnitureGiftWrappedFireworksVisualization, FurnitureGiftWrappedVisualization, FurnitureGuildCustomizedVisualization, FurnitureGuildIsometricBadgeVisualization, FurnitureHabboWheelVisualization, FurnitureIsometricBBVisualization, FurnitureMannequinVisualization, FurnitureMannequinVisualizationData, FurniturePartyBeamerVisualization, FurniturePlanetSystemVisualization, FurniturePosterVisualization, FurnitureQueueTileVisualization, FurnitureResettingAnimatedVisualization, FurnitureRoomBackgroundVisualization, FurnitureScoreBoardVisualization, FurnitureSoundBlockVisualization, FurnitureStickieVisualization, FurnitureValRandomizerVisualization, FurnitureVisualization, FurnitureVisualizationData, FurnitureVoteCounterVisualization, FurnitureVoteMajorityVisualization, FurnitureWaterAreaVisualization, FurnitureYoutubeVisualization, PetVisualization, PetVisualizationData, RoomObjectSpriteVisualization, RoomVisualization, RoomVisualizationData, TileCursorVisualization } from './object'; + +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_ISOMETRIC_BB: + visualization = FurnitureIsometricBBVisualization; + 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_ISOMETRIC_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(RoomObjectVisualizationFactory.CACHING_ENABLED) this._visualizationDatas.set(type, visualizationData); + + return visualizationData; + } +} diff --git a/packages/room/src/RoomPreviewer.ts b/packages/room/src/RoomPreviewer.ts new file mode 100644 index 0000000..c7c02da --- /dev/null +++ b/packages/room/src/RoomPreviewer.ts @@ -0,0 +1,858 @@ +import { IGetImageListener, IImageResult, IObjectData, IRoomEngine, IRoomObjectController, IRoomRenderingCanvas, IVector3D, LegacyDataType, RoomObjectCategory, RoomObjectUserType, RoomObjectVariable } from '@nitrots/api'; +import { FloorHeightMapMessageParser, RoomEntryTileMessageParser } from '@nitrots/communication'; +import { GetEventDispatcher, RoomEngineEvent, RoomEngineObjectEvent } from '@nitrots/events'; +import { GetTickerTime, RoomId, Vector3d } from '@nitrots/utils'; +import { Container, Point, Rectangle, Sprite, Texture } from 'pixi.js'; +import { RoomEngine } from './RoomEngine'; +import { ObjectRoomMapUpdateMessage } from './messages'; +import { RoomPlaneParser } from './object/RoomPlaneParser'; +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 _backgroundSprite: Sprite = null; + 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 && GetEventDispatcher()) + { + GetEventDispatcher().addEventListener(RoomEngineObjectEvent.ADDED, this.onRoomObjectAdded); + GetEventDispatcher().addEventListener(RoomEngineObjectEvent.CONTENT_UPDATED, this.onRoomObjectAdded); + GetEventDispatcher().addEventListener(RoomEngineEvent.INITIALIZED, this.onRoomInitializedonRoomInitialized); + } + + this.createRoomForPreview(); + } + + public dispose(): void + { + this.reset(true); + + if(this.isRoomEngineReady && GetEventDispatcher()) + { + GetEventDispatcher().removeEventListener(RoomEngineObjectEvent.ADDED, this.onRoomObjectAdded); + GetEventDispatcher().removeEventListener(RoomEngineObjectEvent.CONTENT_UPDATED, this.onRoomObjectAdded); + GetEventDispatcher().removeEventListener(RoomEngineEvent.INITIALIZED, this.onRoomInitializedonRoomInitialized); + } + + if(this._backgroundSprite) + { + this._backgroundSprite.destroy(); + + this._backgroundSprite = null; + } + + 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 FloorHeightMapMessageParser(); + + parser.flush(); + parser.parseModel(model, wallHeight, scale); + + //@ts-ignore + 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: RoomEntryTileMessageParser = 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) + { + 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 = GetTickerTime(); + 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 = GetTickerTime(); + 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 = GetTickerTime(); + 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 = GetTickerTime(); + 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 updateObjectStuffData(stuffData: IObjectData): void + { + if(this.isRoomEngineReady) this._roomEngine.updateRoomObjectFloor(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, null, null, stuffData.state, stuffData); + } + + 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.getValidRoomObjectDirection(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 = GetTickerTime(); + + 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): Container + { + 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)) + { + let backgroundSprite = this._backgroundSprite; + + if(!backgroundSprite) + { + backgroundSprite = new Sprite(Texture.WHITE); + + displayObject.addChildAt(backgroundSprite, 0); + } + + backgroundSprite.width = width; + backgroundSprite.height = height; + //backgroundSprite.tint = this._backgroundColor; + } + + 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; + + if(this._backgroundSprite) + { + this._backgroundSprite.width = width; + this._backgroundSprite.height = 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; + } + + public updatePreviewObjectBoundingRectangle(point: Point = null): void + { + if(!point) point = new Point(0, 0); + + 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; + } + } + } + } + + 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 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): IImageResult + { + 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): IImageResult + { + if(this.isRoomEngineReady) + { + return this._roomEngine.getRoomObjectImage(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory, direction, scale, listener, bgColor); + } + + return null; + } + + public getRoomObjectCurrentImage(): Texture + { + if(this.isRoomEngineReady) + { + const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory); + + if(roomObject && roomObject.visualization) return roomObject.visualization.getImage(); + } + + 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 true; + } + + public get roomId(): number + { + return this._previewRoomId; + } + + public get backgroundColor(): number + { + return this._backgroundColor; + } + + public set backgroundColor(color: number) + { + this._backgroundColor = color; + } + + public get width(): number + { + return this._currentPreviewCanvasWidth; + } + + public get height(): number + { + return this._currentPreviewCanvasHeight; + } +} diff --git a/packages/room/src/RoomVariableEnum.ts b/packages/room/src/RoomVariableEnum.ts new file mode 100644 index 0000000..7fdc564 --- /dev/null +++ b/packages/room/src/RoomVariableEnum.ts @@ -0,0 +1,11 @@ +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'; +} diff --git a/packages/room/src/index.ts b/packages/room/src/index.ts new file mode 100644 index 0000000..f09b10d --- /dev/null +++ b/packages/room/src/index.ts @@ -0,0 +1,36 @@ +export * from './GetRoomContentLoader'; +export * from './GetRoomEngine'; +export * from './GetRoomManager'; +export * from './GetRoomMessageHandler'; +export * from './GetRoomObjectLogicFactory'; +export * from './GetRoomObjectVisualizationFactory'; +export * from './ImageResult'; +export * from './PetColorResult'; +export * from './RoomContentLoader'; +export * from './RoomEngine'; +export * from './RoomInstance'; +export * from './RoomManager'; +export * from './RoomMessageHandler'; +export * from './RoomObjectEventHandler'; +export * from './RoomObjectLogicFactory'; +export * from './RoomObjectManager'; +export * from './RoomObjectVisualizationFactory'; +export * from './RoomPreviewer'; +export * from './RoomVariableEnum'; +export * from './messages'; +export * from './object'; +export * from './object/logic'; +export * from './object/logic/furniture'; +export * from './object/visualization'; +export * from './object/visualization/avatar'; +export * from './object/visualization/avatar/additions'; +export * from './object/visualization/data'; +export * from './object/visualization/furniture'; +export * from './object/visualization/pet'; +export * from './object/visualization/room'; +export * from './object/visualization/room/mask'; +export * from './object/visualization/room/utils'; +export * from './renderer'; +export * from './renderer/cache'; +export * from './renderer/utils'; +export * from './utils'; diff --git a/packages/room/src/messages/ObjectAdUpdateMessage.ts b/packages/room/src/messages/ObjectAdUpdateMessage.ts new file mode 100644 index 0000000..6edb597 --- /dev/null +++ b/packages/room/src/messages/ObjectAdUpdateMessage.ts @@ -0,0 +1,21 @@ +import { RoomObjectUpdateMessage } from './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; + } +} diff --git a/packages/room/src/messages/ObjectAvatarCarryObjectUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarCarryObjectUpdateMessage.ts new file mode 100644 index 0000000..4671751 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarChatUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarChatUpdateMessage.ts new file mode 100644 index 0000000..91b9834 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarDanceUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarDanceUpdateMessage.ts new file mode 100644 index 0000000..395739f --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarEffectUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarEffectUpdateMessage.ts new file mode 100644 index 0000000..99c82a0 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarExperienceUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarExperienceUpdateMessage.ts new file mode 100644 index 0000000..ba082a9 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarExpressionUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarExpressionUpdateMessage.ts new file mode 100644 index 0000000..8a33d15 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarFigureUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarFigureUpdateMessage.ts new file mode 100644 index 0000000..004e0ae --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarFlatControlUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarFlatControlUpdateMessage.ts new file mode 100644 index 0000000..5134488 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarGestureUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarGestureUpdateMessage.ts new file mode 100644 index 0000000..ad810f8 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarGuideStatusUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarGuideStatusUpdateMessage.ts new file mode 100644 index 0000000..bf5bd04 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarMutedUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarMutedUpdateMessage.ts new file mode 100644 index 0000000..548aa16 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarOwnMessage.ts b/packages/room/src/messages/ObjectAvatarOwnMessage.ts new file mode 100644 index 0000000..cbdeeaf --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarPetGestureUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarPetGestureUpdateMessage.ts new file mode 100644 index 0000000..c4f52da --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarPlayerValueUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarPlayerValueUpdateMessage.ts new file mode 100644 index 0000000..af74ee0 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarPlayingGameUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarPlayingGameUpdateMessage.ts new file mode 100644 index 0000000..d18ff82 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarPostureUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarPostureUpdateMessage.ts new file mode 100644 index 0000000..b7e5ec0 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarSelectedMessage.ts b/packages/room/src/messages/ObjectAvatarSelectedMessage.ts new file mode 100644 index 0000000..dc7ac65 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarSignUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarSignUpdateMessage.ts new file mode 100644 index 0000000..bfb63b8 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarSleepUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarSleepUpdateMessage.ts new file mode 100644 index 0000000..747fd13 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarTypingUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarTypingUpdateMessage.ts new file mode 100644 index 0000000..0038f76 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectAvatarUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarUpdateMessage.ts new file mode 100644 index 0000000..a6fe8de --- /dev/null +++ b/packages/room/src/messages/ObjectAvatarUpdateMessage.ts @@ -0,0 +1,33 @@ +import { IVector3D } from '@nitrots/api'; +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; + } +} diff --git a/packages/room/src/messages/ObjectAvatarUseObjectUpdateMessage.ts b/packages/room/src/messages/ObjectAvatarUseObjectUpdateMessage.ts new file mode 100644 index 0000000..6997a70 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectDataUpdateMessage.ts b/packages/room/src/messages/ObjectDataUpdateMessage.ts new file mode 100644 index 0000000..500c9ca --- /dev/null +++ b/packages/room/src/messages/ObjectDataUpdateMessage.ts @@ -0,0 +1,33 @@ +import { IObjectData } from '@nitrots/api'; +import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage'; + +export class ObjectDataUpdateMessage extends RoomObjectUpdateMessage +{ + private _state: number; + private _data: IObjectData; + private _extra: number; + + constructor(state: number, data: IObjectData, extra: number = null) + { + 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; + } +} diff --git a/packages/room/src/messages/ObjectGroupBadgeUpdateMessage.ts b/packages/room/src/messages/ObjectGroupBadgeUpdateMessage.ts new file mode 100644 index 0000000..23aff3e --- /dev/null +++ b/packages/room/src/messages/ObjectGroupBadgeUpdateMessage.ts @@ -0,0 +1,27 @@ +import { RoomObjectUpdateMessage } from './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; + } +} diff --git a/packages/room/src/messages/ObjectHeightUpdateMessage.ts b/packages/room/src/messages/ObjectHeightUpdateMessage.ts new file mode 100644 index 0000000..d781f20 --- /dev/null +++ b/packages/room/src/messages/ObjectHeightUpdateMessage.ts @@ -0,0 +1,19 @@ +import { IVector3D } from '@nitrots/api'; +import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage'; + +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; + } +} diff --git a/packages/room/src/messages/ObjectItemDataUpdateMessage.ts b/packages/room/src/messages/ObjectItemDataUpdateMessage.ts new file mode 100644 index 0000000..7017ed3 --- /dev/null +++ b/packages/room/src/messages/ObjectItemDataUpdateMessage.ts @@ -0,0 +1,18 @@ +import { RoomObjectUpdateMessage } from './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; + } +} diff --git a/packages/room/src/messages/ObjectModelDataUpdateMessage.ts b/packages/room/src/messages/ObjectModelDataUpdateMessage.ts new file mode 100644 index 0000000..ce61615 --- /dev/null +++ b/packages/room/src/messages/ObjectModelDataUpdateMessage.ts @@ -0,0 +1,25 @@ +import { RoomObjectUpdateMessage } from './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/packages/room/src/messages/ObjectMoveUpdateMessage.ts b/packages/room/src/messages/ObjectMoveUpdateMessage.ts new file mode 100644 index 0000000..c4fce0b --- /dev/null +++ b/packages/room/src/messages/ObjectMoveUpdateMessage.ts @@ -0,0 +1,28 @@ +import { IVector3D } from '@nitrots/api'; +import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage'; + +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; + } +} diff --git a/packages/room/src/messages/ObjectRoomColorUpdateMessage.ts b/packages/room/src/messages/ObjectRoomColorUpdateMessage.ts new file mode 100644 index 0000000..3387c0d --- /dev/null +++ b/packages/room/src/messages/ObjectRoomColorUpdateMessage.ts @@ -0,0 +1,41 @@ +import { RoomObjectUpdateMessage } from './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; + } +} diff --git a/packages/room/src/messages/ObjectRoomFloorHoleUpdateMessage.ts b/packages/room/src/messages/ObjectRoomFloorHoleUpdateMessage.ts new file mode 100644 index 0000000..4231678 --- /dev/null +++ b/packages/room/src/messages/ObjectRoomFloorHoleUpdateMessage.ts @@ -0,0 +1,56 @@ +import { RoomObjectUpdateMessage } from './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; + } +} diff --git a/packages/room/src/messages/ObjectRoomMapUpdateMessage.ts b/packages/room/src/messages/ObjectRoomMapUpdateMessage.ts new file mode 100644 index 0000000..2bd33a2 --- /dev/null +++ b/packages/room/src/messages/ObjectRoomMapUpdateMessage.ts @@ -0,0 +1,28 @@ +import { RoomMapData } from '../object'; +import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage'; + +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/packages/room/src/messages/ObjectRoomMaskUpdateMessage.ts b/packages/room/src/messages/ObjectRoomMaskUpdateMessage.ts new file mode 100644 index 0000000..9ad096f --- /dev/null +++ b/packages/room/src/messages/ObjectRoomMaskUpdateMessage.ts @@ -0,0 +1,54 @@ +import { IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage'; + +export class ObjectRoomMaskUpdateMessage extends RoomObjectUpdateMessage +{ + public static ADD_MASK: string = 'RORMUM_ADD_MASK'; + public static REMOVE_MASK: 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: IVector3D; + 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; + } +} diff --git a/packages/room/src/messages/ObjectRoomPlanePropertyUpdateMessage.ts b/packages/room/src/messages/ObjectRoomPlanePropertyUpdateMessage.ts new file mode 100644 index 0000000..1d62f59 --- /dev/null +++ b/packages/room/src/messages/ObjectRoomPlanePropertyUpdateMessage.ts @@ -0,0 +1,28 @@ +import { RoomObjectUpdateMessage } from './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; + } +} diff --git a/packages/room/src/messages/ObjectRoomPlaneVisibilityUpdateMessage.ts b/packages/room/src/messages/ObjectRoomPlaneVisibilityUpdateMessage.ts new file mode 100644 index 0000000..3bb79cd --- /dev/null +++ b/packages/room/src/messages/ObjectRoomPlaneVisibilityUpdateMessage.ts @@ -0,0 +1,28 @@ +import { RoomObjectUpdateMessage } from './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; + } +} diff --git a/packages/room/src/messages/ObjectRoomUpdateMessage.ts b/packages/room/src/messages/ObjectRoomUpdateMessage.ts new file mode 100644 index 0000000..6d3607a --- /dev/null +++ b/packages/room/src/messages/ObjectRoomUpdateMessage.ts @@ -0,0 +1,29 @@ +import { RoomObjectUpdateMessage } from './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; + } +} diff --git a/packages/room/src/messages/ObjectSelectedMessage.ts b/packages/room/src/messages/ObjectSelectedMessage.ts new file mode 100644 index 0000000..e807613 --- /dev/null +++ b/packages/room/src/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/packages/room/src/messages/ObjectStateUpdateMessage.ts b/packages/room/src/messages/ObjectStateUpdateMessage.ts new file mode 100644 index 0000000..a6db644 --- /dev/null +++ b/packages/room/src/messages/ObjectStateUpdateMessage.ts @@ -0,0 +1,9 @@ +import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage'; + +export class ObjectStateUpdateMessage extends RoomObjectUpdateMessage +{ + constructor() + { + super(null, null); + } +} diff --git a/packages/room/src/messages/ObjectTileCursorUpdateMessage.ts b/packages/room/src/messages/ObjectTileCursorUpdateMessage.ts new file mode 100644 index 0000000..dbfb724 --- /dev/null +++ b/packages/room/src/messages/ObjectTileCursorUpdateMessage.ts @@ -0,0 +1,40 @@ +import { IVector3D } from '@nitrots/api'; +import { RoomObjectUpdateMessage } from './RoomObjectUpdateMessage'; + +export class ObjectTileCursorUpdateMessage extends RoomObjectUpdateMessage +{ + private _height: number; + private _sourceEventId: string; + private _visible: boolean; + private _toggleVisibility: boolean; + + constructor(k: IVector3D, 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 sourceEventId(): string + { + return this._sourceEventId; + } + + public get toggleVisibility(): boolean + { + return this._toggleVisibility; + } +} diff --git a/packages/room/src/messages/ObjectVisibilityUpdateMessage.ts b/packages/room/src/messages/ObjectVisibilityUpdateMessage.ts new file mode 100644 index 0000000..3d7c836 --- /dev/null +++ b/packages/room/src/messages/ObjectVisibilityUpdateMessage.ts @@ -0,0 +1,21 @@ +import { RoomObjectUpdateMessage } from './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; + } +} diff --git a/packages/room/src/messages/RoomObjectUpdateMessage.ts b/packages/room/src/messages/RoomObjectUpdateMessage.ts new file mode 100644 index 0000000..0dfe63d --- /dev/null +++ b/packages/room/src/messages/RoomObjectUpdateMessage.ts @@ -0,0 +1,23 @@ +import { IVector3D } from '@nitrots/api'; + +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; + } +} diff --git a/packages/room/src/messages/index.ts b/packages/room/src/messages/index.ts new file mode 100644 index 0000000..e4f6bd9 --- /dev/null +++ b/packages/room/src/messages/index.ts @@ -0,0 +1,41 @@ +export * from './ObjectAdUpdateMessage'; +export * from './ObjectAvatarCarryObjectUpdateMessage'; +export * from './ObjectAvatarChatUpdateMessage'; +export * from './ObjectAvatarDanceUpdateMessage'; +export * from './ObjectAvatarEffectUpdateMessage'; +export * from './ObjectAvatarExperienceUpdateMessage'; +export * from './ObjectAvatarExpressionUpdateMessage'; +export * from './ObjectAvatarFigureUpdateMessage'; +export * from './ObjectAvatarFlatControlUpdateMessage'; +export * from './ObjectAvatarGestureUpdateMessage'; +export * from './ObjectAvatarGuideStatusUpdateMessage'; +export * from './ObjectAvatarMutedUpdateMessage'; +export * from './ObjectAvatarOwnMessage'; +export * from './ObjectAvatarPetGestureUpdateMessage'; +export * from './ObjectAvatarPlayerValueUpdateMessage'; +export * from './ObjectAvatarPlayingGameUpdateMessage'; +export * from './ObjectAvatarPostureUpdateMessage'; +export * from './ObjectAvatarSelectedMessage'; +export * from './ObjectAvatarSignUpdateMessage'; +export * from './ObjectAvatarSleepUpdateMessage'; +export * from './ObjectAvatarTypingUpdateMessage'; +export * from './ObjectAvatarUpdateMessage'; +export * from './ObjectAvatarUseObjectUpdateMessage'; +export * from './ObjectDataUpdateMessage'; +export * from './ObjectGroupBadgeUpdateMessage'; +export * from './ObjectHeightUpdateMessage'; +export * from './ObjectItemDataUpdateMessage'; +export * from './ObjectModelDataUpdateMessage'; +export * from './ObjectMoveUpdateMessage'; +export * from './ObjectRoomColorUpdateMessage'; +export * from './ObjectRoomFloorHoleUpdateMessage'; +export * from './ObjectRoomMapUpdateMessage'; +export * from './ObjectRoomMaskUpdateMessage'; +export * from './ObjectRoomPlanePropertyUpdateMessage'; +export * from './ObjectRoomPlaneVisibilityUpdateMessage'; +export * from './ObjectRoomUpdateMessage'; +export * from './ObjectSelectedMessage'; +export * from './ObjectStateUpdateMessage'; +export * from './ObjectTileCursorUpdateMessage'; +export * from './ObjectVisibilityUpdateMessage'; +export * from './RoomObjectUpdateMessage'; diff --git a/packages/room/src/object/RoomFloorHole.ts b/packages/room/src/object/RoomFloorHole.ts new file mode 100644 index 0000000..456dfd5 --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/RoomMapData.ts b/packages/room/src/object/RoomMapData.ts new file mode 100644 index 0000000..2013364 --- /dev/null +++ b/packages/room/src/object/RoomMapData.ts @@ -0,0 +1,90 @@ +import { IRoomMapData } from '@nitrots/api'; + +export class RoomMapData implements IRoomMapData +{ + 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 }; + + 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 + }; + } + + 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; + } +} diff --git a/packages/room/src/object/RoomMapMaskData.ts b/packages/room/src/object/RoomMapMaskData.ts new file mode 100644 index 0000000..325d092 --- /dev/null +++ b/packages/room/src/object/RoomMapMaskData.ts @@ -0,0 +1,16 @@ +import { IVector3D } from '@nitrots/api'; + +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; + } +} diff --git a/packages/room/src/object/RoomObject.ts b/packages/room/src/object/RoomObject.ts new file mode 100644 index 0000000..55a2bfa --- /dev/null +++ b/packages/room/src/object/RoomObject.ts @@ -0,0 +1,229 @@ +import { IRoomObjectController, IRoomObjectEventHandler, IRoomObjectModel, IRoomObjectMouseHandler, IRoomObjectUpdateMessage, IRoomObjectVisualization, IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { RoomObjectModel } from './RoomObjectModel'; + +export class RoomObject implements IRoomObjectController +{ + private static OBJECT_COUNTER: number = 0; + + private _id: number; + private _instanceId: number; + private _type: string; + private _model: IRoomObjectModel = new RoomObjectModel(); + + private _location: IVector3D = new Vector3d(); + private _direction: IVector3D = new Vector3d(); + private _states: number[] = []; + + private _visualization: IRoomObjectVisualization = null; + private _logic: IRoomObjectEventHandler = null; + private _pendingLogicMessages: IRoomObjectUpdateMessage[] = []; + + private _updateCounter: number = 0; + private _isReady: boolean = false; + + constructor(id: number, stateCount: number, type: string) + { + this._id = id; + this._instanceId = RoomObject.OBJECT_COUNTER++; + this._type = type; + + let i = (stateCount - 1); + + while(i >= 0) + { + this._states[i] = 0; + + i--; + } + } + + public dispose(): void + { + this._pendingLogicMessages = []; + + this.setVisualization(null); + this.setLogic(null); + + if(this._model) this._model.dispose(); + } + + 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: IRoomObjectUpdateMessage): 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; + } +} diff --git a/packages/room/src/object/RoomObjectModel.ts b/packages/room/src/object/RoomObjectModel.ts new file mode 100644 index 0000000..bc7a2ff --- /dev/null +++ b/packages/room/src/object/RoomObjectModel.ts @@ -0,0 +1,47 @@ +import { IRoomObjectModel } from '@nitrots/api'; + +export class RoomObjectModel implements IRoomObjectModel +{ + private _map: Map = new Map(); + private _updateCounter: number = 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 + { + if(this._map.has(key)) + { + if(this._map.get(key) === value) return; + } + + 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; + } +} diff --git a/packages/room/src/object/RoomPlaneBitmapMaskData.ts b/packages/room/src/object/RoomPlaneBitmapMaskData.ts new file mode 100644 index 0000000..26599be --- /dev/null +++ b/packages/room/src/object/RoomPlaneBitmapMaskData.ts @@ -0,0 +1,56 @@ +import { IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; + +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; + } +} diff --git a/packages/room/src/object/RoomPlaneBitmapMaskParser.ts b/packages/room/src/object/RoomPlaneBitmapMaskParser.ts new file mode 100644 index 0000000..82a223d --- /dev/null +++ b/packages/room/src/object/RoomPlaneBitmapMaskParser.ts @@ -0,0 +1,147 @@ +import { IVector3D } from '@nitrots/api'; +import { RoomMapMaskData } from './RoomMapMaskData'; +import { RoomPlaneBitmapMaskData } from './RoomPlaneBitmapMaskData'; + +export class RoomPlaneBitmapMaskParser +{ + private _masks: Map; + + constructor() + { + this._masks = new Map(); + } + + public get maskCount(): 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 removeMask(k: string): boolean + { + const existing = this._masks.get(k); + + if(existing) + { + this._masks.delete(k); + + existing.dispose(); + + return true; + } + + return false; + } + + public getXML(): RoomMapMaskData + { + const data = new RoomMapMaskData(); + + for(const [key, mask] of this._masks.entries()) + { + if(!mask) continue; + + const type = this.getMaskType(mask); + const category = this.getMaskCategory(mask); + const location = this.getMaskLocation(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 getMaskLocation(mask: RoomPlaneBitmapMaskData): IVector3D + { + if(!mask) return null; + + return mask.loc; + } + + public getMaskType(mask: RoomPlaneBitmapMaskData): string + { + if(!mask) return null; + + return mask.type; + } + + public getMaskCategory(mask: RoomPlaneBitmapMaskData): string + { + if(!mask) return null; + + return mask.category; + } + + public get masks(): Map + { + return this._masks; + } +} diff --git a/packages/room/src/object/RoomPlaneData.ts b/packages/room/src/object/RoomPlaneData.ts new file mode 100644 index 0000000..3f0cc4e --- /dev/null +++ b/packages/room/src/object/RoomPlaneData.ts @@ -0,0 +1,202 @@ +import { IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +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 leftSide(): IVector3D + { + return this._leftSide; + } + + public get rightSide(): IVector3D + { + return this._rightSide; + } + + public get normal(): IVector3D + { + return this._normal; + } + + public get normalDirection(): IVector3D + { + return this._normalDirection; + } + + public get secondaryNormalCount(): number + { + return this._secondaryNormals.length; + } + + public get maskCount(): number + { + return this._masks.length; + } + + public getSecondaryNormal(k: number): IVector3D + { + if(((k < 0) || (k >= this.secondaryNormalCount))) + { + 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 getMask(k: number): RoomPlaneMaskData + { + if(((k < 0) || (k >= this.maskCount))) + { + return null; + } + return this._masks[k]; + } + + public getMaskLeftSideLoc(k: number): number + { + const _local_2: RoomPlaneMaskData = this.getMask(k); + if(_local_2 != null) + { + return _local_2.leftSideLoc; + } + return -1; + } + + public getMaskRightSideLoc(k: number): number + { + const _local_2: RoomPlaneMaskData = this.getMask(k); + if(_local_2 != null) + { + return _local_2.rightSideLoc; + } + return -1; + } + + public getMaskLeftSideLength(k: number): number + { + const _local_2: RoomPlaneMaskData = this.getMask(k); + if(_local_2 != null) + { + return _local_2.leftSideLength; + } + return -1; + } + + public getMaskRightSideLength(k: number): number + { + const _local_2: RoomPlaneMaskData = this.getMask(k); + if(_local_2 != null) + { + return _local_2.rightSideLength; + } + return -1; + } +} diff --git a/packages/room/src/object/RoomPlaneMaskData.ts b/packages/room/src/object/RoomPlaneMaskData.ts new file mode 100644 index 0000000..7baf59c --- /dev/null +++ b/packages/room/src/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 leftSideLoc(): number + { + return this._leftSideLoc; + } + + public get rightSideLoc(): number + { + return this._rightSideLoc; + } + + public get leftSideLength(): number + { + return this._leftSideLength; + } + + public get rightSideLength(): number + { + return this._rightSideLength; + } +} diff --git a/packages/room/src/object/RoomPlaneParser.ts b/packages/room/src/object/RoomPlaneParser.ts new file mode 100644 index 0000000..da5602e --- /dev/null +++ b/packages/room/src/object/RoomPlaneParser.ts @@ -0,0 +1,1661 @@ +import { IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { Point } from 'pixi.js'; +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[][]; + + 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.addWall(_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.getBorder(_local_2))) && (_local_2 < _local_3))) + { + if(k.getLeftTurn(_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.setHideWall(_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.getHideWall(_local_3)) + { + _local_4 = k.getCorner(_local_3); + _local_5 = k.getDirection(_local_3); + _local_6 = k.getLength(_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.setLength(_local_3, _local_10); + break; + } + _local_9++; + } + else + { + if(_local_9 > 0) + { + k.moveCorner(_local_3, _local_9); + break; + } + } + _local_10++; + } + if(_local_9 == _local_6) + { + k.setHideWall(_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.getCorner(_local_9); + _local_11 = _arg_3.getEndPoint(_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.getHideWall(_local_4)) + { + _local_5 = k.getCorner(_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.getLength(_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.getHideWall(_local_9)) + { + k.setHideWall(_local_4, true); + } + } + else + { + k.setHideWall(_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.getHideWall(_local_7)) + { + const _local_8 = k.getCorner(_local_7); + const _local_9 = k.getDirection(_local_7); + const _local_10 = k.getLength(_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.getEndPoint(_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.getLeftTurn(_local_7); + const _local_23 = k.getLeftTurn((((_local_7 - 1) + _local_3) % _local_3)); + const _local_24 = k.getHideWall(((_local_7 + 1) % _local_3)); + const _local_25 = k.getManuallyLeftCut(_local_7); + const _local_26 = k.getManuallyRightCut(_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.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; + + 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.leftSide; + } + + public getPlaneRightSide(k: number): IVector3D + { + if(((k < 0) || (k >= this.planeCount))) return null; + + const planeData = this._planes[k]; + + if(!planeData) return null; + + return planeData.rightSide; + } + + public getPlaneNormalDirection(k: number): IVector3D + { + if(((k < 0) || (k >= this.planeCount))) return null; + + const planeData = this._planes[k]; + + if(!planeData) return null; + + return planeData.normalDirection; + } + + 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.secondaryNormalCount) + { + _local_3.push(_local_2.getSecondaryNormal(_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.maskCount; + } + + 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.getMaskLeftSideLoc(_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.getMaskRightSideLoc(_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.getMaskLeftSideLength(_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.getMaskRightSideLength(_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++; + } + } +} diff --git a/packages/room/src/object/RoomWallData.ts b/packages/room/src/object/RoomWallData.ts new file mode 100644 index 0000000..2bb7aff --- /dev/null +++ b/packages/room/src/object/RoomWallData.ts @@ -0,0 +1,182 @@ +import { IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { Point } from 'pixi.js'; + +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 addWall(k: Point, _arg_2: number, _arg_3: number, _arg_4: boolean, _arg_5: boolean): void + { + if(((this._addDuplicates) || (this.checkIsNotDuplicate(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 checkIsNotDuplicate(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 getCorner(k: number): Point + { + return this._corners[k]; + } + + public getEndPoint(k: number): Point + { + this.calculateWallEndPoints(); + return this._endPoints[k]; + } + + public getLength(k: number): number + { + return this._lengths[k]; + } + + public getDirection(k: number): number + { + return this._directions[k]; + } + + public getBorder(k: number): boolean + { + return this._borders[k]; + } + + public getHideWall(k: number): boolean + { + return this._hideWalls[k]; + } + + public getLeftTurn(k: number): boolean + { + return this._leftTurns[k]; + } + + public getManuallyLeftCut(k: number): boolean + { + return this._manuallyLeftCut[k]; + } + + public getManuallyRightCut(k: number): boolean + { + return this._manuallyRightCut[k]; + } + + public setHideWall(k: number, _arg_2: boolean): void + { + this._hideWalls[k] = _arg_2; + } + + public setLength(k: number, _arg_2: number): void + { + if(_arg_2 < this._lengths[k]) + { + this._lengths[k] = _arg_2; + this._manuallyRightCut[k] = true; + } + } + + public moveCorner(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 calculateWallEndPoints(): 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.getCorner(k); + _local_3 = new Point(_local_2.x, _local_2.y); + _local_4 = RoomWallData.WALL_DIRECTION_VECTORS[this.getDirection(k)]; + _local_5 = this.getLength(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++; + } + } + } +} diff --git a/packages/room/src/object/index.ts b/packages/room/src/object/index.ts new file mode 100644 index 0000000..ccc0001 --- /dev/null +++ b/packages/room/src/object/index.ts @@ -0,0 +1,22 @@ +export * from './RoomFloorHole'; +export * from './RoomMapData'; +export * from './RoomMapMaskData'; +export * from './RoomObject'; +export * from './RoomObjectModel'; +export * from './RoomPlaneBitmapMaskData'; +export * from './RoomPlaneBitmapMaskParser'; +export * from './RoomPlaneData'; +export * from './RoomPlaneMaskData'; +export * from './RoomPlaneParser'; +export * from './RoomWallData'; +export * from './logic'; +export * from './logic/furniture'; +export * from './visualization'; +export * from './visualization/avatar'; +export * from './visualization/avatar/additions'; +export * from './visualization/data'; +export * from './visualization/furniture'; +export * from './visualization/pet'; +export * from './visualization/room'; +export * from './visualization/room/mask'; +export * from './visualization/room/utils'; diff --git a/packages/room/src/object/logic/AvatarLogic.ts b/packages/room/src/object/logic/AvatarLogic.ts new file mode 100644 index 0000000..97e5589 --- /dev/null +++ b/packages/room/src/object/logic/AvatarLogic.ts @@ -0,0 +1,504 @@ + +import { AvatarAction, IRoomGeometry, IRoomObjectModel, IVector3D, MouseEventType, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectFurnitureActionEvent, RoomObjectMouseEvent, RoomObjectMoveEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { GetTickerTime, Vector3d } from '@nitrots/utils'; +import { ObjectAvatarCarryObjectUpdateMessage, ObjectAvatarChatUpdateMessage, ObjectAvatarDanceUpdateMessage, ObjectAvatarEffectUpdateMessage, ObjectAvatarExpressionUpdateMessage, ObjectAvatarFigureUpdateMessage, ObjectAvatarFlatControlUpdateMessage, ObjectAvatarGestureUpdateMessage, ObjectAvatarMutedUpdateMessage, ObjectAvatarOwnMessage, ObjectAvatarPlayerValueUpdateMessage, ObjectAvatarPlayingGameUpdateMessage, ObjectAvatarPostureUpdateMessage, ObjectAvatarSelectedMessage, ObjectAvatarSignUpdateMessage, ObjectAvatarSleepUpdateMessage, ObjectAvatarTypingUpdateMessage, ObjectAvatarUpdateMessage, ObjectAvatarUseObjectUpdateMessage, RoomObjectUpdateMessage } from '../../messages'; +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 EFFECT_TYPE_SPLASH: number = 28; + private static EFFECT_SPLASH_LENGTH: number = 500; + private static EFFECT_TYPE_SWIM: number = 29; + private static EFFECT_TYPE_SPLASH_DARK: number = 184; + private static EFFECT_TYPE_SWIM_DARK: number = 185; + + private _selected: boolean; + private _reportedLocation: IVector3D; + 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 = GetTickerTime() + 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, RoomObjectMouseEvent.DOUBLE_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.EFFECT_TYPE_SPLASH) + { + this._effectChangeTimeStamp = (GetTickerTime() + AvatarLogic.EFFECT_SPLASH_LENGTH); + this._newEffect = AvatarLogic.EFFECT_TYPE_SWIM; + } + + else if(effect === AvatarLogic.EFFECT_TYPE_SPLASH_DARK) + { + this._effectChangeTimeStamp = (GetTickerTime() + AvatarLogic.EFFECT_SPLASH_LENGTH); + this._newEffect = AvatarLogic.EFFECT_TYPE_SWIM_DARK; + } + + else if(model.getValue(RoomObjectVariable.FIGURE_EFFECT) === AvatarLogic.EFFECT_TYPE_SWIM) + { + this._effectChangeTimeStamp = (GetTickerTime() + AvatarLogic.EFFECT_SPLASH_LENGTH); + this._newEffect = effect; + + effect = AvatarLogic.EFFECT_TYPE_SPLASH; + } + + else if(model.getValue(RoomObjectVariable.FIGURE_EFFECT) === AvatarLogic.EFFECT_TYPE_SWIM_DARK) + { + this._effectChangeTimeStamp = (GetTickerTime() + AvatarLogic.EFFECT_SPLASH_LENGTH); + this._newEffect = effect; + + effect = AvatarLogic.EFFECT_TYPE_SPLASH_DARK; + } + + else if(delay === 0) + { + this._effectChangeTimeStamp = 0; + } + + else + { + this._effectChangeTimeStamp = (GetTickerTime() + 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.DOUBLE_CLICK: + eventType = RoomObjectMouseEvent.DOUBLE_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.eventId, 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/packages/room/src/object/logic/MovingObjectLogic.ts b/packages/room/src/object/logic/MovingObjectLogic.ts new file mode 100644 index 0000000..201d8f2 --- /dev/null +++ b/packages/room/src/object/logic/MovingObjectLogic.ts @@ -0,0 +1,148 @@ +import { IRoomObjectController, IRoomObjectUpdateMessage, IVector3D, RoomObjectVariable } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { ObjectMoveUpdateMessage } from '../../messages'; +import { RoomObjectLogicBase } from './RoomObjectLogicBase'; + +export class MovingObjectLogic extends RoomObjectLogicBase +{ + public static DEFAULT_UPDATE_INTERVAL: number = 500; + 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 = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL; + } + + 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: IRoomObjectUpdateMessage): 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; + } + + protected set updateInterval(interval: number) + { + if(interval <= 0) interval = 1; + + this._updateInterval = interval; + } +} diff --git a/packages/room/src/object/logic/PetLogic.ts b/packages/room/src/object/logic/PetLogic.ts new file mode 100644 index 0000000..2e13a05 --- /dev/null +++ b/packages/room/src/object/logic/PetLogic.ts @@ -0,0 +1,238 @@ +import { IAssetData, IRoomGeometry, IRoomObjectModel, IVector3D, MouseEventType, PetFigureData, PetType, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectMouseEvent, RoomObjectMoveEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { Vector3d } from '@nitrots/utils'; +import { ObjectAvatarChatUpdateMessage, ObjectAvatarExperienceUpdateMessage, ObjectAvatarFigureUpdateMessage, ObjectAvatarPetGestureUpdateMessage, ObjectAvatarPostureUpdateMessage, ObjectAvatarSelectedMessage, ObjectAvatarSleepUpdateMessage, ObjectAvatarUpdateMessage, RoomObjectUpdateMessage } from '../../messages'; +import { MovingObjectLogic } from './MovingObjectLogic'; + +export class PetLogic extends MovingObjectLogic +{ + private _selected: boolean; + private _reportedLocation: IVector3D; + 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; + + if(asset.logic) + { + if(asset.logic.model) + { + const directions = asset.logic.model.directions; + + if(directions && directions.length) + { + for(const direction of directions) this._directions.push(direction); + + this._directions.sort(); + } + } + } + + 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; + } + + if(message instanceof ObjectAvatarExperienceUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_EXPERIENCE_TIMESTAMP, this.time); + model.setValue(RoomObjectVariable.FIGURE_GAINED_EXPERIENCE, message.gainedExperience); + + 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.eventId, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown)); + } + break; + } + } + + if(eventType && this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMouseEvent(eventType, this.object, event.eventId, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown)); + } +} diff --git a/packages/room/src/object/logic/RoomLogic.ts b/packages/room/src/object/logic/RoomLogic.ts new file mode 100644 index 0000000..22c6835 --- /dev/null +++ b/packages/room/src/object/logic/RoomLogic.ts @@ -0,0 +1,453 @@ +import { IRoomGeometry, IRoomObjectModel, MouseEventType, RoomObjectVariable } from '@nitrots/api'; +import { GetConfiguration } from '@nitrots/configuration'; +import { RoomObjectEvent, RoomObjectMouseEvent, RoomObjectTileMouseEvent, RoomObjectWallMouseEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { ColorConverter, Vector3d } from '@nitrots/utils'; +import { Point } from 'pixi.js'; +import { ObjectRoomColorUpdateMessage, ObjectRoomFloorHoleUpdateMessage, ObjectRoomMapUpdateMessage, ObjectRoomMaskUpdateMessage, ObjectRoomPlanePropertyUpdateMessage, ObjectRoomPlaneVisibilityUpdateMessage, ObjectRoomUpdateMessage, RoomObjectUpdateMessage } from '../../messages'; +import { RoomMapData } from '../RoomMapData'; +import { RoomPlaneBitmapMaskData } from '../RoomPlaneBitmapMaskData'; +import { RoomPlaneBitmapMaskParser } from '../RoomPlaneBitmapMaskParser'; +import { RoomPlaneData } from '../RoomPlaneData'; +import { RoomPlaneParser } from '../RoomPlaneParser'; +import { RoomObjectLogicBase } from './RoomObjectLogicBase'; + +export class RoomLogic extends RoomObjectLogicBase +{ + private _planeParser: RoomPlaneParser; + private _planeBitmapMaskParser: RoomPlaneBitmapMaskParser; + private _color: number; + private _light: number; + private _originalColor: number; + private _originalLight: number; + private _targetColor: number; + private _targetLight: number; + private _colorChangedTime: number; + private _colorTransitionLength: number; + private _lastHoleUpdate: number; + private _needsMapUpdate: boolean; + private _skipColorTransition: boolean; + + constructor() + { + super(); + + this._planeParser = new RoomPlaneParser(); + this._planeBitmapMaskParser = new RoomPlaneBitmapMaskParser(); + this._color = 0xFFFFFF; + this._light = 0xFF; + this._originalColor = 0xFFFFFF; + this._originalLight = 0xFF; + this._targetColor = 0xFFFFFF; + this._targetLight = 0xFF; + this._colorChangedTime = 0; + this._colorTransitionLength = 1500; + this._lastHoleUpdate = 0; + this._needsMapUpdate = false; + this._skipColorTransition = 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); + + this._skipColorTransition = (GetConfiguration().getValue('room.color.skip.transition') === true); + } + + public update(time: number): void + { + super.update(time); + + this.updateBackgroundColor(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 updateBackgroundColor(k: number): void + { + if(!this.object || !this._colorChangedTime) return; + + let color = this._color; + let newColor = this._light; + + if((k - this._colorChangedTime) >= this._colorTransitionLength) + { + color = this._targetColor; + newColor = this._targetLight; + + this._colorChangedTime = 0; + } + else + { + let _local_7 = ((this._originalColor >> 16) & 0xFF); + let _local_8 = ((this._originalColor >> 8) & 0xFF); + let _local_9 = (this._originalColor & 0xFF); + + const _local_10 = ((this._targetColor >> 16) & 0xFF); + const _local_11 = ((this._targetColor >> 8) & 0xFF); + const _local_12 = (this._targetColor & 0xFF); + const _local_13 = ((k - this._colorChangedTime) / this._colorTransitionLength); + + _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._originalLight + ((this._targetLight - this._originalLight) * _local_13)); + + this._color = color; + this._light = newColor; + } + + let _local_5 = ColorConverter.rgbToHSL(color); + + _local_5 = ((_local_5 & 0xFFFF00) + newColor); + color = ColorConverter.hslToRGB(_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.REMOVE_MASK: + update = this._planeBitmapMaskParser.removeMask(message.maskId); + break; + + } + + if(update) _arg_2.setValue(RoomObjectVariable.ROOM_PLANE_MASK_XML, this._planeBitmapMaskParser.getXML()); + } + + 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._originalColor = this._color; + this._originalLight = this._light; + this._targetColor = message.color; + this._targetLight = message.light; + this._colorChangedTime = this.time; + + if(this._skipColorTransition) + this._colorTransitionLength = 0; + else + this._colorTransitionLength = 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 planePosition: Point = null; + + const planeLocation = this._planeParser.getPlaneLocation(planeId); + const planeLeftSide = this._planeParser.getPlaneLeftSide(planeId); + const planeRightSide = this._planeParser.getPlaneRightSide(planeId); + const planeNormalDirection = this._planeParser.getPlaneNormalDirection(planeId); + const planeType = this._planeParser.getPlaneType(planeId); + + if(((((planeLocation == null) || (planeLeftSide == null)) || (planeRightSide == null)) || (planeNormalDirection == null))) return; + + const leftSideLength = planeLeftSide.length; + const rightSideLength = planeRightSide.length; + + if(((leftSideLength == 0) || (rightSideLength == 0))) return; + + const screenX = event.screenX; + const screenY = event.screenY; + const screenPoint = new Point(screenX, screenY); + + planePosition = geometry.getPlanePosition(screenPoint, planeLocation, planeLeftSide, planeRightSide); + + if(!planePosition) + { + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_PLANE, 0); + + return; + } + + const _local_18 = Vector3d.product(planeLeftSide, (planePosition.x / leftSideLength)); + + _local_18.add(Vector3d.product(planeRightSide, (planePosition.y / rightSideLength))); + _local_18.add(planeLocation); + + const tileX = _local_18.x; + const tileY = _local_18.y; + const tileZ = _local_18.z; + + if(((((planePosition.x >= 0) && (planePosition.x < leftSideLength)) && (planePosition.y >= 0)) && (planePosition.y < rightSideLength))) + { + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_X, tileX); + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_Y, tileY); + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_Z, tileZ); + 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(planeType === RoomPlaneData.PLANE_FLOOR) + { + newEvent = new RoomObjectTileMouseEvent(eventType, this.object, event.eventId, tileX, tileY, tileZ, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown); + } + + else if((planeType === RoomPlaneData.PLANE_WALL) || (planeType === RoomPlaneData.PLANE_LANDSCAPE)) + { + let direction = 90; + + if(planeNormalDirection) + { + direction = (planeNormalDirection.x + 90); + + if(direction > 360) direction -= 360; + } + + const _local_27 = ((planeLeftSide.length * planePosition.x) / leftSideLength); + const _local_28 = ((planeRightSide.length * planePosition.y) / rightSideLength); + + newEvent = new RoomObjectWallMouseEvent(eventType, this.object, event.eventId, planeLocation, planeLeftSide, planeRightSide, _local_27, _local_28, direction, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown); + } + + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(newEvent); + + return; + } + } + } +} diff --git a/packages/room/src/object/logic/RoomObjectLogicBase.ts b/packages/room/src/object/logic/RoomObjectLogicBase.ts new file mode 100644 index 0000000..72e4a90 --- /dev/null +++ b/packages/room/src/object/logic/RoomObjectLogicBase.ts @@ -0,0 +1,120 @@ +import { IEventDispatcher, IRoomGeometry, IRoomObjectController, IRoomObjectEventHandler, IRoomObjectUpdateMessage } from '@nitrots/api'; +import { RoomSpriteMouseEvent } from '@nitrots/events'; + +export class RoomObjectLogicBase implements IRoomObjectEventHandler +{ + private _events: IEventDispatcher = null; + private _object: IRoomObjectController = null; + private _time: number = 0; + + public initialize(data: unknown): void + { + return; + } + + public dispose(): void + { + this._object = null; + } + + public update(time: number): void + { + this._time = time; + + return; + } + + public processUpdateMessage(message: IRoomObjectUpdateMessage): 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; + } +} diff --git a/packages/room/src/object/logic/SelectionArrowLogic.ts b/packages/room/src/object/logic/SelectionArrowLogic.ts new file mode 100644 index 0000000..fb08533 --- /dev/null +++ b/packages/room/src/object/logic/SelectionArrowLogic.ts @@ -0,0 +1,35 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { ObjectVisibilityUpdateMessage, RoomObjectUpdateMessage } from '../../messages'; +import { RoomObjectLogicBase } from './RoomObjectLogicBase'; + +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; + } + } + } +} diff --git a/packages/room/src/object/logic/TileCursorLogic.ts b/packages/room/src/object/logic/TileCursorLogic.ts new file mode 100644 index 0000000..165984d --- /dev/null +++ b/packages/room/src/object/logic/TileCursorLogic.ts @@ -0,0 +1,64 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { ObjectTileCursorUpdateMessage, RoomObjectUpdateMessage } from '../../messages'; +import { RoomObjectLogicBase } from './RoomObjectLogicBase'; + +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.sourceEventId)) 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.sourceEventId; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureAchievementResolutionLogic.ts b/packages/room/src/object/logic/furniture/FurnitureAchievementResolutionLogic.ts new file mode 100644 index 0000000..f541684 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureAchievementResolutionLogic.ts @@ -0,0 +1,71 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectBadgeAssetEvent, RoomObjectEvent, RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { ObjectGroupBadgeUpdateMessage, ObjectSelectedMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureBadgeDisplayLogic } from './FurnitureBadgeDisplayLogic'; + +export class FurnitureAchievementResolutionLogic extends FurnitureBadgeDisplayLogic +{ + public static STATE_RESOLUTION_NOT_STARTED: number = 0; + public static STATE_RESOLUTION_IN_PROGRESS: number = 1; + public static STATE_RESOLUTION_ACHIEVED: number = 2; + public static STATE_RESOLUTION_FAILED: number = 3; + private static ACH_NOT_SET: string = 'ach_0'; + private static BADGE_VISIBLE_IN_STATE: number = 2; + + public getEventTypes(): string[] + { + const types = [RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_OPEN, RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_ENGRAVING, RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_FAILED, RoomObjectBadgeAssetEvent.LOAD_BADGE]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectGroupBadgeUpdateMessage) + { + if(message.assetName !== 'loading_icon') + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_BADGE_VISIBLE_IN_STATE, FurnitureAchievementResolutionLogic.BADGE_VISIBLE_IN_STATE); + } + } + + if(message instanceof ObjectSelectedMessage) + { + if(!this.eventDispatcher || !this.object) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CLOSE_FURNI_CONTEXT_MENU, this.object)); + } + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + let event: RoomObjectEvent = null; + + switch(this.object.getState(0)) + { + case FurnitureAchievementResolutionLogic.STATE_RESOLUTION_NOT_STARTED: + case FurnitureAchievementResolutionLogic.STATE_RESOLUTION_IN_PROGRESS: + event = new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_OPEN, this.object); + break; + case FurnitureAchievementResolutionLogic.STATE_RESOLUTION_ACHIEVED: + event = new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_ENGRAVING, this.object); + break; + case FurnitureAchievementResolutionLogic.STATE_RESOLUTION_FAILED: + event = new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_FAILED, this.object); + break; + } + + if(event) this.eventDispatcher.dispatchEvent(event); + } + + protected updateBadge(badgeId: string): void + { + if(badgeId === FurnitureAchievementResolutionLogic.ACH_NOT_SET) return; + + super.updateBadge(badgeId); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureBadgeDisplayLogic.ts b/packages/room/src/object/logic/furniture/FurnitureBadgeDisplayLogic.ts new file mode 100644 index 0000000..9440268 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureBadgeDisplayLogic.ts @@ -0,0 +1,63 @@ +import { RoomObjectVariable, StringDataType } from '@nitrots/api'; +import { RoomObjectBadgeAssetEvent, RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { GetTickerTime } from '@nitrots/utils'; +import { ObjectDataUpdateMessage, ObjectGroupBadgeUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureBadgeDisplayLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [RoomObjectWidgetRequestEvent.BADGE_DISPLAY_ENGRAVING, 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(GetTickerTime()); + } + + return; + } + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.BADGE_DISPLAY_ENGRAVING, this.object)); + } + + protected updateBadge(badgeId: string): void + { + if(badgeId === '') return; + + if(this.eventDispatcher) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_BADGE_IMAGE_STATUS, -1); + + this.eventDispatcher.dispatchEvent(new RoomObjectBadgeAssetEvent(RoomObjectBadgeAssetEvent.LOAD_BADGE, this.object, badgeId, false)); + } + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureChangeStateWhenStepOnLogic.ts b/packages/room/src/object/logic/furniture/FurnitureChangeStateWhenStepOnLogic.ts new file mode 100644 index 0000000..ae776d6 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureChangeStateWhenStepOnLogic.ts @@ -0,0 +1,53 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { RoomToObjectOwnAvatarMoveEvent } from '@nitrots/events'; +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); + } + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureClothingChangeLogic.ts b/packages/room/src/object/logic/furniture/FurnitureClothingChangeLogic.ts new file mode 100644 index 0000000..6039d53 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureClothingChangeLogic.ts @@ -0,0 +1,47 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureClothingChangeLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [RoomObjectWidgetRequestEvent.CLOTHING_CHANGE]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + const furniData = this.object.model.getValue(RoomObjectVariable.FURNITURE_DATA); + + this.updateClothingData(furniData); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectDataUpdateMessage) message.data && this.updateClothingData(message.data.getLegacyString()); + } + + private updateClothingData(furnitureData: string): void + { + if(!furnitureData || !furnitureData.length) return; + + const [boyClothing, girlClothing] = furnitureData.split(','); + + if(boyClothing && boyClothing.length) this.object.model.setValue(RoomObjectVariable.FURNITURE_CLOTHING_BOY, boyClothing); + if(girlClothing && girlClothing.length) this.object.model.setValue(RoomObjectVariable.FURNITURE_CLOTHING_GIRL, girlClothing); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CLOTHING_CHANGE, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureCounterClockLogic.ts b/packages/room/src/object/logic/furniture/FurnitureCounterClockLogic.ts new file mode 100644 index 0000000..b996377 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureCounterClockLogic.ts @@ -0,0 +1,51 @@ +import { IRoomGeometry, MouseEventType } from '@nitrots/api'; +import { RoomObjectEvent, RoomObjectStateChangedEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +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)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureCrackableLogic.ts b/packages/room/src/object/logic/furniture/FurnitureCrackableLogic.ts new file mode 100644 index 0000000..b6677be --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureCrackableLogic.ts @@ -0,0 +1,18 @@ +import { RoomObjectVariable, RoomWidgetEnumItemExtradataParameter } from '@nitrots/api'; +import { RoomObjectUpdateMessage } from '../../../messages'; +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/packages/room/src/object/logic/furniture/FurnitureCraftingGizmoLogic.ts b/packages/room/src/object/logic/furniture/FurnitureCraftingGizmoLogic.ts new file mode 100644 index 0000000..bc05b93 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureCraftingGizmoLogic.ts @@ -0,0 +1,10 @@ +import { RoomWidgetEnum } from '@nitrots/api'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureCraftingGizmoLogic extends FurnitureLogic +{ + public get widget(): string + { + return RoomWidgetEnum.CRAFTING; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureCreditLogic.ts b/packages/room/src/object/logic/furniture/FurnitureCreditLogic.ts new file mode 100644 index 0000000..8414fe3 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureCreditLogic.ts @@ -0,0 +1,38 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +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.logic) + { + if(asset.logic.credits && (asset.logic.credits !== '') && (asset.logic.credits.length > 0)) creditValue = parseInt(asset.logic.credits); + } + + this.object.model.setValue(RoomObjectVariable.FURNITURE_CREDIT_VALUE, creditValue); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CREDITFURNI, this.object)); + + super.useObject(); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureCuckooClockLogic.ts b/packages/room/src/object/logic/furniture/FurnitureCuckooClockLogic.ts new file mode 100644 index 0000000..45f1f62 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureCuckooClockLogic.ts @@ -0,0 +1,37 @@ +import { RoomObjectPlaySoundIdEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureCuckooClockLogic extends FurnitureMultiStateLogic +{ + private _state: number = 1; + + public getEventTypes(): string[] + { + const types = [RoomObjectPlaySoundIdEvent.PLAY_SOUND_AT_PITCH]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectDataUpdateMessage) + { + if((this._state !== -1) && (message.state !== this._state)) + { + this.dispatchSoundEvent(this.object.location.z); + } + + this._state = message.state; + } + } + + private dispatchSoundEvent(height: number): void + { + const pitch = Math.pow(2, (height - 1.2)); + + this.eventDispatcher.dispatchEvent(new RoomObjectPlaySoundIdEvent(RoomObjectPlaySoundIdEvent.PLAY_SOUND_AT_PITCH, this.object, 'FURNITURE_cuckoo_clock', pitch)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureCustomStackHeightLogic.ts b/packages/room/src/object/logic/furniture/FurnitureCustomStackHeightLogic.ts new file mode 100644 index 0000000..cdf44af --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureCustomStackHeightLogic.ts @@ -0,0 +1,31 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureCustomStackHeightLogic extends FurnitureMultiStateLogic +{ + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.STACK_HEIGHT + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(this.object && this.object.model) this.object.model.setValue(RoomObjectVariable.FURNITURE_ALWAYS_STACKABLE, 1); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.STACK_HEIGHT, this.object)); + + super.useObject(); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureDiceLogic.ts b/packages/room/src/object/logic/furniture/FurnitureDiceLogic.ts new file mode 100644 index 0000000..281238c --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureDiceLogic.ts @@ -0,0 +1,69 @@ +import { IRoomGeometry, MouseEventType } from '@nitrots/api'; +import { RoomObjectEvent, RoomObjectFurnitureActionEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +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); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureEcotronBoxLogic.ts b/packages/room/src/object/logic/furniture/FurnitureEcotronBoxLogic.ts new file mode 100644 index 0000000..6dd5ea1 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureEcotronBoxLogic.ts @@ -0,0 +1,21 @@ +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureEcotronBoxLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.ECOTRONBOX + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ECOTRONBOX, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureEditableInternalLinkLogic.ts b/packages/room/src/object/logic/furniture/FurnitureEditableInternalLinkLogic.ts new file mode 100644 index 0000000..58fb2e2 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureEditableInternalLinkLogic.ts @@ -0,0 +1,82 @@ +import { IAssetData, IRoomGeometry, MouseEventType, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +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.logic) + { + if(asset.logic.action) + { + if(asset.logic.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.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.INERNAL_LINK, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureEditableRoomLinkLogic.ts b/packages/room/src/object/logic/furniture/FurnitureEditableRoomLinkLogic.ts new file mode 100644 index 0000000..1b3c67e --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureEditableRoomLinkLogic.ts @@ -0,0 +1,76 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +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.logic) + { + if(asset.logic.action) + { + if(asset.logic.action.link && (asset.logic.action.link !== '') && (asset.logic.action.link.length > 0)) + { + (this.object && this.object.model && this.object.model.setValue(RoomObjectVariable.FURNITURE_INTERNAL_LINK, asset.logic.action.link)); + } + } + } + } + + public dispose(): void + { + if(this._timer) + { + clearTimeout(this._timer); + + this._timer = null; + } + + super.dispose(); + } + + 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.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ROOM_LINK, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureEffectBoxLogic.ts b/packages/room/src/object/logic/furniture/FurnitureEffectBoxLogic.ts new file mode 100644 index 0000000..512a33e --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureEffectBoxLogic.ts @@ -0,0 +1,27 @@ +import { ContextMenuEnum } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureEffectBoxLogic extends FurnitureLogic +{ + private _timer: any; + + public getEventTypes(): string[] + { + const types = [RoomObjectWidgetRequestEvent.EFFECTBOX_OPEN_DIALOG]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.EFFECTBOX_OPEN_DIALOG, this.object)); + } + + public get contextMenu(): string + { + return ContextMenuEnum.EFFECT_BOX; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureExternalImageLogic.ts b/packages/room/src/object/logic/furniture/FurnitureExternalImageLogic.ts new file mode 100644 index 0000000..b93c557 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureExternalImageLogic.ts @@ -0,0 +1,44 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureExternalImageLogic extends FurnitureMultiStateLogic +{ + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.EXTERNAL_IMAGE + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(!asset) return; + + if(this.object && this.object.model) + { + let maskType = ''; + + if(asset.logic) + { + if(asset.logic.maskType && (asset.logic.maskType !== '') && (asset.logic.maskType.length > 0)) maskType = asset.logic.maskType; + } + + this.object.model.setValue(RoomObjectVariable.FURNITURE_USES_PLANE_MASK, 0); + this.object.model.setValue(RoomObjectVariable.FURNITURE_PLANE_MASK_TYPE, maskType); + } + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.EXTERNAL_IMAGE, this.object)); + + super.useObject(); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureFireworksLogic.ts b/packages/room/src/object/logic/furniture/FurnitureFireworksLogic.ts new file mode 100644 index 0000000..8ca82e3 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureFireworksLogic.ts @@ -0,0 +1,64 @@ +import { IAssetData, IParticleSystem, IRoomGeometry, MouseEventType, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectEvent, RoomObjectStateChangedEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureFireworksLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [RoomObjectStateChangedEvent.STATE_CHANGE]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(asset.logic) + { + if(asset.logic.particleSystems && asset.logic.particleSystems.length) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_FIREWORKS_DATA, asset.logic.particleSystems); + } + } + } + + 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, 0)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureFloorHoleLogic.ts b/packages/room/src/object/logic/furniture/FurnitureFloorHoleLogic.ts new file mode 100644 index 0000000..0df04c2 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureFloorHoleLogic.ts @@ -0,0 +1,109 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectFloorHoleEvent } from '@nitrots/events'; +import { Vector3d } from '@nitrots/utils'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureFloorHoleLogic extends FurnitureMultiStateLogic +{ + private static STATE_HOLE: 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.STATE_HOLE) + { + this.eventDispatcher.dispatchEvent(new RoomObjectFloorHoleEvent(RoomObjectFloorHoleEvent.REMOVE_HOLE, this.object)); + } + + super.dispose(); + } + + public update(time: number): void + { + super.update(time); + + this.handleAutomaticStateUpdate(); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(!this.object) return; + + if(message instanceof ObjectDataUpdateMessage) + { + this.handleStateUpdate(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.STATE_HOLE) + { + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectFloorHoleEvent(RoomObjectFloorHoleEvent.ADD_HOLE, this.object)); + } + } + } + + this._currentLocation.assign(location); + } + + private handleStateUpdate(state: number): void + { + if(state === this._currentState) return; + + if(this.eventDispatcher) + { + if(state === FurnitureFloorHoleLogic.STATE_HOLE) + { + this.eventDispatcher.dispatchEvent(new RoomObjectFloorHoleEvent(RoomObjectFloorHoleEvent.ADD_HOLE, this.object)); + } + + else if(this._currentState === FurnitureFloorHoleLogic.STATE_HOLE) + { + this.eventDispatcher.dispatchEvent(new RoomObjectFloorHoleEvent(RoomObjectFloorHoleEvent.REMOVE_HOLE, this.object)); + } + } + + this._currentState = state; + } + + private handleAutomaticStateUpdate(): 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.handleStateUpdate((stateIndex % 2)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureFriendFurniLogic.ts b/packages/room/src/object/logic/furniture/FurnitureFriendFurniLogic.ts new file mode 100644 index 0000000..2acd5c9 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureFriendFurniLogic.ts @@ -0,0 +1,70 @@ +import { ContextMenuEnum, IAssetData, RoomObjectVariable, StringDataType } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureFriendFurniLogic 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 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 + { + if(message instanceof ObjectDataUpdateMessage) + { + const data = (message.data as StringDataType); + + if(data) + { + this._state = data.state; + } + else + { + this._state = message.state; + } + } + + super.processUpdateMessage(message); + } + + public getEventTypes(): string[] + { + const types = [RoomObjectWidgetRequestEvent.FRIEND_FURNITURE_ENGRAVING]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + if(this._state === FurnitureFriendFurniLogic.STATE_LOCKED) + { + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.FRIEND_FURNITURE_ENGRAVING, this.object)); + } + else + { + super.useObject(); + } + } + + public get engravingDialogType(): number + { + return 0; + } + + public get contextMenu(): string + { + return ((this._state === FurnitureFriendFurniLogic.STATE_UNLOCKED) ? ContextMenuEnum.FRIEND_FURNITURE : ContextMenuEnum.DUMMY); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureGroupForumTerminalLogic.ts b/packages/room/src/object/logic/furniture/FurnitureGroupForumTerminalLogic.ts new file mode 100644 index 0000000..1cd55f4 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureGroupForumTerminalLogic.ts @@ -0,0 +1,31 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureGuildCustomizedLogic } from './FurnitureGuildCustomizedLogic'; + +export class FurnitureGroupForumTerminalLogic extends FurnitureGuildCustomizedLogic +{ + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.INERNAL_LINK + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + protected updateGroupId(id: string): void + { + super.updateGroupId(id); + + this.object.model.setValue(RoomObjectVariable.FURNITURE_INTERNAL_LINK, `groupforum/${id}`); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.INERNAL_LINK, this.object)); + + super.useObject(); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureGuildCustomizedLogic.ts b/packages/room/src/object/logic/furniture/FurnitureGuildCustomizedLogic.ts new file mode 100644 index 0000000..92628df --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureGuildCustomizedLogic.ts @@ -0,0 +1,93 @@ +import { IRoomGeometry, MouseEventType, RoomObjectVariable, StringDataType } from '@nitrots/api'; +import { RoomObjectBadgeAssetEvent, RoomObjectWidgetRequestEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { GetTickerTime } from '@nitrots/utils'; +import { ObjectDataUpdateMessage, ObjectGroupBadgeUpdateMessage, ObjectSelectedMessage, RoomObjectUpdateMessage } from '../../../messages'; +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 getEventTypes(): string[] + { + const types = [ + RoomObjectBadgeAssetEvent.LOAD_BADGE, + RoomObjectWidgetRequestEvent.GUILD_FURNI_CONTEXT_MENU, + RoomObjectWidgetRequestEvent.CLOSE_FURNI_CONTEXT_MENU + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + 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)); + } + } + + else if(message instanceof ObjectGroupBadgeUpdateMessage) + { + if(message.assetName !== 'loading_icon') + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_ASSET_NAME, message.assetName); + + this.update(GetTickerTime()); + } + } + + else if(message instanceof ObjectSelectedMessage) + { + if(!message.selected) + { + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CLOSE_FURNI_CONTEXT_MENU, this.object)); + } + } + } + + protected updateGroupId(id: string): void + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_GUILD_ID, parseInt(id)); + } + + private updateBadge(badge: string): void + { + this.eventDispatcher.dispatchEvent(new RoomObjectBadgeAssetEvent(RoomObjectBadgeAssetEvent.LOAD_BADGE, this.object, badge, true)); + } + + 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)); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.MOUSE_CLICK: + this.openContextMenu(); + } + + super.mouseEvent(event, geometry); + } + + private openContextMenu(): void + { + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.GUILD_FURNI_CONTEXT_MENU, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureHabboWheelLogic.ts b/packages/room/src/object/logic/furniture/FurnitureHabboWheelLogic.ts new file mode 100644 index 0000000..6395481 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureHabboWheelLogic.ts @@ -0,0 +1,19 @@ +import { RoomObjectFurnitureActionEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureHabboWheelLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [RoomObjectFurnitureActionEvent.USE_HABBOWHEEL]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.USE_HABBOWHEEL, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureHighScoreLogic.ts b/packages/room/src/object/logic/furniture/FurnitureHighScoreLogic.ts new file mode 100644 index 0000000..f56f55f --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureHighScoreLogic.ts @@ -0,0 +1,47 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +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; + } + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureHockeyScoreLogic.ts b/packages/room/src/object/logic/furniture/FurnitureHockeyScoreLogic.ts new file mode 100644 index 0000000..ac19ab1 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureHockeyScoreLogic.ts @@ -0,0 +1,59 @@ +import { IRoomGeometry, MouseEventType } from '@nitrots/api'; +import { RoomObjectEvent, RoomObjectStateChangedEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +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)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureHweenLovelockLogic.ts b/packages/room/src/object/logic/furniture/FurnitureHweenLovelockLogic.ts new file mode 100644 index 0000000..c33af14 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureHweenLovelockLogic.ts @@ -0,0 +1,10 @@ +import { FriendFurniEngravingWidgetType } from '@nitrots/api'; +import { FurnitureFriendFurniLogic } from './FurnitureFriendFurniLogic'; + +export class FurnitureHweenLovelockLogic extends FurnitureFriendFurniLogic +{ + public get engravingDialogType(): number + { + return FriendFurniEngravingWidgetType.HABBOWEEN; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureIceStormLogic.ts b/packages/room/src/object/logic/furniture/FurnitureIceStormLogic.ts new file mode 100644 index 0000000..3f81d5c --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureIceStormLogic.ts @@ -0,0 +1,71 @@ +import { LegacyDataType } from '@nitrots/api'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureIceStormLogic extends FurnitureMultiStateLogic +{ + private _nextState: number; + private _nextStateExtra: 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, this._nextStateExtra)); + } + + super.update(totalTimeRunning); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(message instanceof ObjectDataUpdateMessage) + { + this.processUpdate(message); + + return; + } + + 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, message.extra)); + } + else + { + this._nextState = state; + this._nextStateExtra = message.extra; + this._nextStateTimestamp = this.time + time; + } + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureInternalLinkLogic.ts b/packages/room/src/object/logic/furniture/FurnitureInternalLinkLogic.ts new file mode 100644 index 0000000..b1652ae --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureInternalLinkLogic.ts @@ -0,0 +1,78 @@ +import { IAssetData, IRoomGeometry, MouseEventType, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureInternalLinkLogic extends FurnitureLogic +{ + private _showStateOnceRendered: boolean = false; + private _updateCount: number = 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.logic) + { + if(asset.logic.action) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_INTERNAL_LINK, asset.logic.action.link); + + if(asset.logic.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._showStateOnceRendered) + { + this.setAutomaticStateIndex(0); + } + + super.mouseEvent(event, geometry); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.INERNAL_LINK, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureJukeboxLogic.ts b/packages/room/src/object/logic/furniture/FurnitureJukeboxLogic.ts new file mode 100644 index 0000000..61133c1 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureJukeboxLogic.ts @@ -0,0 +1,97 @@ +import { RoomObjectVariable, RoomWidgetEnumItemExtradataParameter } from '@nitrots/api'; +import { RoomObjectFurnitureActionEvent, RoomObjectStateChangedEvent, RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureJukeboxLogic extends FurnitureMultiStateLogic +{ + private _disposeEventsAllowed: boolean = false; + private _isInitialized: boolean = false; + private _currentState: number = -1; + + public getEventTypes(): string[] + { + const types = [ + RoomObjectFurnitureActionEvent.JUKEBOX_START, + RoomObjectFurnitureActionEvent.JUKEBOX_MACHINE_STOP, + RoomObjectFurnitureActionEvent.JUKEBOX_DISPOSE, + RoomObjectFurnitureActionEvent.JUKEBOX_INIT, + RoomObjectWidgetRequestEvent.JUKEBOX_PLAYLIST_EDITOR + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public dispose(): void + { + this.requestDispose(); + + super.dispose(); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) !== 1) return; + + if(!this._isInitialized) this.requestInit(); + + this.object.model.setValue(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM, RoomWidgetEnumItemExtradataParameter.JUKEBOX); + + if(message instanceof ObjectDataUpdateMessage) + { + const state = this.object.getState(0); + + if(state !== this._currentState) + { + this._currentState = state; + + if(state === 1) this.requestPlayList(); + else if(state === 0) this.requestStopPlaying(); + } + } + } + + private requestInit(): void + { + if(!this.object || !this.eventDispatcher) return; + + this._disposeEventsAllowed = true; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.JUKEBOX_INIT, this.object)); + + this._isInitialized = true; + } + + private requestPlayList(): void + { + if(!this.object || !this.eventDispatcher) return; + + this._disposeEventsAllowed = true; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.JUKEBOX_START, this.object)); + } + + private requestStopPlaying(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.JUKEBOX_MACHINE_STOP, this.object)); + } + + private requestDispose(): void + { + if(!this._disposeEventsAllowed || !this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.JUKEBOX_DISPOSE, this.object)); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.JUKEBOX_PLAYLIST_EDITOR, this.object)); + this.eventDispatcher.dispatchEvent(new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, -1)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureLogic.ts b/packages/room/src/object/logic/furniture/FurnitureLogic.ts new file mode 100644 index 0000000..c2d8f46 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureLogic.ts @@ -0,0 +1,424 @@ +import { IAssetData, IRoomGeometry, IRoomObjectController, IRoomObjectModel, IVector3D, MouseEventType, RoomObjectVariable } from '@nitrots/api'; +import { GetConfiguration } from '@nitrots/configuration'; +import { RoomObjectMouseEvent, RoomObjectRoomAdEvent, RoomObjectStateChangedEvent, RoomObjectWidgetRequestEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { Vector3d } from '@nitrots/utils'; +import { ObjectDataUpdateMessage, ObjectHeightUpdateMessage, ObjectItemDataUpdateMessage, ObjectMoveUpdateMessage, ObjectSelectedMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { MovingObjectLogic } from '../MovingObjectLogic'; + +export class FurnitureLogic extends MovingObjectLogic +{ + private static BOUNCING_STEPS: number = -1; + private static BOUNCING_Z: number = -1; + + 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; + + if(FurnitureLogic.BOUNCING_STEPS === -1) + { + FurnitureLogic.BOUNCING_STEPS = GetConfiguration().getValue('furni.rotation.bounce.steps', 8); + } + + if(FurnitureLogic.BOUNCING_Z === -1) + { + FurnitureLogic.BOUNCING_Z = GetConfiguration().getValue('furni.rotation.bounce.height', 0.0625); + } + } + + public getEventTypes(): string[] + { + const types = [ + RoomObjectStateChangedEvent.STATE_CHANGE, + RoomObjectMouseEvent.CLICK, + RoomObjectMouseEvent.MOUSE_DOWN, + RoomObjectMouseEvent.MOUSE_DOWN_LONG, + RoomObjectRoomAdEvent.ROOM_AD_TOOLTIP_SHOW, + RoomObjectRoomAdEvent.ROOM_AD_TOOLTIP_HIDE, + RoomObjectRoomAdEvent.ROOM_AD_FURNI_DOUBLE_CLICK, + RoomObjectRoomAdEvent.ROOM_AD_FURNI_CLICK]; + + 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; + + if(asset.logic) + { + if(asset.logic.model) + { + const dimensions = asset.logic.model.dimensions; + + if(dimensions) + { + 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.logic.model.directions; + + if(directions && directions.length) + { + for(const direction of directions) this._directions.push(direction); + + this._directions.sort((a, b) => (a - b)); + } + } + + if(asset.logic.customVars) + { + const variables = asset.logic.customVars.variables; + + if(variables && variables.length) + { + model.setValue(RoomObjectVariable.FURNITURE_CUSTOM_VARIABLES, variables); + } + } + } + + 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 + { + this._storedRotateMessage = null; + this._directions = null; + + super.dispose(); + } + + 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); + } + + protected handleAdClick(objectId: number, objectType: string, clickUrl: string): void + { + if(!this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectRoomAdEvent(RoomObjectRoomAdEvent.ROOM_AD_FURNI_CLICK, this.object)); + } + + 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(message.extra !== null) 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.eventId, 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) + { + if(adUrl && (adUrl.indexOf('http') === 0)) + { + this.eventDispatcher.dispatchEvent(new RoomObjectRoomAdEvent(RoomObjectRoomAdEvent.ROOM_AD_TOOLTIP_SHOW, this.object)); + } + + const mouseEvent = new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_ENTER, this.object, event.eventId, 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) + { + if(adUrl && (adUrl.indexOf('http') === 0)) + { + this.eventDispatcher.dispatchEvent(new RoomObjectRoomAdEvent(RoomObjectRoomAdEvent.ROOM_AD_TOOLTIP_HIDE, this.object)); + } + + const mouseEvent = new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_LEAVE, this.object, event.eventId, 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.eventId, 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(adUrl && (adUrl.indexOf('http') === 0)) + { + this.eventDispatcher.dispatchEvent(new RoomObjectRoomAdEvent(RoomObjectRoomAdEvent.ROOM_AD_TOOLTIP_HIDE, this.object)); + } + + if(adUrl && adUrl.length) this.handleAdClick(this.object.id, this.object.type, adUrl); + } + return; + case MouseEventType.MOUSE_DOWN: + if(this.eventDispatcher) + { + const mouseEvent = new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_DOWN, this.object, event.eventId, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown); + + this.eventDispatcher.dispatchEvent(mouseEvent); + } + return; + case MouseEventType.MOUSE_DOWN_LONG: + if(this.eventDispatcher) + { + const mouseEvent = new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_DOWN_LONG, this.object, event.eventId, 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 || !this.eventDispatcher) return; + + const clickUrl = this.getAdClickUrl(this.object.model); + + if(clickUrl && clickUrl.length) + { + this.eventDispatcher.dispatchEvent(new RoomObjectRoomAdEvent(RoomObjectRoomAdEvent.ROOM_AD_FURNI_DOUBLE_CLICK, this.object, null, clickUrl)); + } + + 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.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) === 1) + { + if(this.widget) this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CLOSE_WIDGET, this.object)); + + if(this.contextMenu) this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CLOSE_FURNI_CONTEXT_MENU, this.object)); + } + + super.tearDown(); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureLoveLockLogic.ts b/packages/room/src/object/logic/furniture/FurnitureLoveLockLogic.ts new file mode 100644 index 0000000..c91418f --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureLoveLockLogic.ts @@ -0,0 +1,10 @@ +import { FriendFurniEngravingWidgetType } from '@nitrots/api'; +import { FurnitureFriendFurniLogic } from './FurnitureFriendFurniLogic'; + +export class FurnitureLoveLockLogic extends FurnitureFriendFurniLogic +{ + public get engravingDialogType(): number + { + return FriendFurniEngravingWidgetType.LOVE_LOCK; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureMannequinLogic.ts b/packages/room/src/object/logic/furniture/FurnitureMannequinLogic.ts new file mode 100644 index 0000000..e64c9ea --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureMannequinLogic.ts @@ -0,0 +1,50 @@ +import { MapDataType, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +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 useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.MANNEQUIN, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureMonsterplantSeedLogic.ts b/packages/room/src/object/logic/furniture/FurnitureMonsterplantSeedLogic.ts new file mode 100644 index 0000000..bd431fb --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureMonsterplantSeedLogic.ts @@ -0,0 +1,25 @@ +import { ContextMenuEnum } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureMonsterplantSeedLogic extends FurnitureMultiStateLogic +{ + public getEventTypes(): string[] + { + const types = [RoomObjectWidgetRequestEvent.MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG, this.object)); + } + + public get contextMenu(): string + { + return ContextMenuEnum.MONSTERPLANT_SEED; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureMultiHeightLogic.ts b/packages/room/src/object/logic/furniture/FurnitureMultiHeightLogic.ts new file mode 100644 index 0000000..0aae0e0 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureMultiHeightLogic.ts @@ -0,0 +1,12 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +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); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureMultiStateLogic.ts b/packages/room/src/object/logic/furniture/FurnitureMultiStateLogic.ts new file mode 100644 index 0000000..b130baf --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureMultiStateLogic.ts @@ -0,0 +1,30 @@ +import { IRoomGeometry, MouseEventType } from '@nitrots/api'; +import { RoomObjectFurnitureActionEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +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); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureMysteryBoxLogic.ts b/packages/room/src/object/logic/furniture/FurnitureMysteryBoxLogic.ts new file mode 100644 index 0000000..a9e57f8 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureMysteryBoxLogic.ts @@ -0,0 +1,25 @@ +import { ContextMenuEnum } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureMysteryBoxLogic extends FurnitureMultiStateLogic +{ + public getEventTypes(): string[] + { + const types = [RoomObjectWidgetRequestEvent.MYSTERYBOX_OPEN_DIALOG]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.MYSTERYBOX_OPEN_DIALOG, this.object)); + } + + public get contextMenu(): string + { + return ContextMenuEnum.MYSTERY_BOX; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureMysteryTrophyLogic.ts b/packages/room/src/object/logic/furniture/FurnitureMysteryTrophyLogic.ts new file mode 100644 index 0000000..cefb75d --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureMysteryTrophyLogic.ts @@ -0,0 +1,25 @@ +import { ContextMenuEnum } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureMysteryTrophyLogic extends FurnitureMultiStateLogic +{ + public getEventTypes(): string[] + { + const types = [RoomObjectWidgetRequestEvent.MYSTERYTROPHY_OPEN_DIALOG]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.MYSTERYTROPHY_OPEN_DIALOG, this.object)); + } + + public get contextMenu(): string + { + return ContextMenuEnum.MYSTERY_TROPHY; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureOneWayDoorLogic.ts b/packages/room/src/object/logic/furniture/FurnitureOneWayDoorLogic.ts new file mode 100644 index 0000000..a841e10 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureOneWayDoorLogic.ts @@ -0,0 +1,19 @@ +import { RoomObjectFurnitureActionEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureOneWayDoorLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [RoomObjectFurnitureActionEvent.ENTER_ONEWAYDOOR]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.ENTER_ONEWAYDOOR, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurniturePetCustomizationLogic.ts b/packages/room/src/object/logic/furniture/FurniturePetCustomizationLogic.ts new file mode 100644 index 0000000..dbaafd1 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurniturePetCustomizationLogic.ts @@ -0,0 +1,33 @@ +import { RoomObjectVariable, RoomWidgetEnumItemExtradataParameter } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurniturePetCustomizationLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [RoomObjectWidgetRequestEvent.PET_PRODUCT_MENU]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + 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.USABLE_PRODUCT); + } + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.PET_PRODUCT_MENU, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurniturePlaceholderLogic.ts b/packages/room/src/object/logic/furniture/FurniturePlaceholderLogic.ts new file mode 100644 index 0000000..18ec0e7 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurniturePlaceholderLogic.ts @@ -0,0 +1,21 @@ +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurniturePlaceholderLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.PLACEHOLDER + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.PLACEHOLDER, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurniturePlanetSystemLogic.ts b/packages/room/src/object/logic/furniture/FurniturePlanetSystemLogic.ts new file mode 100644 index 0000000..e52d818 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurniturePlanetSystemLogic.ts @@ -0,0 +1,18 @@ +import { IAssetData, IAssetLogicPlanetSystem, RoomObjectVariable } from '@nitrots/api'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurniturePlanetSystemLogic extends FurnitureLogic +{ + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(asset.logic) + { + if(asset.logic.planetSystems) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_PLANETSYSTEM_DATA, asset.logic.planetSystems); + } + } + } +} diff --git a/packages/room/src/object/logic/furniture/FurniturePresentLogic.ts b/packages/room/src/object/logic/furniture/FurniturePresentLogic.ts new file mode 100644 index 0000000..e7244b3 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurniturePresentLogic.ts @@ -0,0 +1,111 @@ +import { IAssetData, IParticleSystem, IRoomGeometry, MapDataType, MouseEventType, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectFurnitureActionEvent, RoomObjectWidgetRequestEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, ObjectModelDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +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); + + if(asset.logic) + { + if(asset.logic.particleSystems && asset.logic.particleSystems.length) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_FIREWORKS_DATA, asset.logic.particleSystems); + } + } + } + + 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; + } + + super.mouseEvent(event, geometry); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.PRESENT, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurniturePurchaseableClothingLogic.ts b/packages/room/src/object/logic/furniture/FurniturePurchaseableClothingLogic.ts new file mode 100644 index 0000000..e606f02 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurniturePurchaseableClothingLogic.ts @@ -0,0 +1,28 @@ +import { ContextMenuEnum } from '@nitrots/api'; +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +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 + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG, this.object)); + } + + public get contextMenu(): string + { + return ContextMenuEnum.PURCHASABLE_CLOTHING; + } +} diff --git a/packages/room/src/object/logic/furniture/FurniturePushableLogic.ts b/packages/room/src/object/logic/furniture/FurniturePushableLogic.ts new file mode 100644 index 0000000..f7317c9 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurniturePushableLogic.ts @@ -0,0 +1,113 @@ +import { LegacyDataType } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { ObjectDataUpdateMessage, ObjectMoveUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { MovingObjectLogic } from '../MovingObjectLogic'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurniturePushableLogic extends FurnitureMultiStateLogic +{ + private static ANIMATION_NOT_MOVING: number = 0; + private static ANIMATION_MOVING: number = 1; + private static MAX_ANIMATION_COUNT: number = 10; + + private _oldLocation: Vector3d; + + constructor() + { + super(); + + this.updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL; + this._oldLocation = new Vector3d(); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(!message) return; + + const isMoveMessage = (message instanceof ObjectMoveUpdateMessage); + + if(this.object && !isMoveMessage && message.location) + { + const location = this.object.getLocation(); + const difference = Vector3d.dif(message.location, location); + + if(difference) + { + if((Math.abs(difference.x) < 2) && (Math.abs(difference.y) < 2)) + { + let prevLocation = location; + + if((Math.abs(difference.x) > 1) || (Math.abs(difference.y) > 1)) + { + prevLocation = Vector3d.sum(location, Vector3d.product(difference, 0.5)); + } + + super.processUpdateMessage(new ObjectMoveUpdateMessage(prevLocation, message.location, message.direction)); + + return; + } + } + } + + if(message.location && !isMoveMessage) super.processUpdateMessage(new ObjectMoveUpdateMessage(message.location, message.location, message.direction)); + + if(message instanceof ObjectDataUpdateMessage) + { + if(message.state > 0) + { + this.updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL / this.getUpdateIntervalValue(message.state); + } + else + { + this.updateInterval = 1; + } + + this.handleDataUpdate(message); + + return; + } + + if(isMoveMessage && message.isSlide) this.updateInterval = MovingObjectLogic.DEFAULT_UPDATE_INTERVAL; + + super.processUpdateMessage(message); + } + + protected getUpdateIntervalValue(value: number) + { + return (value / FurniturePushableLogic.MAX_ANIMATION_COUNT); + } + + protected getAnimationValue(value: number) + { + return (value % FurniturePushableLogic.MAX_ANIMATION_COUNT); + } + + private handleDataUpdate(message: ObjectDataUpdateMessage): void + { + const animation = this.getAnimationValue(message.state); + + if(animation !== message.state) + { + const legacyStuff = new LegacyDataType(); + + legacyStuff.setString(animation.toString()); + + message = new ObjectDataUpdateMessage(animation, legacyStuff, message.extra); + } + + super.processUpdateMessage(message); + } + + public update(time: number): void + { + if(!this.object) return; + + this._oldLocation.assign(this.object.getLocation()); + + super.update(time); + + if(Vector3d.dif(this.object.getLocation(), this._oldLocation).length !== 0) return; + + if(this.object.getState(0) !== FurniturePushableLogic.ANIMATION_NOT_MOVING) this.object.setState(FurniturePushableLogic.ANIMATION_NOT_MOVING, 0); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureRandomStateLogic.ts b/packages/room/src/object/logic/furniture/FurnitureRandomStateLogic.ts new file mode 100644 index 0000000..1303834 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureRandomStateLogic.ts @@ -0,0 +1,21 @@ +import { RoomObjectStateChangedEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureRandomStateLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ + RoomObjectStateChangedEvent.STATE_RANDOM + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_RANDOM, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureRandomTeleportLogic.ts b/packages/room/src/object/logic/furniture/FurnitureRandomTeleportLogic.ts new file mode 100644 index 0000000..6407ac5 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureRandomTeleportLogic.ts @@ -0,0 +1,10 @@ +import { ContextMenuEnum } from '@nitrots/api'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureRandomTeleportLogic extends FurnitureMultiStateLogic +{ + public get contextMenu(): string + { + return ContextMenuEnum.RANDOM_TELEPORT; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureRentableSpaceLogic.ts b/packages/room/src/object/logic/furniture/FurnitureRentableSpaceLogic.ts new file mode 100644 index 0000000..ed64256 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureRentableSpaceLogic.ts @@ -0,0 +1,46 @@ +import { RoomObjectVariable, RoomWidgetEnum } from '@nitrots/api'; +import { RoomObjectDataRequestEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureRentableSpaceLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ + RoomObjectDataRequestEvent.RODRE_CURRENT_USER_ID, + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public update(time: number): void + { + super.update(time); + + if(this.object && this.object.model) + { + if(!this.object.model.getValue(RoomObjectVariable.SESSION_CURRENT_USER_ID)) + { + this.eventDispatcher.dispatchEvent(new RoomObjectDataRequestEvent(RoomObjectDataRequestEvent.RODRE_CURRENT_USER_ID, this.object)); + } + + const renterId = this.object.model.getValue(RoomObjectVariable.FURNITURE_DATA)['renterId']; + const userId = this.object.model.getValue(RoomObjectVariable.SESSION_CURRENT_USER_ID); + + if(renterId) + { + if(parseInt(renterId) === userId) this.object.setState(2, 0); + else this.object.setState(1, 0); + } + else + { + this.object.setState(0, 0); + } + } + } + + public get widget(): string + { + return RoomWidgetEnum.RENTABLESPACE; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureRoomBackgroundColorLogic.ts b/packages/room/src/object/logic/furniture/FurnitureRoomBackgroundColorLogic.ts new file mode 100644 index 0000000..0a419c0 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureRoomBackgroundColorLogic.ts @@ -0,0 +1,105 @@ +import { IRoomGeometry, MouseEventType, NumberDataType, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectHSLColorEnableEvent, RoomObjectWidgetRequestEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +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; + } + + super.mouseEvent(event, geometry); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureRoomBackgroundLogic.ts b/packages/room/src/object/logic/furniture/FurnitureRoomBackgroundLogic.ts new file mode 100644 index 0000000..f20d371 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureRoomBackgroundLogic.ts @@ -0,0 +1,10 @@ +import { IRoomObjectModel } from '@nitrots/api'; +import { FurnitureRoomBrandingLogic } from './FurnitureRoomBrandingLogic'; + +export class FurnitureRoomBackgroundLogic extends FurnitureRoomBrandingLogic +{ + protected getAdClickUrl(model: IRoomObjectModel): string + { + return null; + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureRoomBillboardLogic.ts b/packages/room/src/object/logic/furniture/FurnitureRoomBillboardLogic.ts new file mode 100644 index 0000000..8320293 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureRoomBillboardLogic.ts @@ -0,0 +1,31 @@ +import { IRoomObjectModel, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectRoomAdEvent } from '@nitrots/events'; +import { HabboWebTools } from '@nitrots/utils'; +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); + } + + protected handleAdClick(objectId: number, objectType: string, clickUrl: string): void + { + if(clickUrl.indexOf('http') === 0) + { + HabboWebTools.openWebPage(clickUrl); + + return; + } + + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectRoomAdEvent(RoomObjectRoomAdEvent.ROOM_AD_FURNI_CLICK, this.object, '', clickUrl)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureRoomBrandingLogic.ts b/packages/room/src/object/logic/furniture/FurnitureRoomBrandingLogic.ts new file mode 100644 index 0000000..cf935da --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureRoomBrandingLogic.ts @@ -0,0 +1,162 @@ +import { IAssetData, IRoomGeometry, MapDataType, MouseEventType, RoomObjectVariable, RoomWidgetEnumItemExtradataParameter } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { RoomObjectRoomAdEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { ObjectAdUpdateMessage, ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +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 _disableFurnitureSelection: boolean; + protected _hasClickUrl: boolean; + + constructor() + { + super(); + + this._disableFurnitureSelection = true; + this._hasClickUrl = false; + } + + public getEventTypes(): string[] + { + const types = [RoomObjectRoomAdEvent.ROOM_AD_LOAD_IMAGE]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(this._disableFurnitureSelection) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_SELECTION_DISABLED, 1); + } + } + + 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; + } + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry) return; + + if((event.type === MouseEventType.MOUSE_MOVE) || (event.type === MouseEventType.DOUBLE_CLICK)) return; + + super.mouseEvent(event, geometry); + } + + private async downloadBackground(): Promise + { + 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 = GetAssetManager(); + + if(!asset) return; + + const texture = asset.getTexture(imageUrl); + + if(!texture) + { + const status = await asset.downloadAsset(imageUrl); + + if(!status) + { + this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADING_FAILED)); + + return; + } + } + + this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureRoomDimmerLogic.ts b/packages/room/src/object/logic/furniture/FurnitureRoomDimmerLogic.ts new file mode 100644 index 0000000..24f7355 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureRoomDimmerLogic.ts @@ -0,0 +1,140 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectDimmerStateUpdateEvent, RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +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 + { + if(!this.object || !this.eventDispatcher) return; + + 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); + // } + // } + // } + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureScoreLogic.ts b/packages/room/src/object/logic/furniture/FurnitureScoreLogic.ts new file mode 100644 index 0000000..28fd078 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureScoreLogic.ts @@ -0,0 +1,70 @@ +import { GetTickerTime } from '@nitrots/utils'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureScoreLogic extends FurnitureLogic +{ + private static UPDATE_INTERVAL: number = 50; + private static MAX_UPDATE_TIME: 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.UPDATE_INTERVAL) > FurnitureScoreLogic.MAX_UPDATE_TIME) this._scoreIncreaser = (FurnitureScoreLogic.MAX_UPDATE_TIME / difference); + else this._scoreIncreaser = FurnitureScoreLogic.UPDATE_INTERVAL; + + this._scoreTimer = GetTickerTime(); + } + } + + 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/packages/room/src/object/logic/furniture/FurnitureSongDiskLogic.ts b/packages/room/src/object/logic/furniture/FurnitureSongDiskLogic.ts new file mode 100644 index 0000000..13497ef --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureSongDiskLogic.ts @@ -0,0 +1,19 @@ +import { RoomObjectVariable, RoomWidgetEnumItemExtradataParameter } from '@nitrots/api'; +import { RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureSongDiskLogic extends FurnitureLogic +{ + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) === 1) + { + const extras = this.object.model.getValue(RoomObjectVariable.FURNITURE_EXTRAS); + const diskId = parseInt(extras); + + this.object.model.setValue(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM, (RoomWidgetEnumItemExtradataParameter.SONGDISK + diskId)); + } + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureSoundBlockLogic.ts b/packages/room/src/object/logic/furniture/FurnitureSoundBlockLogic.ts new file mode 100644 index 0000000..9e38c28 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureSoundBlockLogic.ts @@ -0,0 +1,119 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectSamplePlaybackEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +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 = -1; + private _sampleId: number = -1; + private _noPitch: boolean = false; + private _lastLocZ: number = 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.logic) + { + if(asset.logic.soundSample) + { + this._sampleId = asset.logic.soundSample.id; + this._noPitch = asset.logic.soundSample.noPitch; + } + } + + this.object.model.setValue(RoomObjectVariable.FURNITURE_SOUNDBLOCK_RELATIVE_ANIMATION_SPEED, 1); + } + + public dispose(): void + { + if(this._state !== FurnitureSoundBlockLogic.STATE_UNINITIALIZED) + { + this.eventDispatcher.dispatchEvent(new RoomObjectSamplePlaybackEvent(RoomObjectSamplePlaybackEvent.ROOM_OBJECT_DISPOSED, this.object, this._sampleId)); + } + + super.dispose(); + } + + 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.getPitchForHeight(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.getPitchForHeight(location.z))); + } + + } + + if(this._state !== FurnitureSoundBlockLogic.STATE_UNINITIALIZED && message.state !== this._state) + { + this.playSoundAt(location.z); + } + + this._state = message.state; + } + + private playSoundAt(height: number): void + { + if(!this.object) return; + + const pitch: number = this.getPitchForHeight(height); + + this.object.model.setValue(RoomObjectVariable.FURNITURE_SOUNDBLOCK_RELATIVE_ANIMATION_SPEED, pitch); + + this.eventDispatcher.dispatchEvent(new RoomObjectSamplePlaybackEvent(RoomObjectSamplePlaybackEvent.PLAY_SAMPLE, this.object, this._sampleId, pitch)); + } + + private getPitchForHeight(height: number): number + { + if(this._noPitch) return 1; + + let heightScaled: number = (height * 2); + + if(heightScaled > FurnitureSoundBlockLogic.HIGHEST_SEMITONE) + { + heightScaled = Math.min(0, (FurnitureSoundBlockLogic.LOWEST_SEMITONE + ((heightScaled - FurnitureSoundBlockLogic.HIGHEST_SEMITONE) - 1))); + } + + return Math.pow(2, (heightScaled / 12)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureSoundMachineLogic.ts b/packages/room/src/object/logic/furniture/FurnitureSoundMachineLogic.ts new file mode 100644 index 0000000..630c621 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureSoundMachineLogic.ts @@ -0,0 +1,88 @@ +import { RoomObjectVariable, RoomWidgetEnumItemExtradataParameter } from '@nitrots/api'; +import { RoomObjectFurnitureActionEvent } from '@nitrots/events'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureSoundMachineLogic extends FurnitureMultiStateLogic +{ + private _disposeEventsAllowed: boolean = false; + private _isInitialized: boolean = false; + private _currentState: number = -1; + + public getEventTypes(): string[] + { + const types = [ + RoomObjectFurnitureActionEvent.SOUND_MACHINE_START, + RoomObjectFurnitureActionEvent.SOUND_MACHINE_STOP, + RoomObjectFurnitureActionEvent.SOUND_MACHINE_DISPOSE, + RoomObjectFurnitureActionEvent.SOUND_MACHINE_INIT + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public dispose(): void + { + this.requestDispose(); + + super.dispose(); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) !== 1) return; + + if(!this._isInitialized) this.requestInit(); + + this.object.model.setValue(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM, RoomWidgetEnumItemExtradataParameter.JUKEBOX); + + if(message instanceof ObjectDataUpdateMessage) + { + const state = this.object.getState(0); + + if(state !== this._currentState) + { + this._currentState = state; + + if(state === 1) this.requestPlayList(); + else if(state === 0) this.requestStopPlaying(); + } + } + } + + private requestInit(): void + { + if(!this.object || !this.eventDispatcher) return; + + this._disposeEventsAllowed = true; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.SOUND_MACHINE_INIT, this.object)); + + this._isInitialized = true; + } + + private requestPlayList(): void + { + if(!this.object || !this.eventDispatcher) return; + + this._disposeEventsAllowed = true; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.SOUND_MACHINE_START, this.object)); + } + + private requestStopPlaying(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.SOUND_MACHINE_STOP, this.object)); + } + + private requestDispose(): void + { + if(!this._disposeEventsAllowed || !this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.SOUND_MACHINE_DISPOSE, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureStickieLogic.ts b/packages/room/src/object/logic/furniture/FurnitureStickieLogic.ts new file mode 100644 index 0000000..041149d --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureStickieLogic.ts @@ -0,0 +1,60 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectFurnitureActionEvent, RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { ObjectItemDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +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 useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.STICKIE, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureTrophyLogic.ts b/packages/room/src/object/logic/furniture/FurnitureTrophyLogic.ts new file mode 100644 index 0000000..48ff5ad --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureTrophyLogic.ts @@ -0,0 +1,19 @@ +import { RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureTrophyLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [RoomObjectWidgetRequestEvent.TROPHY]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.TROPHY, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureVoteCounterLogic.ts b/packages/room/src/object/logic/furniture/FurnitureVoteCounterLogic.ts new file mode 100644 index 0000000..5a5a7b8 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureVoteCounterLogic.ts @@ -0,0 +1,95 @@ +import { RoomObjectVariable, VoteDataType } from '@nitrots/api'; +import { GetTickerTime } from '@nitrots/utils'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureVoteCounterLogic extends FurnitureMultiStateLogic +{ + private static UPDATE_INTERVAL: number = 33; + private static MAX_UPDATE_TIME: 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.updateTotal(stuffData.result); + } + } + + private updateTotal(k: number): void + { + this._total = k; + + if(!this._lastUpdate) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_VOTE_COUNTER_COUNT, k); + + this._lastUpdate = GetTickerTime(); + + return; + } + + if(this._total !== this.currentTotal) + { + const difference = Math.abs((this._total - this.currentTotal)); + + if((difference * FurnitureVoteCounterLogic.UPDATE_INTERVAL) > FurnitureVoteCounterLogic.MAX_UPDATE_TIME) + { + this._interval = (FurnitureVoteCounterLogic.MAX_UPDATE_TIME / difference); + } + else + { + this._interval = FurnitureVoteCounterLogic.UPDATE_INTERVAL; + } + + this._lastUpdate = GetTickerTime(); + } + } + + public update(time: number): void + { + super.update(time); + + if(this.object) + { + if((this.currentTotal !== 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.currentTotal) _local_4 = -1; + + if(_local_3 > (_local_4 * (this._total - this.currentTotal))) _local_3 = (_local_4 * (this._total - this.currentTotal)); + + this.object.model.setValue(RoomObjectVariable.FURNITURE_VOTE_COUNTER_COUNT, (this.currentTotal + (_local_4 * _local_3))); + + this._lastUpdate = (time - (_local_2 - (_local_3 * this._interval))); + } + } + } + + private get currentTotal(): number + { + return this.object.model.getValue(RoomObjectVariable.FURNITURE_VOTE_COUNTER_COUNT); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureVoteMajorityLogic.ts b/packages/room/src/object/logic/furniture/FurnitureVoteMajorityLogic.ts new file mode 100644 index 0000000..0e61372 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureVoteMajorityLogic.ts @@ -0,0 +1,20 @@ +import { RoomObjectVariable, VoteDataType } from '@nitrots/api'; +import { ObjectDataUpdateMessage, RoomObjectUpdateMessage } from '../../../messages'; +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); + } + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureWelcomeGiftLogic.ts b/packages/room/src/object/logic/furniture/FurnitureWelcomeGiftLogic.ts new file mode 100644 index 0000000..98093a2 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureWelcomeGiftLogic.ts @@ -0,0 +1,18 @@ +import { IRoomGeometry, MouseEventType } from '@nitrots/api'; +import { RoomObjectStateChangedEvent, RoomSpriteMouseEvent } from '@nitrots/events'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureWelcomeGiftLogic extends FurnitureMultiStateLogic +{ + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry) return; + + if(event.type === MouseEventType.DOUBLE_CLICK) + { + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object)); + } + + super.mouseEvent(event, geometry); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureWindowLogic.ts b/packages/room/src/object/logic/furniture/FurnitureWindowLogic.ts new file mode 100644 index 0000000..1260007 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureWindowLogic.ts @@ -0,0 +1,20 @@ +import { IAssetData, RoomObjectVariable } from '@nitrots/api'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureWindowLogic extends FurnitureMultiStateLogic +{ + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + let maskType = ''; + + if(asset.logic) + { + if(asset.logic.maskType && (asset.logic.maskType !== '') && (asset.logic.maskType.length > 0)) maskType = asset.logic.maskType; + } + + this.object.model.setValue(RoomObjectVariable.FURNITURE_USES_PLANE_MASK, 1); + this.object.model.setValue(RoomObjectVariable.FURNITURE_PLANE_MASK_TYPE, maskType); + } +} diff --git a/packages/room/src/object/logic/furniture/FurnitureYoutubeLogic.ts b/packages/room/src/object/logic/furniture/FurnitureYoutubeLogic.ts new file mode 100644 index 0000000..0814e74 --- /dev/null +++ b/packages/room/src/object/logic/furniture/FurnitureYoutubeLogic.ts @@ -0,0 +1,33 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { RoomObjectDataRequestEvent, RoomObjectWidgetRequestEvent } from '@nitrots/events'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureYoutubeLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.YOUTUBE, + 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 useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.YOUTUBE, this.object)); + } +} diff --git a/packages/room/src/object/logic/furniture/index.ts b/packages/room/src/object/logic/furniture/index.ts new file mode 100644 index 0000000..d548e94 --- /dev/null +++ b/packages/room/src/object/logic/furniture/index.ts @@ -0,0 +1,62 @@ +export * from './FurnitureAchievementResolutionLogic'; +export * from './FurnitureBadgeDisplayLogic'; +export * from './FurnitureChangeStateWhenStepOnLogic'; +export * from './FurnitureClothingChangeLogic'; +export * from './FurnitureCounterClockLogic'; +export * from './FurnitureCrackableLogic'; +export * from './FurnitureCraftingGizmoLogic'; +export * from './FurnitureCreditLogic'; +export * from './FurnitureCuckooClockLogic'; +export * from './FurnitureCustomStackHeightLogic'; +export * from './FurnitureDiceLogic'; +export * from './FurnitureEcotronBoxLogic'; +export * from './FurnitureEditableInternalLinkLogic'; +export * from './FurnitureEditableRoomLinkLogic'; +export * from './FurnitureEffectBoxLogic'; +export * from './FurnitureExternalImageLogic'; +export * from './FurnitureFireworksLogic'; +export * from './FurnitureFloorHoleLogic'; +export * from './FurnitureFriendFurniLogic'; +export * from './FurnitureGroupForumTerminalLogic'; +export * from './FurnitureGuildCustomizedLogic'; +export * from './FurnitureHabboWheelLogic'; +export * from './FurnitureHighScoreLogic'; +export * from './FurnitureHockeyScoreLogic'; +export * from './FurnitureHweenLovelockLogic'; +export * from './FurnitureIceStormLogic'; +export * from './FurnitureInternalLinkLogic'; +export * from './FurnitureJukeboxLogic'; +export * from './FurnitureLogic'; +export * from './FurnitureLoveLockLogic'; +export * from './FurnitureMannequinLogic'; +export * from './FurnitureMonsterplantSeedLogic'; +export * from './FurnitureMultiHeightLogic'; +export * from './FurnitureMultiStateLogic'; +export * from './FurnitureMysteryBoxLogic'; +export * from './FurnitureMysteryTrophyLogic'; +export * from './FurnitureOneWayDoorLogic'; +export * from './FurniturePetCustomizationLogic'; +export * from './FurniturePlaceholderLogic'; +export * from './FurniturePlanetSystemLogic'; +export * from './FurniturePresentLogic'; +export * from './FurniturePurchaseableClothingLogic'; +export * from './FurniturePushableLogic'; +export * from './FurnitureRandomStateLogic'; +export * from './FurnitureRandomTeleportLogic'; +export * from './FurnitureRentableSpaceLogic'; +export * from './FurnitureRoomBackgroundColorLogic'; +export * from './FurnitureRoomBackgroundLogic'; +export * from './FurnitureRoomBillboardLogic'; +export * from './FurnitureRoomBrandingLogic'; +export * from './FurnitureRoomDimmerLogic'; +export * from './FurnitureScoreLogic'; +export * from './FurnitureSongDiskLogic'; +export * from './FurnitureSoundBlockLogic'; +export * from './FurnitureSoundMachineLogic'; +export * from './FurnitureStickieLogic'; +export * from './FurnitureTrophyLogic'; +export * from './FurnitureVoteCounterLogic'; +export * from './FurnitureVoteMajorityLogic'; +export * from './FurnitureWelcomeGiftLogic'; +export * from './FurnitureWindowLogic'; +export * from './FurnitureYoutubeLogic'; diff --git a/packages/room/src/object/logic/index.ts b/packages/room/src/object/logic/index.ts new file mode 100644 index 0000000..3b6c256 --- /dev/null +++ b/packages/room/src/object/logic/index.ts @@ -0,0 +1,8 @@ +export * from './AvatarLogic'; +export * from './MovingObjectLogic'; +export * from './PetLogic'; +export * from './RoomLogic'; +export * from './RoomObjectLogicBase'; +export * from './SelectionArrowLogic'; +export * from './TileCursorLogic'; +export * from './furniture'; diff --git a/packages/room/src/object/visualization/RoomObjectSprite.ts b/packages/room/src/object/visualization/RoomObjectSprite.ts new file mode 100644 index 0000000..51b8796 --- /dev/null +++ b/packages/room/src/object/visualization/RoomObjectSprite.ts @@ -0,0 +1,355 @@ +import { AlphaTolerance, IRoomObjectSprite, RoomObjectSpriteType } from '@nitrots/api'; +import { BLEND_MODES, Filter, Texture } from 'pixi.js'; + +export class RoomObjectSprite implements IRoomObjectSprite +{ + private static SPRITE_COUNTER: number = 0; + + private _id: number = RoomObjectSprite.SPRITE_COUNTER++; + private _name: string = ''; + private _type: string = ''; + private _spriteType: number = RoomObjectSpriteType.DEFAULT; + private _texture: Texture = null; + + private _width: number = 0; + private _height: number = 0; + private _offsetX: number = 0; + private _offsetY: number = 0; + private _flipH: boolean = false; + private _flipV: boolean = false; + private _direction: number = 0; + + private _alpha: number = 255; + private _blendMode: BLEND_MODES = 'normal'; + private _color: number = 0xFFFFFF; + private _relativeDepth: number = 0; + private _varyingDepth: boolean = false; + private _libraryAssetName: string = ''; + private _clickHandling: boolean = false; + private _visible: boolean = true; + private _tag: string = ''; + private _posture: string = null; + private _alphaTolerance: number = AlphaTolerance.MATCH_OPAQUE_PIXELS; + private _filters: Filter[] = []; + + private _updateCounter: number = 0; + + public dispose(): void + { + this._texture = null; + this._width = 0; + this._height = 0; + } + + public increaseUpdateCounter(): void + { + this._updateCounter++; + } + + 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 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(): BLEND_MODES + { + return this._blendMode; + } + + public set blendMode(blend: BLEND_MODES) + { + 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 varyingDepth(): boolean + { + return this._varyingDepth; + } + + public set varyingDepth(flag: boolean) + { + if(flag === this._varyingDepth) return; + + this._varyingDepth = flag; + + this._updateCounter++; + } + + public get libraryAssetName(): string + { + return this._libraryAssetName; + } + + public set libraryAssetName(value: string) + { + this._libraryAssetName = 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; + } +} diff --git a/packages/room/src/object/visualization/RoomObjectSpriteVisualization.ts b/packages/room/src/object/visualization/RoomObjectSpriteVisualization.ts new file mode 100644 index 0000000..4a6315b --- /dev/null +++ b/packages/room/src/object/visualization/RoomObjectSpriteVisualization.ts @@ -0,0 +1,286 @@ +import { IGraphicAssetCollection, IObjectVisualizationData, IRoomGeometry, IRoomObjectController, IRoomObjectSprite, IRoomObjectSpriteVisualization, RoomObjectSpriteData } from '@nitrots/api'; +import { TextureUtils } from '@nitrots/utils'; +import { Container, Point, Rectangle, Sprite, Texture } from 'pixi.js'; +import { RoomObjectSprite } from './RoomObjectSprite'; + +export class RoomObjectSpriteVisualization implements IRoomObjectSpriteVisualization +{ + private static VISUALIZATION_COUNTER: number = 0; + + private _id: number = RoomObjectSpriteVisualization.VISUALIZATION_COUNTER++; + private _object: IRoomObjectController = null; + private _asset: IGraphicAssetCollection = null; + private _sprites: IRoomObjectSprite[] = []; + + protected _scale: number = -1; + + private _updateObjectCounter: number = -1; + private _updateModelCounter: number = -1; + private _updateSpriteCounter: number = -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.shift(); + } + + 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 createSprites(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(): Texture + { + return this.getImage(); + } + + public getImage(): Texture + { + 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 = new Sprite(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++; + } + + return TextureUtils.generateTexture({ + target: container + }); + } + + 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/packages/room/src/object/visualization/avatar/AvatarVisualization.ts b/packages/room/src/object/visualization/avatar/AvatarVisualization.ts new file mode 100644 index 0000000..ff09f41 --- /dev/null +++ b/packages/room/src/object/visualization/avatar/AvatarVisualization.ts @@ -0,0 +1,1130 @@ +import { AlphaTolerance, AvatarAction, AvatarGuideStatus, AvatarSetType, IAdvancedMap, IAvatarEffectListener, IAvatarImage, IAvatarImageListener, IGraphicAsset, IObjectVisualizationData, IRoomGeometry, IRoomObject, IRoomObjectModel, RoomObjectSpriteType, RoomObjectVariable } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { AdvancedMap } from '@nitrots/utils'; +import { Texture } from 'pixi.js'; +import { RoomObjectSpriteVisualization } from '../RoomObjectSpriteVisualization'; +import { AvatarVisualizationData } from './AvatarVisualizationData'; +import { ExpressionAdditionFactory, FloatingIdleZAddition, GameClickTargetAddition, GuideStatusBubbleAddition, IAvatarAddition, MutedBubbleAddition, NumberBubbleAddition, TypingBubbleAddition } from './additions'; + +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 GAME_CLICK_TARGET_ID: number = 5; + private static MUTED_BUBBLE_ID: number = 6; + private static GUIDE_BUBBLE_ID: number = 7; + private static OWN_USER_ID: number = 4; + private static UPDATE_TIME_INCREASER: number = 41; + private static AVATAR_LAYER_ID: number = 0; + private static SHADOW_LAYER_ID: number = 1; + private static SNOWBOARDING_EFFECT: number = 97; + private static INITIAL_RESERVED_SPRITES: number = 2; + private static ANIMATION_FRAME_UPDATE_INTERVAL: number = 2; + private static DEFAULT_CANVAS_OFFSETS: number[] = [0, 0, 0]; + private static MAX_EFFECT_CACHE: number = 2; + private static SPRITE_INDEX_AVATAR: number = 0; + private static BASE_Y_SCALE: number = 1000; + private static AVATAR_SPRITE_DEFAULT_DEPTH: number = -0.01; + private static AVATAR_OWN_DEPTH_ADJUST: number = 0.001; + private static AVATAR_SPRITE_LAYING_DEPTH: number = -0.409; + + protected _data: AvatarVisualizationData; + + private _avatarImage: IAvatarImage; + private _cachedAvatars: IAdvancedMap; + private _cachedAvatarEffects: IAdvancedMap; + 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 _isLaying: boolean; + private _layInside: boolean; + private _isAnimating: boolean; + private _extraSpritesStartIndex: number; + private _forcedAnimFrames: number; + private _updatesUntilFrameUpdate: 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._isLaying = false; + this._layInside = false; + this._isAnimating = false; + this._extraSpritesStartIndex = 2; + this._forcedAnimFrames = 0; + this._updatesUntilFrameUpdate = 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.createSprites(AvatarVisualization.INITIAL_RESERVED_SPRITES); + + 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._extraSpritesStartIndex; + + 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._extraSpritesStartIndex; + + for(const addition of this._additions.values()) + { + if(addition.animate(this.getSprite(index++))) this.updateSpriteCounter++; + } + } + + const update1 = (objectUpdate || updateModel || didScaleUpdate); + const update2 = ((this._isAnimating || (this._forcedAnimFrames > 0)) && update); + + if(update1) this._forcedAnimFrames = AvatarVisualization.ANIMATION_FRAME_UPDATE_INTERVAL; + + if(update1 || update2) + { + this.updateSpriteCounter++; + + this._forcedAnimFrames--; + this._updatesUntilFrameUpdate--; + + if((((this._updatesUntilFrameUpdate <= 0) || didScaleUpdate) || updateModel) || otherUpdate) + { + this._avatarImage.updateAnimationByFrames(1); + + this._updatesUntilFrameUpdate = AvatarVisualization.ANIMATION_FRAME_UPDATE_INTERVAL; + } + else + { + return; + } + + let _local_20 = this._avatarImage.getCanvasOffsets(); + + if(!_local_20 || (_local_20.length < 3)) _local_20 = AvatarVisualization.DEFAULT_CANVAS_OFFSETS; + + const sprite = this.getSprite(AvatarVisualization.SPRITE_INDEX_AVATAR); + + 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.processAsTexture(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._isLaying) + { + if(this._layInside) sprite.relativeDepth = -0.5; + else sprite.relativeDepth = (AvatarVisualization.AVATAR_SPRITE_LAYING_DEPTH + _local_20[2]); + } + else + { + sprite.relativeDepth = (AvatarVisualization.AVATAR_SPRITE_DEFAULT_DEPTH + _local_20[2]); + } + + if(this._ownUser) + { + sprite.relativeDepth -= AvatarVisualization.AVATAR_OWN_DEPTH_ADJUST; + sprite.spriteType = RoomObjectSpriteType.AVATAR_OWN; + } + else + { + sprite.spriteType = RoomObjectSpriteType.AVATAR; + } + } + + const typingBubble = this.getAddition(AvatarVisualization.TYPING_BUBBLE_ID) as TypingBubbleAddition; + + if(typingBubble) + { + if(!this._isLaying) typingBubble.relativeDepth = ((AvatarVisualization.AVATAR_SPRITE_DEFAULT_DEPTH - 0.01) + _local_20[2]); + else typingBubble.relativeDepth = ((AvatarVisualization.AVATAR_SPRITE_LAYING_DEPTH - 0.01) + _local_20[2]); + } + + this._isAnimating = this._avatarImage.isAnimating(); + + let _local_21 = AvatarVisualization.INITIAL_RESERVED_SPRITES; + const direction = this._avatarImage.getDirection(); + + for(const spriteData of this._avatarImage.getSprites()) + { + if(spriteData.id === AvatarVisualization.AVATAR) + { + const sprite = this.getSprite(AvatarVisualization.SPRITE_INDEX_AVATAR); + + if(sprite) + { + const layerData = this._avatarImage.getLayerData(spriteData); + + let offsetX = spriteData.getDirectionOffsetX(direction); + let offsetY = spriteData.getDirectionOffsetY(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.MATCH_NOTHING; + sprite.visible = true; + + const layerData = this._avatarImage.getLayerData(spriteData); + + let frameNumber = 0; + let offsetX = spriteData.getDirectionOffsetX(direction); + let offsetY = spriteData.getDirectionOffsetY(direction); + const offsetZ = spriteData.getDirectionOffsetZ(direction); + let dd = 0; + + if(spriteData.hasDirections) dd = direction; + + if(layerData) + { + frameNumber = layerData.animationFrame; + 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 = GetAssetManager().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.hasStaticY) + { + sprite.offsetY += ((this._verticalOffset * scale) / (2 * AvatarVisualization.BASE_Y_SCALE)); + } + else + { + sprite.offsetY += this._postureOffset; + } + + if(this._isLaying) + { + sprite.relativeDepth = (AvatarVisualization.AVATAR_SPRITE_LAYING_DEPTH - ((0.001 * this.totalSprites) * offsetZ)); + } + else + { + sprite.relativeDepth = (AvatarVisualization.AVATAR_SPRITE_DEFAULT_DEPTH - ((0.001 * this.totalSprites) * offsetZ)); + } + + if(spriteData.ink === 33) sprite.blendMode = 'add'; + else sprite.blendMode = '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.BASE_Y_SCALE); + + 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); + + needsUpdate = true; + } + } + } + + const guideStatusValue = (model.getValue(RoomObjectVariable.FIGURE_GUIDE_STATUS) || 0); + + if(guideStatusValue !== AvatarGuideStatus.NONE) + { + this.removeAddition(AvatarVisualization.GUIDE_BUBBLE_ID); + this.addAddition(new GuideStatusBubbleAddition(AvatarVisualization.GUIDE_BUBBLE_ID, this, guideStatusValue)); + + needsUpdate = true; + } + else + { + if(this.getAddition(AvatarVisualization.GUIDE_BUBBLE_ID)) + { + this.removeAddition(AvatarVisualization.GUIDE_BUBBLE_ID); + + needsUpdate = true; + } + } + + const isPlayingGame = (model.getValue(RoomObjectVariable.FIGURE_IS_PLAYING_GAME) > 0); + + let gameClickAddition = this.getAddition(AvatarVisualization.GAME_CLICK_TARGET_ID); + + if(isPlayingGame) + { + if(!gameClickAddition) gameClickAddition = this.addAddition(new GameClickTargetAddition(AvatarVisualization.GAME_CLICK_TARGET_ID)); + + needsUpdate = true; + } + else + { + if(gameClickAddition) this.removeAddition(AvatarVisualization.GAME_CLICK_TARGET_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._layInside = false; + this._isLaying = false; + + if(this._posture === 'lay') + { + this._isLaying = true; + + const _local_2 = parseInt(this._postureParameter); + + if(_local_2 < 0) this._layInside = 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._isAnimating = avatar.isAnimating(); + + let spriteCount = AvatarVisualization.INITIAL_RESERVED_SPRITES; + + for(const sprite of this._avatarImage.getSprites()) + { + if(sprite.id !== AvatarVisualization.AVATAR) spriteCount++; + } + + if(spriteCount !== this.totalSprites) this.createSprites(spriteCount); + + this._extraSpritesStartIndex = 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 + { + const sprite = this.getSprite(AvatarVisualization.AVATAR_LAYER_ID); + + if(sprite) + { + sprite.texture = Texture.EMPTY; + sprite.alpha = 255; + } + + 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; + } + + 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.SNOWBOARDING_EFFECT) hasShadow = false; + + if(hasShadow) + { + sprite.visible = true; + + if(!this._shadow || (scale !== this._scale)) + { + let offsetX = 0; + let offsetY = 0; + + if(scale < 48) + { + sprite.libraryAssetName = 'sh_std_sd_1_0_0'; + + this._shadow = GetAssetManager().getAsset(sprite.libraryAssetName); + + offsetX = -8; + offsetY = ((this._canStandUp) ? 6 : -3); + } + else + { + sprite.libraryAssetName = 'h_std_sd_1_0_0'; + + this._shadow = GetAssetManager().getAsset(sprite.libraryAssetName); + + 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 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/packages/room/src/object/visualization/avatar/AvatarVisualizationData.ts b/packages/room/src/object/visualization/avatar/AvatarVisualizationData.ts new file mode 100644 index 0000000..ec4b769 --- /dev/null +++ b/packages/room/src/object/visualization/avatar/AvatarVisualizationData.ts @@ -0,0 +1,29 @@ +import { AvatarScaleType, IAssetData, IAvatarEffectListener, IAvatarImage, IAvatarImageListener, IObjectVisualizationData } from '@nitrots/api'; +import { GetAvatarRenderManager } from '@nitrots/avatar'; + +export class AvatarVisualizationData implements IObjectVisualizationData +{ + public initialize(asset: IAssetData): boolean + { + return true; + } + + public dispose(): void + { + } + + public createAvatarImage(figure: string, size: number, gender: string = null, avatarListener: IAvatarImageListener = null, effectListener: IAvatarEffectListener = null): IAvatarImage + { + let avatarImage: IAvatarImage = null; + + if(size > 48) avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, gender, avatarListener, effectListener); + else avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.SMALL, gender, avatarListener, effectListener); + + return avatarImage; + } + + public get layerCount(): number + { + return 0; + } +} diff --git a/packages/room/src/object/visualization/avatar/additions/ExpressionAddition.ts b/packages/room/src/object/visualization/avatar/additions/ExpressionAddition.ts new file mode 100644 index 0000000..cc54267 --- /dev/null +++ b/packages/room/src/object/visualization/avatar/additions/ExpressionAddition.ts @@ -0,0 +1,42 @@ +import { IRoomObjectSprite } from '@nitrots/api'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { IExpressionAddition } from './IExpressionAddition'; + +export class ExpressionAddition implements IExpressionAddition +{ + constructor( + private _id: number, + private _type: number, + private _visualization: AvatarVisualization) + {} + + 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; + } +} diff --git a/packages/room/src/object/visualization/avatar/additions/ExpressionAdditionFactory.ts b/packages/room/src/object/visualization/avatar/additions/ExpressionAdditionFactory.ts new file mode 100644 index 0000000..7276544 --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/avatar/additions/FloatingHeartAddition.ts b/packages/room/src/object/visualization/avatar/additions/FloatingHeartAddition.ts new file mode 100644 index 0000000..3de2568 --- /dev/null +++ b/packages/room/src/object/visualization/avatar/additions/FloatingHeartAddition.ts @@ -0,0 +1,157 @@ +import { AvatarAction, IRoomObjectSprite } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { GetTickerTime } from '@nitrots/utils'; +import { Texture } from 'pixi.js'; +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 = null; + private _startTime: number = GetTickerTime(); + private _delta: number = 0; + private _offsetY: number = 0; + private _scale: number = 0; + private _state: number = 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 = GetAssetManager().getTexture('avatar_addition_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 = GetAssetManager().getTexture('avatar_addition_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 === AvatarAction.POSTURE_SIT) + { + this._offsetY += (additionScale / 2); + } + + else if(this.visualization.posture === AvatarAction.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((GetTickerTime() - 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/packages/room/src/object/visualization/avatar/additions/FloatingIdleZAddition.ts b/packages/room/src/object/visualization/avatar/additions/FloatingIdleZAddition.ts new file mode 100644 index 0000000..820b8a6 --- /dev/null +++ b/packages/room/src/object/visualization/avatar/additions/FloatingIdleZAddition.ts @@ -0,0 +1,155 @@ +import { AvatarAction, IRoomObjectSprite } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { GetTickerTime } from '@nitrots/utils'; +import { Texture } from 'pixi.js'; +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 _asset: Texture = null; + private _startTime: number = GetTickerTime(); + private _offsetY: number = 0; + private _scale: number = 0; + private _state: number = 0; + + constructor( + private _id: number, + private _visualization: AvatarVisualization) + {} + + 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 ('avatar_addition_user_idle_' + side + '_' + state + ((this._scale < 48) ? '_small' : '')); + } + + public update(sprite: IRoomObjectSprite, scale: number): void + { + if(!sprite) return; + + this._scale = scale; + this._asset = GetAssetManager().getTexture(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 === AvatarAction.POSTURE_SIT) + { + this._offsetY += (additionScale / 2); + } + + else if(this._visualization.posture === AvatarAction.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 = GetTickerTime(); + + 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 = GetAssetManager().getTexture(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 = GetAssetManager().getTexture(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 = GetAssetManager().getTexture(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/packages/room/src/object/visualization/avatar/additions/GameClickTargetAddition.ts b/packages/room/src/object/visualization/avatar/additions/GameClickTargetAddition.ts new file mode 100644 index 0000000..6ff9cce --- /dev/null +++ b/packages/room/src/object/visualization/avatar/additions/GameClickTargetAddition.ts @@ -0,0 +1,51 @@ +import { AlphaTolerance, IRoomObjectSprite } from '@nitrots/api'; +import { GetTexturePool } from '@nitrots/utils'; +import { Texture } from 'pixi.js'; +import { IAvatarAddition } from './IAvatarAddition'; + +export class GameClickTargetAddition implements IAvatarAddition +{ + private static WIDTH: number = 46; + private static HEIGHT: number = 60; + private static OFFSET_X: number = -23; + private static OFFSET_Y: number = -48; + + private _asset: Texture = null; + + constructor( + private _id: number) + {} + + public dispose(): void + { + if(this._asset) + { + GetTexturePool().putTexture(this._asset); + + this._asset = null; + } + } + + public update(sprite: IRoomObjectSprite, scale: number): void + { + if(!sprite) return; + + if(!this._asset) this._asset = GetTexturePool().getTexture(GameClickTargetAddition.WIDTH, GameClickTargetAddition.HEIGHT); + + sprite.visible = true; + sprite.texture = this._asset; + sprite.offsetX = GameClickTargetAddition.OFFSET_X; + sprite.offsetY = GameClickTargetAddition.OFFSET_Y; + sprite.alphaTolerance = AlphaTolerance.MATCH_ALL_PIXELS; + } + + public animate(sprite: IRoomObjectSprite): boolean + { + return false; + } + + public get id(): number + { + return this._id; + } +} diff --git a/packages/room/src/object/visualization/avatar/additions/GuideStatusBubbleAddition.ts b/packages/room/src/object/visualization/avatar/additions/GuideStatusBubbleAddition.ts new file mode 100644 index 0000000..0613b4d --- /dev/null +++ b/packages/room/src/object/visualization/avatar/additions/GuideStatusBubbleAddition.ts @@ -0,0 +1,93 @@ +import { AvatarAction, AvatarGuideStatus, IRoomObjectSprite } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { Texture } from 'pixi.js'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { IAvatarAddition } from './IAvatarAddition'; + +export class GuideStatusBubbleAddition implements IAvatarAddition +{ + private _asset: Texture = null; + private _relativeDepth: number = 0; + + constructor( + private _id: number, + private _visualization: AvatarVisualization, + private _status: number) + {} + + 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; + + this._asset = GetAssetManager().getTexture((this._status === AvatarGuideStatus.GUIDE) ? 'avatar_addition_user_guide_bubble' : 'avatar_addition_user_guide_requester_bubble'); + + if(scale < 48) + { + offsetX = -19; + offsetY = -80; + additionScale = 32; + } + else + { + offsetX = -19; + offsetY = -120; + } + + if(this._visualization.posture === AvatarAction.POSTURE_SIT) + { + offsetY += (additionScale / 2); + } + + else if(this._visualization.posture === AvatarAction.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; + } +} diff --git a/packages/room/src/object/visualization/avatar/additions/IAvatarAddition.ts b/packages/room/src/object/visualization/avatar/additions/IAvatarAddition.ts new file mode 100644 index 0000000..061b75c --- /dev/null +++ b/packages/room/src/object/visualization/avatar/additions/IAvatarAddition.ts @@ -0,0 +1,9 @@ +import { IRoomObjectSprite } from '@nitrots/api'; + +export interface IAvatarAddition +{ + dispose(): void; + update(sprite: IRoomObjectSprite, scale: number): void; + animate(sprite: IRoomObjectSprite): boolean; + id: number; +} diff --git a/packages/room/src/object/visualization/avatar/additions/IExpressionAddition.ts b/packages/room/src/object/visualization/avatar/additions/IExpressionAddition.ts new file mode 100644 index 0000000..d13225c --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/avatar/additions/MutedBubbleAddition.ts b/packages/room/src/object/visualization/avatar/additions/MutedBubbleAddition.ts new file mode 100644 index 0000000..84e9401 --- /dev/null +++ b/packages/room/src/object/visualization/avatar/additions/MutedBubbleAddition.ts @@ -0,0 +1,77 @@ +import { AvatarAction, IRoomObjectSprite } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { Texture } from 'pixi.js'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { IAvatarAddition } from './IAvatarAddition'; + +export class MutedBubbleAddition implements IAvatarAddition +{ + private _asset: Texture = null; + + constructor( + private _id: number, + private _visualization: AvatarVisualization) + {} + + 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 = GetAssetManager().getTexture('avatar_addition_user_muted_small'); + + additionScale = 32; + offsetX = -12; + offsetY = -66; + } + else + { + this._asset = GetAssetManager().getTexture('avatar_addition_user_muted'); + + offsetX = -15; + offsetY = -110; + } + + if(this._visualization.posture === AvatarAction.POSTURE_SIT) offsetY += (additionScale / 2); + else if(this._visualization.posture === AvatarAction.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/packages/room/src/object/visualization/avatar/additions/NumberBubbleAddition.ts b/packages/room/src/object/visualization/avatar/additions/NumberBubbleAddition.ts new file mode 100644 index 0000000..1d6853a --- /dev/null +++ b/packages/room/src/object/visualization/avatar/additions/NumberBubbleAddition.ts @@ -0,0 +1,175 @@ +import { AvatarAction, IRoomObjectSprite } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { Texture } from 'pixi.js'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { IAvatarAddition } from './IAvatarAddition'; + +export class NumberBubbleAddition implements IAvatarAddition +{ + private _asset: Texture = null; + private _scale: number = 0; + private _numberValueFadeDirection: number = 0; + private _numberValueMoving: boolean = false; + private _numberValueMoveCounter: number = 0; + + constructor( + private _id: number, + private _number: number, + private _visualization: AvatarVisualization) + {} + + 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 = GetAssetManager().getTexture('avatar_addition_number_' + this._number + '_small'); + + additionScale = 32; + offsetX = -6; + offsetY = -52; + } + else + { + this._asset = GetAssetManager().getTexture('avatar_addition_number_' + this._number); + + offsetX = -8; + offsetY = -105; + } + + if(this._visualization.posture === AvatarAction.POSTURE_SIT) + { + offsetY += (additionScale / 2); + } + + else if(this._visualization.posture === AvatarAction.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; + } +} diff --git a/packages/room/src/object/visualization/avatar/additions/TypingBubbleAddition.ts b/packages/room/src/object/visualization/avatar/additions/TypingBubbleAddition.ts new file mode 100644 index 0000000..8028340 --- /dev/null +++ b/packages/room/src/object/visualization/avatar/additions/TypingBubbleAddition.ts @@ -0,0 +1,95 @@ +import { AvatarAction, IRoomObjectSprite } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { Texture } from 'pixi.js'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { IAvatarAddition } from './IAvatarAddition'; + +export class TypingBubbleAddition implements IAvatarAddition +{ + private _asset: Texture = null; + private _relativeDepth: number = 0; + + constructor( + private _id: number, + private _visualization: AvatarVisualization) + {} + + 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 = GetAssetManager().getTexture('avatar_addition_user_typing_small'); + + offsetX = 3; + offsetY = -42; + + additionScale = 32; + } + else + { + this._asset = GetAssetManager().getTexture('avatar_addition_user_typing'); + + offsetX = 14; + offsetY = -83; + } + + if(this._visualization.posture === AvatarAction.POSTURE_SIT) + { + offsetY += (additionScale / 2); + } + + else if(this._visualization.posture === AvatarAction.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; + } +} diff --git a/packages/room/src/object/visualization/avatar/additions/index.ts b/packages/room/src/object/visualization/avatar/additions/index.ts new file mode 100644 index 0000000..b2e5dda --- /dev/null +++ b/packages/room/src/object/visualization/avatar/additions/index.ts @@ -0,0 +1,11 @@ +export * from './ExpressionAddition'; +export * from './ExpressionAdditionFactory'; +export * from './FloatingHeartAddition'; +export * from './FloatingIdleZAddition'; +export * from './GameClickTargetAddition'; +export * from './GuideStatusBubbleAddition'; +export * from './IAvatarAddition'; +export * from './IExpressionAddition'; +export * from './MutedBubbleAddition'; +export * from './NumberBubbleAddition'; +export * from './TypingBubbleAddition'; diff --git a/packages/room/src/object/visualization/avatar/index.ts b/packages/room/src/object/visualization/avatar/index.ts new file mode 100644 index 0000000..6801a02 --- /dev/null +++ b/packages/room/src/object/visualization/avatar/index.ts @@ -0,0 +1,3 @@ +export * from './AvatarVisualization'; +export * from './AvatarVisualizationData'; +export * from './additions'; diff --git a/packages/room/src/object/visualization/data/AnimationData.ts b/packages/room/src/object/visualization/data/AnimationData.ts new file mode 100644 index 0000000..c1d4308 --- /dev/null +++ b/packages/room/src/object/visualization/data/AnimationData.ts @@ -0,0 +1,191 @@ +import { IAssetVisualAnimation, IAssetVisualAnimationLayer, IAssetVisualAnimationSequenceFrame } from '@nitrots/api'; +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/packages/room/src/object/visualization/data/AnimationFrame.ts b/packages/room/src/object/visualization/data/AnimationFrame.ts new file mode 100644 index 0000000..615c7fb --- /dev/null +++ b/packages/room/src/object/visualization/data/AnimationFrame.ts @@ -0,0 +1,117 @@ +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); + } +} diff --git a/packages/room/src/object/visualization/data/AnimationFrameData.ts b/packages/room/src/object/visualization/data/AnimationFrameData.ts new file mode 100644 index 0000000..6f7b799 --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/data/AnimationFrameDirectionalData.ts b/packages/room/src/object/visualization/data/AnimationFrameDirectionalData.ts new file mode 100644 index 0000000..79f5df9 --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/data/AnimationFrameSequenceData.ts b/packages/room/src/object/visualization/data/AnimationFrameSequenceData.ts new file mode 100644 index 0000000..5522587 --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/data/AnimationLayerData.ts b/packages/room/src/object/visualization/data/AnimationLayerData.ts new file mode 100644 index 0000000..6271524 --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/data/AnimationSizeData.ts b/packages/room/src/object/visualization/data/AnimationSizeData.ts new file mode 100644 index 0000000..190ccc8 --- /dev/null +++ b/packages/room/src/object/visualization/data/AnimationSizeData.ts @@ -0,0 +1,158 @@ +import { IAssetVisualAnimation } from '@nitrots/api'; +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.split('_')[0]); + 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/packages/room/src/object/visualization/data/AnimationStateData.ts b/packages/room/src/object/visualization/data/AnimationStateData.ts new file mode 100644 index 0000000..ad7a13e --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/data/ColorData.ts b/packages/room/src/object/visualization/data/ColorData.ts new file mode 100644 index 0000000..05978b5 --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/data/DirectionData.ts b/packages/room/src/object/visualization/data/DirectionData.ts new file mode 100644 index 0000000..130b548 --- /dev/null +++ b/packages/room/src/object/visualization/data/DirectionData.ts @@ -0,0 +1,197 @@ +import { BLEND_MODES } from 'pixi.js'; +import { LayerData } from './LayerData'; + +export class DirectionData +{ + public static USE_DEFAULT_DIRECTION: 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 getLayerBlendMode(layerId: number): BLEND_MODES + { + const existing = this.getLayer(layerId); + + if(!existing) return LayerData.DEFAULT_BLEND_MODE; + + return existing.blendMode; + } + + public setLayerBlendMode(layerId: number, blendMode: BLEND_MODES): void + { + const existing = this.getLayer(layerId); + + if(!existing) return; + + if(!blendMode || !blendMode.length) return; + + existing.blendMode = blendMode; + } + + 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; + } +} diff --git a/packages/room/src/object/visualization/data/DirectionalOffsetData.ts b/packages/room/src/object/visualization/data/DirectionalOffsetData.ts new file mode 100644 index 0000000..6d1993d --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/data/LayerData.ts b/packages/room/src/object/visualization/data/LayerData.ts new file mode 100644 index 0000000..88ce0b1 --- /dev/null +++ b/packages/room/src/object/visualization/data/LayerData.ts @@ -0,0 +1,105 @@ +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_BLEND_MODE: 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; + + private _tag: string = LayerData.DEFAULT_TAG; + private _blendMode: BLEND_MODES = LayerData.DEFAULT_BLEND_MODE; + private _alpha: number = LayerData.DEFAULT_ALPHA; + private _ignoreMouse: boolean = LayerData.DEFAULT_IGNORE_MOUSE; + private _xOffset: number = LayerData.DEFAULT_XOFFSET; + private _yOffset: number = LayerData.DEFAULT_YOFFSET; + private _zOffset: number = LayerData.DEFAULT_ZOFFSET; + + public setFromLayer(layer: LayerData): void + { + if(!layer) return; + + this._tag = layer.tag; + this._blendMode = layer.blendMode; + 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 blendMode(): BLEND_MODES + { + return this._blendMode; + } + + public set blendMode(value: BLEND_MODES) + { + this._blendMode = value; + } + + 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; + } +} diff --git a/packages/room/src/object/visualization/data/ParticleSystemParticle.ts b/packages/room/src/object/visualization/data/ParticleSystemParticle.ts new file mode 100644 index 0000000..2378519 --- /dev/null +++ b/packages/room/src/object/visualization/data/ParticleSystemParticle.ts @@ -0,0 +1,9 @@ +import { IGraphicAsset } from '@nitrots/api'; + +export interface ParticleSystemParticle +{ + isEmitter?: boolean; + lifeTime?: number; + fade?: boolean; + frames?: IGraphicAsset[]; +} diff --git a/packages/room/src/object/visualization/data/PetSizeData.ts b/packages/room/src/object/visualization/data/PetSizeData.ts new file mode 100644 index 0000000..eb2b16f --- /dev/null +++ b/packages/room/src/object/visualization/data/PetSizeData.ts @@ -0,0 +1,130 @@ +import { IAssetGesture, IAssetPosture } from '@nitrots/api'; +import { AnimationSizeData } from './AnimationSizeData'; + +export class PetSizeData extends AnimationSizeData +{ + public static DEFAULT: number = -1; + + private _posturesToAnimations: Map = new Map(); + private _gesturesToAnimations: Map = new Map(); + private _defaultPosture: string = null; + + public processPostures(postures: { defaultPosture?: string, postures: IAssetPosture[] }): boolean + { + if(!postures) return false; + + if(postures.defaultPosture && postures.defaultPosture.length) this._defaultPosture = postures.defaultPosture; + + if(!postures.postures) return false; + + for(const posture of postures.postures) + { + 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: IAssetGesture[]): boolean + { + if(!gestures) return false; + + for(const gesture of gestures) + { + 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 getGestureDisabled(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 animationToPosture(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 animationToGesture(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 getGestureForAnimationId(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; + } +} diff --git a/packages/room/src/object/visualization/data/SizeData.ts b/packages/room/src/object/visualization/data/SizeData.ts new file mode 100644 index 0000000..bfd1953 --- /dev/null +++ b/packages/room/src/object/visualization/data/SizeData.ts @@ -0,0 +1,285 @@ +import { IAssetColor, IAssetVisualizationDirection, IAssetVisualizationLayer } from '@nitrots/api'; +import { BLEND_MODES } from 'pixi.js'; +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; + + // TODO: check the .nitro files for inks + if(layer.ink !== undefined) directionData.setLayerBlendMode(layerId, (layer.ink?.toLowerCase() as BLEND_MODES)); + + 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 getLayerBlendMode(direction: number, layerId: number): BLEND_MODES + { + const directionData = this.getDirectionData(direction); + + if(!directionData) return LayerData.DEFAULT_BLEND_MODE; + + return directionData.getLayerBlendMode(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; + } +} diff --git a/packages/room/src/object/visualization/data/index.ts b/packages/room/src/object/visualization/data/index.ts new file mode 100644 index 0000000..1fda26a --- /dev/null +++ b/packages/room/src/object/visualization/data/index.ts @@ -0,0 +1,15 @@ +export * from './AnimationData'; +export * from './AnimationFrame'; +export * from './AnimationFrameData'; +export * from './AnimationFrameDirectionalData'; +export * from './AnimationFrameSequenceData'; +export * from './AnimationLayerData'; +export * from './AnimationSizeData'; +export * from './AnimationStateData'; +export * from './ColorData'; +export * from './DirectionData'; +export * from './DirectionalOffsetData'; +export * from './LayerData'; +export * from './ParticleSystemParticle'; +export * from './PetSizeData'; +export * from './SizeData'; diff --git a/packages/room/src/object/visualization/furniture/FurnitureAnimatedVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureAnimatedVisualization.ts new file mode 100644 index 0000000..ef8420d --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureAnimatedVisualization.ts @@ -0,0 +1,398 @@ +import { IObjectVisualizationData, RoomObjectVariable, RoomObjectVisualizationType } from '@nitrots/api'; +import { AnimationData, AnimationFrame, AnimationStateData } from '../data'; +import { FurnitureAnimatedVisualizationData } from './FurnitureAnimatedVisualizationData'; +import { FurnitureVisualization } from './FurnitureVisualization'; + +export class FurnitureAnimatedVisualization extends FurnitureVisualization +{ + public static TYPE: string = RoomObjectVisualizationType.FURNITURE_ANIMATED; + public static DEFAULT_ANIMATION_ID: number = 0; + + protected _state: number = -1; + protected _frameIncrease: number = 1; + private _animationData: AnimationStateData = new AnimationStateData(); + private _animationScale: number = 0; + private _animationChangeTime: number = 0; + private _animatedLayerCount: number = 0; + private _directionChanged: boolean = 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 += this.frameIncrease; + 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 <= this.frameIncrease)) + { + lastFramePlayed = true; + } + } + + if((this._directionChanged || !frame) || ((frame.remainingFrameRepeats >= 0) && ((frame.remainingFrameRepeats = (frame.remainingFrameRepeats - this.frameIncrease)) <= 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; + } + + protected get frameIncrease(): number + { + return this._frameIncrease; + } + + protected get data(): FurnitureAnimatedVisualizationData + { + return this._data as FurnitureAnimatedVisualizationData; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureAnimatedVisualizationData.ts b/packages/room/src/object/visualization/furniture/FurnitureAnimatedVisualizationData.ts new file mode 100644 index 0000000..675d19b --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureAnimatedVisualizationData.ts @@ -0,0 +1,90 @@ +import { AnimationFrame, AnimationSizeData, SizeData } from '../data'; +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); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureBBVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureBBVisualization.ts new file mode 100644 index 0000000..b534565 --- /dev/null +++ b/packages/room/src/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; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts new file mode 100644 index 0000000..67a6c36 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts @@ -0,0 +1,89 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureBadgeDisplayVisualization extends FurnitureAnimatedVisualization +{ + private static BADGE: string = 'BADGE'; + + private _badgeId: string = ''; + private _badgeAssetNameNormalScale: string = ''; + private _badgeAssetNameSmallScale: string = ''; + private _badgeVisibleInState: number = -1; + + protected updateModel(scale: number): boolean + { + let updateModel = super.updateModel(scale); + + const badgeStatus = this.object.model.getValue(RoomObjectVariable.FURNITURE_BADGE_IMAGE_STATUS); + const badgeId = this.object.model.getValue(RoomObjectVariable.FURNITURE_BADGE_ASSET_NAME); + + if(badgeStatus === -1) + { + this._badgeAssetNameNormalScale = ''; + this._badgeAssetNameSmallScale = ''; + } + + else if((badgeStatus === 1) && (badgeId !== this._badgeId)) + { + this._badgeId = badgeId; + this._badgeAssetNameNormalScale = this._badgeId; + + if(this._badgeAssetNameSmallScale === '') this._badgeAssetNameSmallScale = this._badgeAssetNameNormalScale + '_32'; + + const visibleInState = this.object.model.getValue(RoomObjectVariable.FURNITURE_BADGE_VISIBLE_IN_STATE); + + if(!isNaN(visibleInState)) 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/packages/room/src/object/visualization/furniture/FurnitureBottleVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureBottleVisualization.ts new file mode 100644 index 0000000..344eefe --- /dev/null +++ b/packages/room/src/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 ANIMATION_ID_ROLL: 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.ANIMATION_ID_ROLL); + + 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); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureBrandedImageVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureBrandedImageVisualization.ts new file mode 100644 index 0000000..5c312be --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureBrandedImageVisualization.ts @@ -0,0 +1,210 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { Texture } from 'pixi.js'; +import { FurnitureVisualization } from './FurnitureVisualization'; + +export class FurnitureBrandedImageVisualization extends FurnitureVisualization +{ + protected static BRANDED_IMAGE: string = 'branded_image'; + protected static STATE_0: number = 0; + protected static STATE_1: number = 1; + protected static STATE_2: number = 2; + protected static STATE_3: number = 3; + + protected _imageUrl: string; + protected _shortUrl: string; + protected _imageReady: boolean; + + protected _offsetX: number; + protected _offsetY: number; + protected _offsetZ: number; + protected _currentFrame: number; + protected _totalFrames: number; + + constructor() + { + super(); + + this._imageUrl = null; + this._shortUrl = null; + this._imageReady = false; + + this._offsetX = 0; + this._offsetY = 0; + this._offsetZ = 0; + this._currentFrame = -1; + this._totalFrames = -1; + } + + public dispose(): void + { + super.dispose(); + + if(this._imageUrl) + { + (this.asset && this.asset.disposeAsset(this._imageUrl)); + // dispose all + } + } + + 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) || 0); + this._offsetY = (this.object.model.getValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Y) || 0); + this._offsetZ = (this.object.model.getValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Z) || 0); + } + + 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; + } + + 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) + { + let texture: Texture = null; + + texture = GetAssetManager().getTexture(imageUrl); + + if(!texture) return false; + + this.imageReady(texture, imageUrl); + + return true; + } + + return false; + } + + protected imageReady(texture: Texture, imageUrl: string): void + { + if(!texture) + { + this._imageUrl = null; + + return; + } + + this._imageUrl = imageUrl; + } + + protected checkAndCreateImageForCurrentState(): void + { + if(!this._imageUrl) return; + + const texture = GetAssetManager().getTexture(this._imageUrl); + + if(!texture) return; + + const state = this.object.getState(0); + + this.addBackgroundAsset(texture, state, 0); + } + + protected addBackgroundAsset(texture: Texture, state: number, frame: number): void + { + let x = 0; + let y = 0; + let flipH = false; + let flipV = false; + + switch(state) + { + case FurnitureBrandedImageVisualization.STATE_0: + x = 0; + y = 0; + flipH = false; + flipV = false; + break; + case FurnitureBrandedImageVisualization.STATE_1: + x = -(texture.width); + y = 0; + flipH = true; + flipV = false; + break; + case FurnitureBrandedImageVisualization.STATE_2: + x = -(texture.width); + y = -(texture.height); + flipH = true; + flipV = true; + break; + case FurnitureBrandedImageVisualization.STATE_3: + x = 0; + y = -(texture.height); + flipH = false; + flipV = true; + break; + } + + this.asset.addAsset(`${this._imageUrl}_${frame}`, texture, true, x, y, flipH, flipV); + } + + 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}_${this.getFrameNumber(scale, layerId)}`; + } + + return super.getSpriteAssetName(scale, layerId); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureBuilderPlaceholderVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureBuilderPlaceholderVisualization.ts new file mode 100644 index 0000000..ce769c0 --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/furniture/FurnitureCounterClockVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureCounterClockVisualization.ts new file mode 100644 index 0000000..22ca401 --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/furniture/FurnitureCuboidVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureCuboidVisualization.ts new file mode 100644 index 0000000..6aea624 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureCuboidVisualization.ts @@ -0,0 +1,6 @@ +import { RoomObjectSpriteVisualization } from '../RoomObjectSpriteVisualization'; + +export class FurnitureCuboidVisualization extends RoomObjectSpriteVisualization +{ + +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts new file mode 100644 index 0000000..b6f4566 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts @@ -0,0 +1,56 @@ +import { Texture } from 'pixi.js'; +import { IsometricImageFurniVisualization } from './IsometricImageFurniVisualization'; + +export class FurnitureDynamicThumbnailVisualization extends IsometricImageFurniVisualization +{ + private _cachedUrl: string; + + constructor() + { + super(); + + this._cachedUrl = null; + this._hasOutline = true; + } + + 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.source.scaleMode = 'linear'; + + this.setThumbnailImages(texture); + }; + } + else + { + this.setThumbnailImages(null); + } + } + } + + return super.updateModel(scale); + } + + protected getThumbnailURL(): string + { + throw (new Error('This method must be overridden!')); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureExternalImageVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureExternalImageVisualization.ts new file mode 100644 index 0000000..1261ff7 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureExternalImageVisualization.ts @@ -0,0 +1,51 @@ +import { RoomObjectVariable } from '@nitrots/api'; +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.buildThumbnailUrl(url); + + this._url = url; + + return this._url; + } + + private buildThumbnailUrl(url: string): string + { + url = url.replace('.png', '_small.png'); + + if(url.indexOf('.png') === -1) url = (url + '_small.png'); + + return url; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureFireworksVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureFireworksVisualization.ts new file mode 100644 index 0000000..1521060 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureFireworksVisualization.ts @@ -0,0 +1,110 @@ +import { IAdvancedMap, IParticleSystem, RoomObjectVariable } from '@nitrots/api'; +import { AdvancedMap, NitroLogger } from '@nitrots/utils'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; +import { FurnitureParticleSystem } from './FurnitureParticleSystem'; + +export class FurnitureFireworksVisualization extends FurnitureAnimatedVisualization +{ + private _particleSystems: IAdvancedMap; + private _currentParticleSystem: FurnitureParticleSystem; + + public dispose(): void + { + super.dispose(); + + this._currentParticleSystem = null; + + if(this._particleSystems) + { + for(const particleSystem of this._particleSystems.getValues()) particleSystem.dispose(); + + this._particleSystems = null; + } + } + + protected updateObject(scale: number, direction: number): boolean + { + if(super.updateObject(scale, direction)) + { + if(!this._particleSystems) + { + this.readDefinition(); + + if(this._particleSystems) this._currentParticleSystem = this._particleSystems.getValue(scale); + + else NitroLogger.log('ERROR Particle systems could not be read!', this.object.type); + } + else + { + if((scale !== this._scale) || (this._particleSystems.getValue(scale) !== this._currentParticleSystem)) + { + const particleSystem = this._particleSystems.getValue(scale); + + particleSystem.copyStateFrom(this._currentParticleSystem); + + if(this._currentParticleSystem) this._currentParticleSystem.reset(); + + this._currentParticleSystem = particleSystem; + } + } + + return true; + } + + return false; + } + + protected updateSprites(scale: number, update: boolean, animation: number): void + { + super.updateSprites(scale, update, animation); + + if(this._currentParticleSystem) this._currentParticleSystem.updateSprites(); + } + + protected updateAnimation(scale: number): number + { + if(this._currentParticleSystem) this._currentParticleSystem.updateAnimation(); + + return super.updateAnimation(scale); + } + + protected setAnimation(id: number): void + { + if(this._currentParticleSystem) this._currentParticleSystem.setAnimation(id); + + super.setAnimation(id); + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + if(this._currentParticleSystem && this._currentParticleSystem.controlsSprite(layerId)) + { + return this._currentParticleSystem.getLayerYOffset(scale, direction, layerId); + } + + return super.getLayerYOffset(scale, direction, layerId); + } + + private readDefinition(): boolean + { + if(!this.object || !this.object.model) return false; + + const fireworksData = this.object.model.getValue(RoomObjectVariable.FURNITURE_FIREWORKS_DATA); + + if(!fireworksData || !fireworksData.length) return false; + + this._particleSystems = new AdvancedMap(); + + for(const particleData of fireworksData) + { + const size = particleData.size; + const particleSystem = new FurnitureParticleSystem(this); + + particleSystem.parseData(particleData); + + this._particleSystems.add(size, particleSystem); + } + + return true; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureGiftWrappedFireworksVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureGiftWrappedFireworksVisualization.ts new file mode 100644 index 0000000..586ef49 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureGiftWrappedFireworksVisualization.ts @@ -0,0 +1,78 @@ +import { IRoomGeometry, RoomObjectVariable } from '@nitrots/api'; +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/packages/room/src/object/visualization/furniture/FurnitureGiftWrappedVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureGiftWrappedVisualization.ts new file mode 100644 index 0000000..abdb9ae --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureGiftWrappedVisualization.ts @@ -0,0 +1,60 @@ +import { IRoomGeometry, RoomObjectVariable } from '@nitrots/api'; +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/packages/room/src/object/visualization/furniture/FurnitureGuildCustomizedVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureGuildCustomizedVisualization.ts new file mode 100644 index 0000000..802253d --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureGuildCustomizedVisualization.ts @@ -0,0 +1,89 @@ +import { IGraphicAsset, IRoomObjectSprite, RoomObjectVariable } from '@nitrots/api'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureGuildCustomizedVisualization extends FurnitureAnimatedVisualization +{ + public static PRIMARY_COLOUR_SPRITE_TAG: string = 'COLOR1'; + public static SECONDARY_COLOUR_SPRITE_TAG: string = 'COLOR2'; + public static BADGE: string = 'BADGE'; + public static DEFAULT_COLOR_1: number = 0xEEEEEE; + public static DEFAULT_COLOR_2: number = 0x4B4B4B; + + private _color1: number; + private _color2: number; + private _badgeAssetNameNormalScale: string; + private _badgeAssetNameSmallScale: string; + + constructor() + { + super(); + + this._color1 = FurnitureGuildCustomizedVisualization.DEFAULT_COLOR_1; + this._color2 = FurnitureGuildCustomizedVisualization.DEFAULT_COLOR_2; + this._badgeAssetNameNormalScale = ''; + this._badgeAssetNameSmallScale = ''; + } + + protected updateModel(scale: number): boolean + { + const flag = super.updateModel(scale); + + if(this._badgeAssetNameNormalScale === '') + { + const assetName = this.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_ASSET_NAME); + + if(assetName) + { + this._badgeAssetNameNormalScale = assetName; + this._badgeAssetNameSmallScale = (this._badgeAssetNameNormalScale + '_32'); + } + } + + const color1 = this.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_COLOR_1); + + this._color1 = color1 ? color1 : FurnitureGuildCustomizedVisualization.DEFAULT_COLOR_1; + + const color2 = this.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_COLOR_2); + + this._color2 = color2 ? color2 : FurnitureGuildCustomizedVisualization.DEFAULT_COLOR_2; + + return flag; + } + + protected getLayerColor(scale: number, layerId: number, colorId: number): number + { + const tag = this.getLayerTag(scale, this._direction, layerId); + + switch(tag) + { + case FurnitureGuildCustomizedVisualization.PRIMARY_COLOUR_SPRITE_TAG: return this._color1; + case FurnitureGuildCustomizedVisualization.SECONDARY_COLOUR_SPRITE_TAG: return this._color2; + } + + return super.getLayerColor(scale, layerId, colorId); + } + + public getSpriteAssetName(scale: number, layerId: number): string + { + const tag = this.getLayerTag(scale, this._direction, layerId); + + if(tag === FurnitureGuildCustomizedVisualization.BADGE) + { + if(scale === 32) return this._badgeAssetNameSmallScale; + + return this._badgeAssetNameNormalScale; + } + + return super.getSpriteAssetName(scale, layerId); + } + + protected getLibraryAssetNameForSprite(asset: IGraphicAsset, sprite: IRoomObjectSprite): string + { + if(sprite.tag === FurnitureGuildCustomizedVisualization.BADGE) + { + return '%group.badge.url%' + sprite.libraryAssetName.replace('badge_', ''); + } + + return super.getLibraryAssetNameForSprite(asset, sprite); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureGuildIsometricBadgeVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureGuildIsometricBadgeVisualization.ts new file mode 100644 index 0000000..57403bd --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureGuildIsometricBadgeVisualization.ts @@ -0,0 +1,144 @@ +import { IGraphicAsset, IRoomObjectSprite, RoomObjectVariable } from '@nitrots/api'; +import { TextureUtils } from '@nitrots/utils'; +import { Matrix, Sprite, Texture } from 'pixi.js'; +import { IsometricImageFurniVisualization } from './IsometricImageFurniVisualization'; + +export class FurnitureGuildIsometricBadgeVisualization extends IsometricImageFurniVisualization +{ + public static PRIMARY_COLOUR_SPRITE_TAG: string = 'COLOR1'; + public static SECONDARY_COLOUR_SPRITE_TAG: string = 'COLOR2'; + public static DEFAULT_COLOR_1: number = 0xEEEEEE; + public static DEFAULT_COLOR_2: number = 0x4B4B4B; + + private _color1: number; + private _color2: number; + + protected updateModel(scale: number): boolean + { + const flag = super.updateModel(scale); + + if(!this.hasThumbnailImage) + { + const assetName = this.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_ASSET_NAME); + + if(assetName && assetName.length) this.setThumbnailImages(this.getBitmapAsset(assetName)); + } + + const color1 = this.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_COLOR_1); + + this._color1 = color1 ? color1 : FurnitureGuildIsometricBadgeVisualization.DEFAULT_COLOR_1; + + const color2 = this.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_COLOR_2); + + this._color2 = color2 ? color2 : FurnitureGuildIsometricBadgeVisualization.DEFAULT_COLOR_2; + + return flag; + } + + protected generateTransformedThumbnail(texture: Texture, asset: IGraphicAsset): Texture + { + const scale = 1.1; + const matrix = new Matrix(); + const difference = (asset.width / texture.width); + + switch(this.direction) + { + case 2: + matrix.a = difference; + matrix.b = (-0.5 * difference); + matrix.c = 0; + matrix.d = (difference * scale); + matrix.tx = 0; + matrix.ty = ((0.5 * difference) * texture.width); + break; + case 0: + case 4: + matrix.a = difference; + matrix.b = (0.5 * difference); + matrix.c = 0; + matrix.d = (difference * scale); + matrix.tx = 0; + matrix.ty = 0; + break; + default: + matrix.a = difference; + matrix.b = 0; + matrix.c = 0; + matrix.d = difference; + matrix.tx = 0; + matrix.ty = 0; + } + + const sprite = new Sprite(texture); + + sprite.setFromMatrix(matrix); + + sprite.position.set(0); + + return TextureUtils.generateTexture(sprite); + + /* const renderTexture = RenderTexture.create({ + width: asset.width, + height: asset.height + }); + + PixiApplicationProxy.instance.renderer.render(sprite, { + renderTexture, + clear: true, + }); + + return renderTexture; */ + + /* const sprite = new NitroSprite(texture); + + const renderTexture = RenderTexture.create({ + width: (asset.width + matrix.tx), + height: (asset.height + matrix.ty) + }); + + sprite.position.set(0) + + PixiApplicationProxy.instance.renderer.render(sprite, { + renderTexture, + clear: true, + transform: matrix + }); + + return renderTexture; */ + } + + protected getLayerColor(scale: number, layerId: number, colorId: number): number + { + const tag = this.getLayerTag(scale, this._direction, layerId); + + switch(tag) + { + case FurnitureGuildIsometricBadgeVisualization.PRIMARY_COLOUR_SPRITE_TAG: return this._color1; + case FurnitureGuildIsometricBadgeVisualization.SECONDARY_COLOUR_SPRITE_TAG: return this._color2; + } + + return super.getLayerColor(scale, layerId, colorId); + } + + protected getLibraryAssetNameForSprite(asset: IGraphicAsset, sprite: IRoomObjectSprite): string + { + if(sprite.tag === FurnitureGuildIsometricBadgeVisualization.THUMBNAIL) + { + if(this.object && this.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_ASSET_NAME)) + { + return '%group.badge.url%' + this.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_ASSET_NAME); + } + } + + return super.getLibraryAssetNameForSprite(asset, sprite); + } + + private getBitmapAsset(name: string) + { + const asset = this.asset.getAsset(name); + + if(!asset || !asset.texture) return null; + + return asset.texture; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureHabboWheelVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureHabboWheelVisualization.ts new file mode 100644 index 0000000..628d811 --- /dev/null +++ b/packages/room/src/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 ANIMATION_ID_START_ROLL: number = 31; + private static ANIMATION_ID_ROLL: 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.ANIMATION_ID_START_ROLL); + this._stateQueue.push(FurnitureHabboWheelVisualization.ANIMATION_ID_ROLL); + + 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); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureIsometricBBVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureIsometricBBVisualization.ts new file mode 100644 index 0000000..7cc55f7 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureIsometricBBVisualization.ts @@ -0,0 +1,75 @@ +import { IGraphicAsset } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { TextureUtils } from '@nitrots/utils'; +import { Matrix, Sprite, Texture } from 'pixi.js'; +import { FurnitureBBVisualization } from './FurnitureBBVisualization'; +import { FurnitureBrandedImageVisualization } from './FurnitureBrandedImageVisualization'; + +export class FurnitureIsometricBBVisualization extends FurnitureBBVisualization +{ + private _needsTransform: boolean = true; + + protected generateTransformedImage(texture: Texture, asset: IGraphicAsset): void + { + const scale = 1.1; + const matrix = new Matrix(); + const difference = (asset.width / texture.width); + + switch(this.direction) + { + case 2: + matrix.a = difference; + matrix.b = (-0.5 * difference); + matrix.c = 0; + matrix.d = (difference * scale); + matrix.tx = 0; + matrix.ty = ((0.5 * difference) * texture.width); + break; + case 0: + case 4: + matrix.a = difference; + matrix.b = (0.5 * difference); + matrix.c = 0; + matrix.d = (difference * scale); + matrix.tx = 0; + matrix.ty = 0; + break; + default: + matrix.a = difference; + matrix.b = 0; + matrix.c = 0; + matrix.d = difference; + matrix.tx = 0; + matrix.ty = 0; + } + + const sprite = new Sprite(texture); + const newTexture = TextureUtils.createAndWriteRenderTexture((asset.width + matrix.tx), (asset.height + matrix.ty), sprite, matrix); + + this.asset.disposeAsset(`${this._imageUrl}_0`); + this.asset.addAsset(`${this._imageUrl}_0`, newTexture, true, sprite.x, sprite.y, asset.flipH, asset.flipV); + + this._needsTransform = false; + } + + protected checkAndCreateImageForCurrentState(): void + { + super.checkAndCreateImageForCurrentState(); + + this._needsTransform = true; + } + + protected getSpriteAssetName(scale: number, layerId: number): string + { + const tag = this.getLayerTag(scale, this._direction, layerId); + + if((tag === FurnitureBrandedImageVisualization.BRANDED_IMAGE) && this._imageUrl) + { + if(this._needsTransform) this.generateTransformedImage(GetAssetManager().getTexture(this._imageUrl), this.getAsset(super.getSpriteAssetName(scale, layerId))); + + return `${this._imageUrl}_${this.getFrameNumber(scale, layerId)}`; + } + + return super.getSpriteAssetName(scale, layerId); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureMannequinVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureMannequinVisualization.ts new file mode 100644 index 0000000..7574dca --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureMannequinVisualization.ts @@ -0,0 +1,143 @@ +import { AvatarSetType, IAvatarImage, IAvatarImageListener, IGraphicAsset, IObjectVisualizationData, RoomObjectVariable } from '@nitrots/api'; +import { Texture } from 'pixi.js'; +import { FurnitureMannequinVisualizationData } from './FurnitureMannequinVisualizationData'; +import { FurnitureVisualization } from './FurnitureVisualization'; +export class FurnitureMannequinVisualization extends FurnitureVisualization implements IAvatarImageListener +{ + private static AVATAR_IMAGE_SPRITE_TAG: string = 'avatar_image'; + + private _mannequinScale: number = -1; + private _figure: string = null; + private _gender: string = null; + private _avatarImage: IAvatarImage = null; + private _avatarWidth: number = 90; + private _avatarHeight: number = 130; + private _needsUpdate: boolean = false; + private _placeHolderFigure: string = 'hd-99999-99998'; + private _disposed: boolean = 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._avatarImage) + { + this._avatarImage.dispose(); + + this._avatarImage = 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(): void + { + if(this._avatarImage) + { + this._avatarImage.dispose(); + + this._avatarImage = null; + } + + this._avatarImage = this.data.createAvatarImage(this._figure, this._mannequinScale, this._gender, this); + } + + public resetFigure(figure: string): void + { + this.updateAvatar(); + + this._needsUpdate = true; + } + + protected getLayerXOffset(scale: number, direction: number, layerId: number): number + { + const tag = this.getLayerTag(scale, direction, layerId); + + if((tag === FurnitureMannequinVisualization.AVATAR_IMAGE_SPRITE_TAG) && this._avatarImage) return (-(this._avatarWidth) / 3); + + 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._avatarImage) return (-(this._avatarHeight) / 3); + + return super.getLayerYOffset(scale, direction, layerId); + } + + public getTexture(scale: number, layerId: number, asset: IGraphicAsset): Texture + { + const tag = this.getLayerTag(scale, this.direction, layerId); + + if((tag === FurnitureMannequinVisualization.AVATAR_IMAGE_SPRITE_TAG) && this._avatarImage) + { + this._avatarImage.setDirection(AvatarSetType.FULL, this.direction); + + return this._avatarImage.processAsTexture(AvatarSetType.FULL, false); + } + + return super.getTexture(scale, layerId, asset); + } + + public get disposed(): boolean + { + return this._disposed; + } + + protected get data(): FurnitureMannequinVisualizationData + { + return this._data as FurnitureMannequinVisualizationData; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureMannequinVisualizationData.ts b/packages/room/src/object/visualization/furniture/FurnitureMannequinVisualizationData.ts new file mode 100644 index 0000000..a9c43e3 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureMannequinVisualizationData.ts @@ -0,0 +1,32 @@ +import { IAvatarEffectListener, IAvatarImage, IAvatarImageListener } from '@nitrots/api'; +import { AvatarVisualizationData } from '../avatar'; +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); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureParticleSystem.ts b/packages/room/src/object/visualization/furniture/FurnitureParticleSystem.ts new file mode 100644 index 0000000..15d0d69 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureParticleSystem.ts @@ -0,0 +1,313 @@ +import { IAdvancedMap, IGraphicAsset, IParticleSystem, IRoomObjectSprite } from '@nitrots/api'; +import { AdvancedMap, TextureUtils, Vector3d } from '@nitrots/utils'; +import { AlphaFilter, Graphics, Matrix, Point, Sprite, Texture } from 'pixi.js'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; +import { FurnitureParticleSystemEmitter } from './FurnitureParticleSystemEmitter'; + +export class FurnitureParticleSystem +{ + private _emitters: IAdvancedMap; + private _visualization: FurnitureAnimatedVisualization; + private _size: number; + private _canvasId: number = -1; + private _offsetY: number; + private _currentEmitter: FurnitureParticleSystemEmitter; + private _canvasTexture: Texture; + private _roomSprite: IRoomObjectSprite; + private _hasIgnited: boolean = false; + private _centerX: number = 0; + private _centerY: number = 0; + private _scaleMultiplier: number = 1; + private _blackOverlay: Graphics; + private _blackOverlayAlphaTransform: AlphaFilter; + private _particleColorTransform: AlphaFilter; + private _identityMatrix: Matrix; + private _translationMatrix: Matrix; + private _blend: number = 1; + private _bgColor: number = 0xFF000000; + private _emptySprite: Sprite; + private _isDone: boolean = false; + + constructor(visualization: FurnitureAnimatedVisualization) + { + this._emitters = new AdvancedMap(); + this._visualization = visualization; + this._blackOverlayAlphaTransform = new AlphaFilter(); + this._blackOverlayAlphaTransform.alpha = 1; + this._particleColorTransform = new AlphaFilter(); + this._identityMatrix = new Matrix(); + this._translationMatrix = new Matrix(); + } + + public dispose(): void + { + for(const emitter of this._emitters.getValues()) emitter.dispose(); + + this._emitters = null; + + if(this._canvasTexture) + { + this._canvasTexture.destroy(); + this._canvasTexture = null; + } + + if(this._blackOverlay) + { + this._blackOverlay.destroy(); + this._blackOverlay = null; + } + + if(this._emptySprite) + { + this._emptySprite.destroy(); + this._emptySprite = null; + } + + this._blackOverlayAlphaTransform = null; + this._particleColorTransform = null; + this._identityMatrix = null; + this._translationMatrix = null; + } + + public reset(): void + { + if(this._currentEmitter) this._currentEmitter.reset(); + + this._currentEmitter = null; + this._hasIgnited = false; + this._isDone = false; + + this.updateCanvas(); + } + + public setAnimation(id: number): void + { + if(this._currentEmitter) this._currentEmitter.reset(); + + this._currentEmitter = this._emitters.getValue(id); + this._hasIgnited = false; + this._isDone = false; + + this.updateCanvas(); + } + + private updateCanvas(): void + { + if(!this._currentEmitter || (this._canvasId === -1)) return; + + this._roomSprite = this._visualization.getSprite(this._canvasId); + + if(this._roomSprite && this._roomSprite.texture) + { + if((this._roomSprite.width <= 1) || (this._roomSprite.height <= 1)) return; + + if(this._canvasTexture && ((this._canvasTexture.width !== this._roomSprite.width) || (this._canvasTexture.height !== this._roomSprite.height))) this._canvasTexture = null; + + this.clearCanvas(); + + this._centerX = -(this._roomSprite.offsetX); + this._centerY = -(this._roomSprite.offsetY); + this._roomSprite.texture = this._canvasTexture; + } + } + + public getLayerYOffset(scale: number, direction: number, layerId: number): number + { + if(this._currentEmitter && (this._currentEmitter.roomObjectSpriteId === layerId)) + { + return this._currentEmitter.y * this._scaleMultiplier; + } + + return 0; + } + + public controlsSprite(k: number): boolean + { + if(this._currentEmitter) return this._currentEmitter.roomObjectSpriteId == k; + + return false; + } + + public updateSprites(): void + { + if(!this._currentEmitter || !this._roomSprite) return; + + if(this._canvasTexture && (this._roomSprite.texture !== this._canvasTexture)) + { + this._roomSprite.texture = this._canvasTexture; + } + + if(this._hasIgnited) + { + if(this._currentEmitter.roomObjectSpriteId >= 0) this._visualization.getSprite(this._currentEmitter.roomObjectSpriteId).visible = false; + } + } + + public updateAnimation(): void + { + if(!this._currentEmitter || !this._roomSprite || this._isDone) return; + + const k = 10; + + if(!this._hasIgnited && this._currentEmitter.hasIgnited) this._hasIgnited = true; + + const offsetY = (this._offsetY * this._scaleMultiplier); + + this._currentEmitter.update(); + + if(this._hasIgnited) + { + if(this._currentEmitter.roomObjectSpriteId >= 0) + { + this._visualization.getSprite(this._currentEmitter.roomObjectSpriteId).visible = false; + } + + if(!this._canvasTexture) this.updateCanvas(); + + this.clearCanvas(); + + for(const particle of this._currentEmitter.particles) + { + const tx = (this._centerX + ((((particle.x - particle.z) * k) / 10) * this._scaleMultiplier)); + const ty = ((this._centerY - offsetY) + ((((particle.y + ((particle.x + particle.z) / 2)) * k) / 10) * this._scaleMultiplier)); + const asset = particle.getAsset(); + + if(asset && asset.texture) + { + if(particle.fade && (particle.alphaMultiplier < 1)) + { + this._translationMatrix.identity(); + this._translationMatrix.translate((tx + asset.offsetX), (ty + asset.offsetY)); + + const sprite = new Sprite(asset.texture); + + this._particleColorTransform.alpha = particle.alphaMultiplier; + + sprite.filters = [this._particleColorTransform]; + + TextureUtils.writeToTexture(sprite, this._canvasTexture, false, this._translationMatrix); + } + else + { + const point = new Point((tx + asset.offsetX), (ty + asset.offsetY)); + const sprite = new Sprite(asset.texture); + + sprite.x = point.x; + sprite.y = point.y; + + TextureUtils.writeToTexture(sprite, this._canvasTexture, false); + } + } + else + { + const sprite = new Sprite(Texture.WHITE); + + sprite.tint = 0xFFFFFF; + sprite.x = (tx - 1); + sprite.y = (ty - 1); + sprite.width = 2; + sprite.height = 2; + + TextureUtils.writeToTexture(sprite, this._canvasTexture, false); + } + } + + if(!this._currentEmitter.particles.length) + { + this._isDone = true; + + return; + } + } + } + + public parseData(particleSystem: IParticleSystem): void + { + this._size = particleSystem.size; + this._canvasId = ((particleSystem.canvasId !== undefined) ? particleSystem.canvasId : -1); + this._offsetY = ((particleSystem.offsetY !== undefined) ? particleSystem.offsetY : 10); + this._scaleMultiplier = (this._size / 64); + this._blend = ((particleSystem.blend !== undefined) ? particleSystem.blend : 1); + this._blend = Math.min(this._blend, 1); + + this._blackOverlayAlphaTransform.alpha = this._blend; + + const bgColor = ((particleSystem.bgColor !== undefined) ? particleSystem.bgColor : '0'); + + this._bgColor = (parseInt(bgColor, 16) || 0x000000); + + if(!particleSystem.emitters || !particleSystem.emitters.length) return; + + for(const emitter of particleSystem.emitters) + { + const emitterId = emitter.id; + const emitterName = emitter.name; + const emitterSpriteId = emitter.spriteId; + + const particleEmitter = new FurnitureParticleSystemEmitter(emitterName, emitterSpriteId); + + this._emitters.add(emitterId, particleEmitter); + + const maxNumParticles = emitter.maxNumParticles; + const particlesPerFrame = emitter.particlesPerFrame; + const burstPulse = ((emitter.burstPulse !== undefined) ? emitter.burstPulse : 1); + const fuseTime = emitter.fuseTime; + const simulationForce = emitter.simulation.force; + const simulationDirection = emitter.simulation.direction; + const simulationGravity = emitter.simulation.gravity; + const simulationAirFriction = emitter.simulation.airFriction; + const simulationShape = emitter.simulation.shape; + const simulationEnergy = emitter.simulation.energy; + + for(const particle of emitter.particles) + { + const lifeTime = particle.lifeTime; + const isEmitter = (particle.isEmitter || false); + const fade = (particle.fade || false); + + const frames: IGraphicAsset[] = []; + + for(const name of particle.frames) frames.push(this._visualization.asset.getAsset(name)); + + particleEmitter.configureParticle(lifeTime, isEmitter, frames, fade); + } + + particleEmitter.setup(maxNumParticles, particlesPerFrame, simulationForce, new Vector3d(0, simulationDirection, 0), simulationGravity, simulationAirFriction, simulationShape, simulationEnergy, fuseTime, burstPulse); + } + } + + public copyStateFrom(particleSystem: FurnitureParticleSystem): void + { + let emitterId = 0; + + if(particleSystem._emitters && particleSystem._currentEmitter) + { + emitterId = particleSystem._emitters.getKey(particleSystem._emitters.getValues().indexOf(particleSystem._currentEmitter)); + } + + this.setAnimation(emitterId); + + if(this._currentEmitter) this._currentEmitter.copyStateFrom(particleSystem._currentEmitter, (particleSystem._size / this._size)); + + this._canvasTexture = null; + } + + private clearCanvas(): void + { + if(!this._emptySprite) + { + this._emptySprite = new Sprite(Texture.EMPTY); + + this._emptySprite.alpha = 0; + } + + if(!this._canvasTexture) + { + this._canvasTexture = TextureUtils.createRenderTexture(this._roomSprite.width, this._roomSprite.height); + } + else + { + TextureUtils.writeToTexture(this._emptySprite, this._canvasTexture, true); + } + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureParticleSystemEmitter.ts b/packages/room/src/object/visualization/furniture/FurnitureParticleSystemEmitter.ts new file mode 100644 index 0000000..43b8ea1 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureParticleSystemEmitter.ts @@ -0,0 +1,277 @@ +import { IGraphicAsset, IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { ParticleSystemParticle } from '../data'; +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: ParticleSystemParticle[]; + 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; + private _emitterDirection: IVector3D; + + constructor(name: string = '', spriteId: number = -1) + { + super(); + + this._particles = []; + this._name = name; + this._roomObjectSpriteId = spriteId; + this._particleConfigurations = []; + } + + public dispose(): void + { + for(const k of this._particles) k.dispose(); + + this._particles = null; + this._particleConfigurations = null; + + super.dispose(); + } + + public setup(maxNumOfParticles: number, particlesPerFrame: number, force: number, direction: IVector3D, gravity: number, airFriction: number, explosionShape: string, energy: number, fuseTime: number, burstPulse: number): void + { + this._maxNumberOfParticles = maxNumOfParticles; + this._particlesPerFrame = particlesPerFrame; + this._force = force; + this._emitterDirection = direction; + this._emitterDirection.normalize(); + this._gravity = gravity; + this._airFriction = airFriction; + this._explosionShape = explosionShape; + this._fuseTime = fuseTime; + this._energy = energy; + this._burstPulse = burstPulse; + this.reset(); + } + + public reset(): void + { + for(const particle of this._particles) particle.dispose(); + + this._particles = []; + this._emittedParticles = 0; + this._hasIgnited = false; + + this.init(0, 0, 0, this._emitterDirection, this._force, this._timeStep, this._fuseTime, true); + } + + public copyStateFrom(emitter: FurnitureParticleSystemEmitter, scale: number): void + { + super.copy(emitter, scale); + + this._force = emitter._force; + this._emitterDirection = emitter._emitterDirection; + this._gravity = emitter._gravity; + this._airFriction = emitter._airFriction; + this._explosionShape = emitter._explosionShape; + this._fuseTime = emitter._fuseTime; + this._energy = emitter._energy; + this._burstPulse = emitter._burstPulse; + this._timeStep = emitter._timeStep; + this._hasIgnited = emitter._hasIgnited; + } + + public configureParticle(lifeTIme: number, isEmitter: boolean, frames: IGraphicAsset[], fade: boolean): void + { + const particle: ParticleSystemParticle = {}; + + particle.lifeTime = lifeTIme; + particle.isEmitter = isEmitter; + particle.frames = frames; + particle.fade = fade; + + this._particleConfigurations.push(particle); + } + + protected ignite(): void + { + this._hasIgnited = true; + + if(this._emittedParticles < this._maxNumberOfParticles) + { + if(this.age > 1) this.releaseParticles(this, this.direction); + } + } + + private releaseParticles(particle: FurnitureParticleSystemParticle, direction: IVector3D = null): void + { + if(!direction) direction = new Vector3d(); + + const newDirection = new Vector3d(); + const randomParticle = this.getRandomParticleConfiguration(); + + let i = 0; + + while(i < this._particlesPerFrame) + { + switch(this._explosionShape) + { + case FurnitureParticleSystemEmitter.CONE: + newDirection.x = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random())); + newDirection.y = -(Math.random() + 1); + newDirection.z = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random())); + break; + case FurnitureParticleSystemEmitter.PLANE: + newDirection.x = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random())); + newDirection.y = 0; + newDirection.z = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random())); + break; + case FurnitureParticleSystemEmitter.SPHERE: + newDirection.x = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random())); + newDirection.y = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random())); + newDirection.z = ((this.randomBoolean(0.5)) ? Math.random() : -(Math.random())); + break; + } + + newDirection.normalize(); + + const newParticle = new FurnitureParticleSystemParticle(); + + let lifeTime = 0; + let isEmitter = false; + let fade = false; + let frames: IGraphicAsset[] = []; + + if(randomParticle) + { + lifeTime = Math.floor(((Math.random() * randomParticle.lifeTime) + 10)); + isEmitter = randomParticle.isEmitter; + frames = randomParticle.frames; + fade = randomParticle.fade; + } + else + { + lifeTime = Math.trunc(Math.floor(((Math.random() * 20) + 10))); + isEmitter = false; + frames = []; + } + + newParticle.init(particle.x, particle.y, particle.z, newDirection, this._energy, this._timeStep, lifeTime, isEmitter, frames, fade); + + this._particles.push(newParticle); + this._emittedParticles++; + + i++; + } + } + + private getRandomParticleConfiguration(): ParticleSystemParticle + { + const index: number = Math.trunc(Math.floor((Math.random() * this._particleConfigurations.length))); + + return this._particleConfigurations[index]; + } + + public update(): void + { + super.update(); + + this.accumulateForces(); + this.verlet(); + this.satisfyConstraints(); + + if(!this.isAlive && (this._emittedParticles < this._maxNumberOfParticles)) + { + if((this.age % this._burstPulse) === 0) this.releaseParticles(this, this.direction); + } + } + + public verlet(): void + { + if(this.isAlive || (this._emittedParticles < this._maxNumberOfParticles)) + { + const x = this.x; + const y = this.y; + const z = this.z; + + this.x = (((2 - this._airFriction) * this.x) - ((1 - this._airFriction) * this.lastX)); + this.y = ((((2 - this._airFriction) * this.y) - ((1 - this._airFriction) * this.lastY)) + ((this._gravity * this._timeStep) * this._timeStep)); + this.z = (((2 - this._airFriction) * this.z) - ((1 - this._airFriction) * this.lastZ)); + this.lastX = x; + this.lastY = y; + this.lastZ = z; + } + + const particles: FurnitureParticleSystemParticle[] = []; + + for(const particle of this._particles) + { + particle.update(); + + const x = particle.x; + const y = particle.y; + const z = particle.z; + particle.x = (((2 - this._airFriction) * particle.x) - ((1 - this._airFriction) * particle.lastX)); + particle.y = ((((2 - this._airFriction) * particle.y) - ((1 - this._airFriction) * particle.lastY)) + ((this._gravity * this._timeStep) * this._timeStep)); + particle.z = (((2 - this._airFriction) * particle.z) - ((1 - this._airFriction) * particle.lastZ)); + particle.lastX = x; + particle.lastY = y; + particle.lastZ = z; + + if((particle.y > 10) || !particle.isAlive) particles.push(particle); + } + + for(const particle of particles) + { + if(particle.isEmitter) + { + // + } + + this._particles.splice(this._particles.indexOf(particle), 1); + + particle.dispose(); + } + } + + private satisfyConstraints(): void + { + } + + private accumulateForces(): void + { + for(const k of this._particles) + { + // + } + } + + public get particles(): FurnitureParticleSystemParticle[] + { + return this._particles; + } + + public get hasIgnited(): boolean + { + return this._hasIgnited; + } + + private randomBoolean(k: number): boolean + { + return Math.random() < k; + } + + public get roomObjectSpriteId(): number + { + return this._roomObjectSpriteId; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureParticleSystemParticle.ts b/packages/room/src/object/visualization/furniture/FurnitureParticleSystemParticle.ts new file mode 100644 index 0000000..4620ce4 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureParticleSystemParticle.ts @@ -0,0 +1,196 @@ +import { IGraphicAsset, IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; + +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; + private _particleDirection: IVector3D; + private _age: number = 0; + private _lifeTime: number; + private _isEmitter: boolean = false; + private _fade: boolean = false; + private _fadeTime: number; + private _alphaMultiplier: number = 1; + private _frames: IGraphicAsset[]; + + public init(x: number, y: number, z: number, direction: IVector3D, energy: number, timeStep: number, lifeTime: number, isEmitter: boolean = false, frames: IGraphicAsset[] = null, fade: boolean = false): void + { + this._x = x; + this._y = y; + this._z = z; + this._particleDirection = new Vector3d(direction.x, direction.y, direction.z); + this._particleDirection.multiply(energy); + + this._lastX = (this._x - (this._particleDirection.x * timeStep)); + this._lastY = (this._y - (this._particleDirection.y * timeStep)); + this._lastZ = (this._z - (this._particleDirection.z * timeStep)); + this._age = 0; + this._hasMoved = false; + this._lifeTime = lifeTime; + this._isEmitter = isEmitter; + this._frames = frames; + this._fade = fade; + this._alphaMultiplier = 1; + this._fadeTime = (0.5 + (Math.random() * 0.5)); + } + + public dispose(): void + { + this._particleDirection = 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(): IGraphicAsset + { + 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(): IVector3D + { + return this._particleDirection; + } + + public get age(): number + { + return this._age; + } + + public get isEmitter(): boolean + { + return this._isEmitter; + } + + public get isAlive(): boolean + { + return this._age <= this._lifeTime; + } + + 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; + } + + public get lastX(): number + { + return this._lastX; + } + + public set lastX(y: number) + { + this._hasMoved = true; + this._lastX = y; + } + + public get lastY(): number + { + return this._lastY; + } + + public set lastY(k: number) + { + this._hasMoved = true; + this._lastY = k; + } + + public get lastZ(): number + { + return this._lastZ; + } + + public set lastZ(z: number) + { + this._hasMoved = true; + this._lastZ = z; + } + + public get hasMoved(): boolean + { + return this._hasMoved; + } + + public toString(): string + { + return [this._x, this._y, this._z].toString(); + } + + public copy(particle: FurnitureParticleSystemParticle, scale: number): void + { + this._x = (particle._x * scale); + this._y = (particle._y * scale); + this._z = (particle._z * scale); + this._lastX = (particle._lastX * scale); + this._lastY = (particle._lastY * scale); + this._lastZ = (particle._lastZ * scale); + this._hasMoved = particle.hasMoved; + this._particleDirection = particle._particleDirection; + this._age = particle._age; + this._lifeTime = particle._lifeTime; + this._isEmitter = particle._isEmitter; + this._fade = particle._fade; + this._fadeTime = particle._fadeTime; + this._alphaMultiplier = particle._alphaMultiplier; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurniturePartyBeamerVisualization.ts b/packages/room/src/object/visualization/furniture/FurniturePartyBeamerVisualization.ts new file mode 100644 index 0000000..12fbf26 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurniturePartyBeamerVisualization.ts @@ -0,0 +1,160 @@ +import { Point } from 'pixi.js'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurniturePartyBeamerVisualization extends FurnitureAnimatedVisualization +{ + private static UPDATE_INTERVAL: number = 2; + private static AREA_DIAMETER_SMALL: number = 15; + private static AREA_DIAMETER_LARGE: number = 31; + private static ANIM_SPEED_FAST: number = 2; + private static ANIM_SPEED_SLOW: number = 1; + + private _animPhaseIndex: number[]; + private _animDirectionIndex: number[]; + private _animSpeedIndex: number[]; + private _animFactorIndex: number[]; + private _animOffsetIndex: Point[]; + + constructor() + { + super(); + + this._animOffsetIndex = []; + } + + protected updateAnimation(scale: number): number + { + if(!this._animSpeedIndex) this.initItems(scale); + + let sprite = this.getSprite(2); + + if(sprite) this._animOffsetIndex[0] = this.getNewPoint(scale, 0); + + sprite = this.getSprite(3); + + if(sprite) this._animOffsetIndex[1] = this.getNewPoint(scale, 1); + + return super.updateAnimation(scale); + } + + private getNewPoint(scale: number, layerId: number): Point + { + let diameter = 0; + + let animationPhase: number = this._animPhaseIndex[layerId]; + let animationDirection: number = this._animDirectionIndex[layerId]; + + const animationSpeed: number = this._animSpeedIndex[layerId]; + const animationFactor: number = this._animFactorIndex[layerId]; + + let _local_7 = 1; + + if(scale == 32) + { + diameter = FurniturePartyBeamerVisualization.AREA_DIAMETER_SMALL; + _local_7 = 0.5; + } + else + { + diameter = FurniturePartyBeamerVisualization.AREA_DIAMETER_LARGE; + } + + const _local_9: number = (animationPhase + (animationDirection * animationSpeed)); + + if(Math.abs(_local_9) >= diameter) + { + if(animationDirection > 0) + { + animationPhase = (animationPhase - (_local_9 - diameter)); + } + else + { + animationPhase = (animationPhase + (-(diameter) - _local_9)); + } + + animationDirection = -(animationDirection); + + this._animDirectionIndex[layerId] = animationDirection; + } + + const _local_10: number = ((diameter - Math.abs(animationPhase)) * animationFactor); + + let _local_11: number = ((animationDirection * Math.sin(Math.abs((animationPhase / 4)))) * _local_10); + + if(animationDirection > 0) + { + _local_11 = (_local_11 - _local_10); + } + else + { + _local_11 = (_local_11 + _local_10); + } + + animationPhase = (animationPhase + ((animationDirection * animationSpeed) * _local_7)); + + this._animPhaseIndex[layerId] = animationPhase; + + if(Math.trunc(_local_11) == 0) this._animFactorIndex[layerId] = this.getRandomAmplitudeFactor(); + + return new Point(animationPhase, _local_11); + } + + private initItems(scale: number): void + { + let diameter: number; + + if(scale === 32) + { + diameter = FurniturePartyBeamerVisualization.AREA_DIAMETER_SMALL; + } + else + { + diameter = FurniturePartyBeamerVisualization.AREA_DIAMETER_LARGE; + } + + this._animPhaseIndex = []; + this._animPhaseIndex.push(((Math.random() * diameter) * 1.5)); + this._animPhaseIndex.push(((Math.random() * diameter) * 1.5)); + + this._animDirectionIndex = []; + this._animDirectionIndex.push(1); + this._animDirectionIndex.push(-1); + + this._animSpeedIndex = []; + this._animSpeedIndex.push(FurniturePartyBeamerVisualization.ANIM_SPEED_FAST); + this._animSpeedIndex.push(FurniturePartyBeamerVisualization.ANIM_SPEED_SLOW); + + this._animFactorIndex = []; + this._animFactorIndex.push(this.getRandomAmplitudeFactor()); + this._animFactorIndex.push(this.getRandomAmplitudeFactor()); + } + + protected getLayerXOffset(scale: number, direction: number, layerId: number): number + { + if((layerId === 2) || (layerId === 3)) + { + if(this._animOffsetIndex.length == 2) + { + return this._animOffsetIndex[(layerId - 2)].x; + } + } + return super.getLayerXOffset(scale, direction, layerId); + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + if((layerId === 2) || (layerId === 3)) + { + if(this._animOffsetIndex.length == 2) + { + return this._animOffsetIndex[(layerId - 2)].y; + } + } + return super.getLayerYOffset(scale, direction, layerId); + } + + private getRandomAmplitudeFactor(): number + { + return ((Math.random() * 30) / 100) + 0.15; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurniturePlanetSystemVisualization.ts b/packages/room/src/object/visualization/furniture/FurniturePlanetSystemVisualization.ts new file mode 100644 index 0000000..9386b9f --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurniturePlanetSystemVisualization.ts @@ -0,0 +1,134 @@ +import { IAssetLogicPlanetSystem, IVector3D, RoomObjectVariable } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; +import { FurniturePlanetSystemVisualizationPlanetObject } from './FurniturePlanetSystemVisualizationPlanetObject'; + +export class FurniturePlanetSystemVisualization extends FurnitureAnimatedVisualization +{ + private _planetIndex: FurniturePlanetSystemVisualizationPlanetObject[]; + private _planetNameIndex: string[]; + private _offsetArray: IVector3D[]; + private _rootPosition: IVector3D; + + constructor() + { + super(); + + this._offsetArray = []; + this._rootPosition = new Vector3d(); + } + + public dispose(): void + { + if(this._planetIndex) + { + while(this._planetIndex.length > 0) + { + const planet = this._planetIndex.shift(); + + planet.dispose(); + } + } + + this._planetIndex = null; + this._planetNameIndex = null; + } + + protected updateAnimation(scale: number): number + { + if(!this._planetIndex && (this.spriteCount > 0)) + { + if(!this.processPlanets()) return 0; + } + + if(this._planetIndex) + { + for(const planet of this._planetIndex) planet.update(this._offsetArray, this._rootPosition, scale); + + return super.updateAnimation(scale); + } + + return 0; + } + + protected getLayerXOffset(scale: number, direction: number, layerId: number): number + { + if(this._offsetArray[layerId]) + { + return this._offsetArray[layerId].x; + } + + return super.getLayerXOffset(scale, direction, layerId); + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + if(this._offsetArray[layerId]) + { + return this._offsetArray[layerId].y; + } + + return super.getLayerYOffset(scale, direction, layerId); + } + + protected getLayerZOffset(scale: number, direction: number, layerId: number): number + { + if(this._offsetArray[layerId]) + { + return this._offsetArray[layerId].z; + } + + return super.getLayerZOffset(scale, direction, layerId); + } + + private processPlanets(): boolean + { + if(!this.object || !this.object.model) return; + + const planetSystems = this.object.model.getValue(RoomObjectVariable.FURNITURE_PLANETSYSTEM_DATA); + + if(!planetSystems) return false; + + this._planetIndex = []; + this._planetNameIndex = []; + + for(const planet of planetSystems) + { + const sprite = this.getSprite(planet.id); + + if(sprite) + { + this.addPlanet(planet.name, planet.id, planet.parent, (planet.radius || 0), (planet.arcSpeed || 0), (planet.arcOffset || 0), (planet.height || 0)); + } + } + + return true; + } + + private addPlanet(name: string, index: number, parentName: string, radius: number, arcSpeed: number, arcOffset: number, height: number): void + { + if(!this._planetIndex) return; + + const planet = new FurniturePlanetSystemVisualizationPlanetObject(name, index, radius, arcSpeed, arcOffset, height); + const existingPlanet = this.getPlanet(parentName); + + if(existingPlanet) existingPlanet.addChild(planet); + else + { + this._planetIndex.push(planet); + this._planetNameIndex.push(name); + } + } + + private getPlanet(name: string): FurniturePlanetSystemVisualizationPlanetObject + { + for(const planet of this._planetIndex) + { + if(planet.name === name) return planet; + + if(planet.hasChild(name)) return planet.getChild(name); + } + + return null; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurniturePlanetSystemVisualizationPlanetObject.ts b/packages/room/src/object/visualization/furniture/FurniturePlanetSystemVisualizationPlanetObject.ts new file mode 100644 index 0000000..3c5187c --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurniturePlanetSystemVisualizationPlanetObject.ts @@ -0,0 +1,92 @@ +import { IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; + +export class FurniturePlanetSystemVisualizationPlanetObject +{ + private static SYSTEM_TEMPO: number = 30; + + private _name: string; + private _index: number; + private _radius: number; + private _arcSpeed: number; + private _arcOffset: number; + private _height: number; + private _position: number; + private _positionVector: IVector3D; + private _children: FurniturePlanetSystemVisualizationPlanetObject[]; + + constructor(name: string, index: number, radius: number, arcSpeed: number, arcOffset: number, height: number) + { + this._name = name; + this._index = index; + this._radius = radius; + this._arcSpeed = (((arcSpeed * Math.PI) * 2) / 360); + this._arcOffset = (((arcOffset * Math.PI) * 2) / 360); + this._height = height; + this._position = 0; + this._positionVector = new Vector3d(0, 0, 0); + this._children = []; + } + + public dispose(): void + { + while(this._children.length > 0) + { + const child = this._children.shift(); + + child.dispose(); + } + } + + public update(offsets: IVector3D[], rootPosition: IVector3D, scale: number): void + { + this._position = (this._position + (this._arcSpeed / FurniturePlanetSystemVisualizationPlanetObject.SYSTEM_TEMPO)); + + offsets[this._index] = this.getPositionVector(rootPosition, scale); + + for(const child of this._children) child.update(offsets, this._positionVector, scale); + } + + public getPositionVector(position: IVector3D, scale: number): IVector3D + { + const cos = (this._radius * Math.cos((this._position + this._arcOffset))); + const sine = (this._radius * Math.sin((this._position + this._arcOffset))); + + this._positionVector.x = ((cos - sine) * (scale / 2)); + this._positionVector.y = ((((sine + cos) * (scale / 2)) * 0.5) - (this._height * (scale / 2))); + this._positionVector.z = -(Math.trunc(((4 * (cos + sine)) - 0.7))); + + if(position) this._positionVector.add(position); + + return this._positionVector; + } + + public addChild(planetObject: FurniturePlanetSystemVisualizationPlanetObject): void + { + if(this._children.indexOf(planetObject) >= 0) return; + + this._children.push(planetObject); + } + + public hasChild(name: string): boolean + { + return !!this.getChild(name); + } + + public getChild(name: string): FurniturePlanetSystemVisualizationPlanetObject + { + for(const child of this._children) + { + if(child.name === name) return child; + + if(child.hasChild(name)) return child.getChild(name); + } + + return null; + } + + public get name(): string + { + return this._name; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurniturePosterVisualization.ts b/packages/room/src/object/visualization/furniture/FurniturePosterVisualization.ts new file mode 100644 index 0000000..6bfadc4 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurniturePosterVisualization.ts @@ -0,0 +1,6 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurniturePosterVisualization extends FurnitureAnimatedVisualization +{ + +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureQueueTileVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureQueueTileVisualization.ts new file mode 100644 index 0000000..9a1e5de --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureQueueTileVisualization.ts @@ -0,0 +1,50 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureQueueTileVisualization extends FurnitureAnimatedVisualization +{ + private static ANIMATION_ID_ROLL: number = 3; + private static ANIMATION_ID_ROLL_ONCE: number = 2; + private static ANIMATION_ID_NORMAL: number = 1; + private static ANIMATION_DURATION: number = 15; + + private _stateQueue: number[]; + private _animationCounter: number; + + constructor() + { + super(); + + this._stateQueue = []; + this._animationCounter = -1; + } + + protected setAnimation(animationId: number): void + { + if(animationId === FurnitureQueueTileVisualization.ANIMATION_ID_ROLL_ONCE) + { + this._stateQueue = []; + this._stateQueue.push(FurnitureQueueTileVisualization.ANIMATION_ID_NORMAL); + + this._animationCounter = FurnitureQueueTileVisualization.ANIMATION_DURATION; + } + + 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; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureResettingAnimatedVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureResettingAnimatedVisualization.ts new file mode 100644 index 0000000..dd191e9 --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/furniture/FurnitureRoomBackgroundVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureRoomBackgroundVisualization.ts new file mode 100644 index 0000000..895b985 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureRoomBackgroundVisualization.ts @@ -0,0 +1,64 @@ +import { Texture } from 'pixi.js'; +import { DirectionalOffsetData } from '../data'; +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)); + } + + protected getLayerIgnoreMouse(scale: number, direction: number, layerId: number): boolean + { + return true; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureScoreBoardVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureScoreBoardVisualization.ts new file mode 100644 index 0000000..0ec747e --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/furniture/FurnitureSoundBlockVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureSoundBlockVisualization.ts new file mode 100644 index 0000000..1268e7c --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureSoundBlockVisualization.ts @@ -0,0 +1,16 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureSoundBlockVisualization extends FurnitureAnimatedVisualization +{ + private _internalFrameIncreaseCounter: number = 0; + + protected updateAnimations(scale: number): number + { + this._internalFrameIncreaseCounter = (this._internalFrameIncreaseCounter + this.object.model.getValue(RoomObjectVariable.FURNITURE_SOUNDBLOCK_RELATIVE_ANIMATION_SPEED)); + this._frameIncrease = this._internalFrameIncreaseCounter; + this._internalFrameIncreaseCounter = (this._internalFrameIncreaseCounter - this._frameIncrease); + + return super.updateAnimations(scale); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureStickieVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureStickieVisualization.ts new file mode 100644 index 0000000..29cfca3 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureStickieVisualization.ts @@ -0,0 +1,12 @@ +import { ColorData } from '../data'; +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); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureValRandomizerVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureValRandomizerVisualization.ts new file mode 100644 index 0000000..b95769c --- /dev/null +++ b/packages/room/src/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 ANIMATION_ID_START_ROLL: number = 31; + private static ANIMATION_ID_ROLL: number = 32; + private static ANIMATION_ID_OFF: number = 30; + + private _stateQueue: number[]; + private _running: boolean; + + constructor() + { + super(); + + this._stateQueue = []; + this._running = false; + + super.setAnimation(FurnitureValRandomizerVisualization.ANIMATION_ID_OFF); + } + + protected setAnimation(animationId: number): void + { + if(animationId === 0) + { + if(!this._running) + { + this._running = true; + this._stateQueue = []; + + this._stateQueue.push(FurnitureValRandomizerVisualization.ANIMATION_ID_START_ROLL); + this._stateQueue.push(FurnitureValRandomizerVisualization.ANIMATION_ID_ROLL); + + 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.ANIMATION_ID_OFF); + + return; + } + + super.setAnimation(FurnitureValRandomizerVisualization.ANIMATION_ID_OFF); + } + } + + protected updateAnimation(scale: number): number + { + if(this.getLastFramePlayed(11)) + { + if(this._stateQueue.length) super.setAnimation(this._stateQueue.shift()); + } + + return super.updateAnimation(scale); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureVisualization.ts new file mode 100644 index 0000000..12c022e --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureVisualization.ts @@ -0,0 +1,594 @@ +import { AlphaTolerance, IGraphicAsset, IObjectVisualizationData, IRoomGeometry, IRoomObjectSprite, RoomObjectVariable, RoomObjectVisualizationType } from '@nitrots/api'; +import { BLEND_MODES, Texture } from 'pixi.js'; +import { RoomObjectSpriteVisualization } from '../RoomObjectSpriteVisualization'; +import { ColorData, LayerData } from '../data'; +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 _clickHandling: boolean; + + 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 _spriteBlendModes: BLEND_MODES[]; + 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._clickHandling = false; + + this._cacheDirection = -1; + this._cacheScale = 0; + this._cacheSize = -1; + + this._layerCount = 0; + this._shadowLayerIndex = -1; + this._updatedLayers = []; + this._assetNames = []; + this._spriteTags = []; + this._spriteBlendModes = []; + 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._spriteBlendModes = 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._spriteBlendModes = []; + this._spriteAlphas = []; + this._spriteColors = []; + this._spriteMouseCaptures = []; + this._spriteXOffsets = []; + this._spriteYOffsets = []; + this._spriteZOffsets = []; + + this.createSprites(0); + } + + protected resetLayers(scale: number, direction: number): void + { + if((this._cacheDirection === direction) && (this._cacheScale === scale)) return; + + this._updatedLayers = []; + this._assetNames = []; + this._spriteTags = []; + this._spriteBlendModes = []; + 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._clickHandling = ((this._clickUrl && (this._clickUrl !== '') && (this._clickUrl.indexOf('http') === 0)) || false); + 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.createSprites(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) + { + sprite.visible = true; + sprite.type = this._type; + sprite.texture = this.getTexture(scale, layerId, assetData); + 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.getLayerBlendMode(scale, this._direction, layerId); + sprite.alphaTolerance = (this.getLayerIgnoreMouse(scale, this._direction, layerId) ? AlphaTolerance.MATCH_NOTHING : AlphaTolerance.MATCH_OPAQUE_PIXELS); + + 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.MATCH_NOTHING; + + relativeDepth = 1; + } + + sprite.relativeDepth = (relativeDepth * FurnitureVisualization.DEPTH_MULTIPLIER); + sprite.name = assetName; + sprite.libraryAssetName = this.getLibraryAssetNameForSprite(assetData, sprite); + sprite.posture = this.getPostureForAsset(scale, assetData.source); + sprite.clickHandling = this._clickHandling; + } + 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.libraryAssetName = ''; + sprite.posture = ''; + sprite.tag = ''; + sprite.offsetX = 0; + sprite.offsetY = 0; + sprite.flipH = false; + sprite.flipV = false; + sprite.relativeDepth = 0; + sprite.clickHandling = false; + } + + 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 getLayerBlendMode(scale: number, direction: number, layerId: number): BLEND_MODES + { + const existing = this._spriteBlendModes[layerId]; + + if(existing !== undefined) return existing; + + if(!this._data) return LayerData.DEFAULT_BLEND_MODE; + + const blendMode = this._data.getLayerBlendMode(scale, direction, layerId); + + this._spriteBlendModes[layerId] = blendMode; + + return blendMode; + } + + 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 * (scale / 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); + } + + public getTexture(scale: number, layerId: number, asset: IGraphicAsset): Texture + { + return asset?.texture ?? null; + } + + protected get direction(): number + { + return this._direction; + } + + protected get data(): FurnitureVisualizationData + { + return this._data; + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureVisualizationData.ts b/packages/room/src/object/visualization/furniture/FurnitureVisualizationData.ts new file mode 100644 index 0000000..e64004d --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureVisualizationData.ts @@ -0,0 +1,281 @@ +import { IAssetData, IAssetVisualizationData, IObjectVisualizationData } from '@nitrots/api'; +import { BLEND_MODES } from 'pixi.js'; +import { ColorData, LayerData, SizeData } from '../data'; + +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 = new Map(); + private _lastSize: number = -1; + private _lastSizeScale: number = -1; + private _lastSizeData: SizeData = null; + private _lastSizeDataScale: number = -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 getLayerBlendMode(scale: number, direction: number, layerId: number): BLEND_MODES + { + const size = this.getSizeData(scale); + + if(!size) return LayerData.DEFAULT_BLEND_MODE; + + return size.getLayerBlendMode(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/packages/room/src/object/visualization/furniture/FurnitureVoteCounterVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureVoteCounterVisualization.ts new file mode 100644 index 0000000..de34e4d --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureVoteCounterVisualization.ts @@ -0,0 +1,51 @@ +import { RoomObjectVariable } from '@nitrots/api'; +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 HIDE_COUNTER_SCORE: 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.HIDE_COUNTER_SCORE) + { + 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); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureVoteMajorityVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureVoteMajorityVisualization.ts new file mode 100644 index 0000000..17030b5 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureVoteMajorityVisualization.ts @@ -0,0 +1,45 @@ +import { RoomObjectVariable } from '@nitrots/api'; +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 HIDE_RESULTS_STATES: number[] = [-1, 1]; + private static HIDE_RESULTS_VALUE: 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.HIDE_RESULTS_STATES.indexOf(this.object.getState(0)) === -1)) || (result === FurnitureVoteMajorityVisualization.HIDE_RESULTS_VALUE))) + { + 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); + } +} diff --git a/packages/room/src/object/visualization/furniture/FurnitureWaterAreaVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureWaterAreaVisualization.ts new file mode 100644 index 0000000..c40f65c --- /dev/null +++ b/packages/room/src/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/packages/room/src/object/visualization/furniture/FurnitureYoutubeVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureYoutubeVisualization.ts new file mode 100644 index 0000000..1b1a544 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/FurnitureYoutubeVisualization.ts @@ -0,0 +1,18 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { FurnitureDynamicThumbnailVisualization } from './FurnitureDynamicThumbnailVisualization'; + +export class FurnitureYoutubeVisualization extends FurnitureDynamicThumbnailVisualization +{ + protected static THUMBNAIL_URL: string = 'THUMBNAIL_URL'; + + protected getThumbnailURL(): string + { + if(!this.object) return null; + + const furnitureData = this.object.model.getValue<{ [index: string]: string }>(RoomObjectVariable.FURNITURE_DATA); + + if(furnitureData) return (furnitureData[FurnitureYoutubeVisualization.THUMBNAIL_URL] || null); + + return null; + } +} diff --git a/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts b/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts new file mode 100644 index 0000000..2504825 --- /dev/null +++ b/packages/room/src/object/visualization/furniture/IsometricImageFurniVisualization.ts @@ -0,0 +1,172 @@ +import { IGraphicAsset } from '@nitrots/api'; +import { TextureUtils } from '@nitrots/utils'; +import { Matrix, Sprite, Texture } from 'pixi.js'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class IsometricImageFurniVisualization extends FurnitureAnimatedVisualization +{ + protected static THUMBNAIL: string = 'THUMBNAIL'; + + private _thumbnailAssetNameNormal: string; + private _thumbnailImageNormal: Texture; + private _thumbnailDirection: number; + private _thumbnailChanged: boolean; + protected _hasOutline: boolean; + + constructor() + { + super(); + + this._thumbnailAssetNameNormal = null; + this._thumbnailImageNormal = null; + this._thumbnailDirection = -1; + this._thumbnailChanged = false; + this._hasOutline = false; + } + + public get hasThumbnailImage(): boolean + { + return !(this._thumbnailImageNormal == null); + } + + public setThumbnailImages(k: Texture): void + { + this._thumbnailImageNormal = k; + this._thumbnailChanged = true; + } + + protected updateModel(scale: number): boolean + { + const flag = super.updateModel(scale); + + if(!this._thumbnailChanged && (this._thumbnailDirection === this.direction)) return flag; + + this.refreshThumbnail(); + + return true; + } + + private refreshThumbnail(): void + { + if(this.asset == null) return; + + if(this._thumbnailImageNormal) + { + this.addThumbnailAsset(this._thumbnailImageNormal, 64); + } + else + { + this.asset.disposeAsset(this.getThumbnailAssetName(64)); + } + + this._thumbnailChanged = false; + this._thumbnailDirection = this.direction; + } + + private addThumbnailAsset(k: Texture, scale: number): void + { + let layerId = 0; + + while(layerId < this.totalSprites) + { + if(this.getLayerTag(scale, this.direction, layerId) === IsometricImageFurniVisualization.THUMBNAIL) + { + const assetName = (this.cacheSpriteAssetName(scale, layerId, false) + this.getFrameNumber(scale, layerId)); + const asset = this.getAsset(assetName, layerId); + + if(asset) + { + const _local_6 = this.generateTransformedThumbnail(k, asset); + const _local_7 = this.getThumbnailAssetName(scale); + + this.asset.disposeAsset(_local_7); + this.asset.addAsset(_local_7, _local_6, true, asset.offsetX, asset.offsetY, false, false); + } + + return; + } + + layerId++; + } + } + + protected generateTransformedThumbnail(texture: Texture, asset: IGraphicAsset): Texture + { + if(this._hasOutline) + { + const container = new Sprite(); + const background = new Sprite(Texture.WHITE); + + background.tint = 0x000000; + background.width = (texture.width + 40); + background.height = (texture.height + 40); + + const sprite = new Sprite(texture); + const offsetX = ((background.width - sprite.width) / 2); + const offsetY = ((background.height - sprite.height) / 2); + + sprite.position.set(offsetX, offsetY); + + container.addChild(background, sprite); + + texture = TextureUtils.generateTexture(container); + } + + const scale = 1.1; + const matrix = new Matrix(); + const difference = (asset.width / texture.width); + + switch(this.direction) + { + case 2: + matrix.a = difference; + matrix.b = (-0.5 * difference); + matrix.c = 0; + matrix.d = (difference * scale); + matrix.tx = 0; + matrix.ty = ((0.5 * difference) * texture.width); + break; + case 0: + case 4: + matrix.a = difference; + matrix.b = (0.5 * difference); + matrix.c = 0; + matrix.d = (difference * scale); + matrix.tx = 0; + matrix.ty = 0; + break; + default: + matrix.a = difference; + matrix.b = 0; + matrix.c = 0; + matrix.d = difference; + matrix.tx = 0; + matrix.ty = 0; + } + + const sprite = new Sprite(texture); + + sprite.setFromMatrix(matrix); + + return TextureUtils.generateTexture(sprite); + } + + protected getSpriteAssetName(scale: number, layerId: number): string + { + if(this._thumbnailImageNormal && (this.getLayerTag(scale, this.direction, layerId) === IsometricImageFurniVisualization.THUMBNAIL)) return this.getThumbnailAssetName(scale); + + return super.getSpriteAssetName(scale, layerId); + } + + protected getThumbnailAssetName(scale: number): string + { + this._thumbnailAssetNameNormal = this.getFullThumbnailAssetName(this.object.id, 64); + + return this._thumbnailAssetNameNormal; + } + + protected getFullThumbnailAssetName(k: number, _arg_2: number): string + { + return [this._type, k, 'thumb', _arg_2].join('_'); + } +} diff --git a/packages/room/src/object/visualization/furniture/index.ts b/packages/room/src/object/visualization/furniture/index.ts new file mode 100644 index 0000000..9c96d0f --- /dev/null +++ b/packages/room/src/object/visualization/furniture/index.ts @@ -0,0 +1,41 @@ +export * from './FurnitureAnimatedVisualization'; +export * from './FurnitureAnimatedVisualizationData'; +export * from './FurnitureBBVisualization'; +export * from './FurnitureBadgeDisplayVisualization'; +export * from './FurnitureBottleVisualization'; +export * from './FurnitureBrandedImageVisualization'; +export * from './FurnitureBuilderPlaceholderVisualization'; +export * from './FurnitureCounterClockVisualization'; +export * from './FurnitureCuboidVisualization'; +export * from './FurnitureDynamicThumbnailVisualization'; +export * from './FurnitureExternalImageVisualization'; +export * from './FurnitureFireworksVisualization'; +export * from './FurnitureGiftWrappedFireworksVisualization'; +export * from './FurnitureGiftWrappedVisualization'; +export * from './FurnitureGuildCustomizedVisualization'; +export * from './FurnitureGuildIsometricBadgeVisualization'; +export * from './FurnitureHabboWheelVisualization'; +export * from './FurnitureIsometricBBVisualization'; +export * from './FurnitureMannequinVisualization'; +export * from './FurnitureMannequinVisualizationData'; +export * from './FurnitureParticleSystem'; +export * from './FurnitureParticleSystemEmitter'; +export * from './FurnitureParticleSystemParticle'; +export * from './FurniturePartyBeamerVisualization'; +export * from './FurniturePlanetSystemVisualization'; +export * from './FurniturePlanetSystemVisualizationPlanetObject'; +export * from './FurniturePosterVisualization'; +export * from './FurnitureQueueTileVisualization'; +export * from './FurnitureResettingAnimatedVisualization'; +export * from './FurnitureRoomBackgroundVisualization'; +export * from './FurnitureScoreBoardVisualization'; +export * from './FurnitureSoundBlockVisualization'; +export * from './FurnitureStickieVisualization'; +export * from './FurnitureValRandomizerVisualization'; +export * from './FurnitureVisualization'; +export * from './FurnitureVisualizationData'; +export * from './FurnitureVoteCounterVisualization'; +export * from './FurnitureVoteMajorityVisualization'; +export * from './FurnitureWaterAreaVisualization'; +export * from './FurnitureYoutubeVisualization'; +export * from './IsometricImageFurniVisualization'; diff --git a/packages/room/src/object/visualization/index.ts b/packages/room/src/object/visualization/index.ts new file mode 100644 index 0000000..a7fd77a --- /dev/null +++ b/packages/room/src/object/visualization/index.ts @@ -0,0 +1,10 @@ +export * from './RoomObjectSprite'; +export * from './RoomObjectSpriteVisualization'; +export * from './avatar'; +export * from './avatar/additions'; +export * from './data'; +export * from './furniture'; +export * from './pet'; +export * from './room'; +export * from './room/mask'; +export * from './room/utils'; diff --git a/packages/room/src/object/visualization/pet/ExperienceData.ts b/packages/room/src/object/visualization/pet/ExperienceData.ts new file mode 100644 index 0000000..6c9ac44 --- /dev/null +++ b/packages/room/src/object/visualization/pet/ExperienceData.ts @@ -0,0 +1,75 @@ +import { TextureUtils } from '@nitrots/utils'; +import { Container, Sprite, Text, TextStyle, Texture } from 'pixi.js'; + +export class ExperienceData +{ + private _sprite: Sprite; + private _texture: Texture; + private _amount: number; + private _alpha: number; + + constructor(texture: Texture) + { + this._sprite = new Sprite(texture); + this._texture = null; + this._amount = -1; + this._alpha = 0; + } + + public renderBubble(amount: number): Texture + { + if(!this._sprite || (this._amount === amount)) return null; + + const container = new Container(); + + container.addChild(this._sprite); + + const text = new Text({ + text: ('+' + amount), + style: new TextStyle({ + fontFamily: 'Arial', + fontSize: 9, + fill: 0xFFFFFF, + align: 'center' + }) + }); + + text.anchor.x = 0.5; + + text.x = (this._sprite.width / 2); + text.y = 19; + + container.addChild(text); + + if(!this._texture) + { + this._texture = TextureUtils.generateTexture(container); + } + else + { + TextureUtils.writeToTexture(container, this._texture, true); + } + + return this._texture; + } + + public get amount(): number + { + return this._amount; + } + + public set amount(amount: number) + { + this._amount = amount; + } + + public get alpha(): number + { + return this._alpha; + } + + public set alpha(alpha: number) + { + this._alpha = alpha; + } +} diff --git a/packages/room/src/object/visualization/pet/PetVisualization.ts b/packages/room/src/object/visualization/pet/PetVisualization.ts new file mode 100644 index 0000000..879c922 --- /dev/null +++ b/packages/room/src/object/visualization/pet/PetVisualization.ts @@ -0,0 +1,594 @@ +import { IGraphicAsset, IObjectVisualizationData, IRoomGeometry, RoomObjectVariable, RoomObjectVisualizationType } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { AnimationData, AnimationStateData, DirectionData, LayerData } from '../data'; +import { FurnitureAnimatedVisualization, FurnitureVisualizationData } from '../furniture'; +import { ExperienceData } from './ExperienceData'; +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 ADDITIONAL_SPRITE_COUNT: number = 1; + private static EXPERIENCE_BUBBLE_VISIBLE_IN_MS: number = 1000; + private static PET_EXPERIENCE_BUBBLE: string = 'avatar_addition_pet_experience_bubble'; + private static POSTURE_ANIMATION_INDEX: number = 0; + private static GESTURE_ANIMATION_INDEX: number = 1; + private static ANIMATION_INDEX_COUNT: number = 2; + + 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 _experience: number; + private _experienceTimestamp: number; + private _experienceData: ExperienceData; + + private _previousAnimationDirection: number; + private _animationStates: AnimationStateData[]; + + constructor() + { + super(); + + 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._experience = 0; + this._experienceTimestamp = 0; + this._experienceData = null; + + this._previousAnimationDirection = -1; + this._animationStates = []; + + while(this._animationStates.length < PetVisualization.ANIMATION_INDEX_COUNT) this._animationStates.push(new AnimationStateData()); + } + + public initialize(data: IObjectVisualizationData): boolean + { + if(!(data instanceof PetVisualizationData)) return false; + + const texture = GetAssetManager().getTexture(PetVisualization.PET_EXPERIENCE_BUBBLE); + + if(texture) + { + this._experienceData = new ExperienceData(texture); + } + + 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); + + this.updateExperienceBubble(time); + } + + protected updateExperienceBubble(time: number): void + { + if(!this._experienceData) return; + + this._experienceData.alpha = 0; + + if(this._experienceTimestamp) + { + const difference = (time - this._experienceTimestamp); + + if(difference < PetVisualization.EXPERIENCE_BUBBLE_VISIBLE_IN_MS) + { + this._experienceData.alpha = (Math.sin(((difference / PetVisualization.EXPERIENCE_BUBBLE_VISIBLE_IN_MS) * Math.PI)) * 0xFF); + } + else + { + this._experienceTimestamp = 0; + } + + const sprite = this.getSprite((this.totalSprites - 1)); + + if(sprite) + { + if(this._experienceData.alpha > 0) + { + const texture = this._experienceData.renderBubble(this._experience); + + if(texture) + { + sprite.texture = texture; + sprite.offsetX = -20; + sprite.offsetY = -80; + sprite.alpha = this._experienceData.alpha; + sprite.visible = true; + sprite.relativeDepth = -0.2; + + return; + } + } + + sprite.texture = null; + sprite.visible = false; + } + } + } + + protected updateModel(scale: number): boolean + { + const model = this.object && this.object.model; + + if(!model) return false; + + if(this.updateModelCounter === model.updateCounter) return false; + + const posture = model.getValue(RoomObjectVariable.FIGURE_POSTURE); + const gesture = model.getValue(RoomObjectVariable.FIGURE_GESTURE); + + 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; + } + + this._experience = (model.getValue(RoomObjectVariable.FIGURE_GAINED_EXPERIENCE)); + this._experienceTimestamp = (model.getValue(RoomObjectVariable.FIGURE_EXPERIENCE_TIMESTAMP)); + + 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(!this.data) return; + + if(posture !== this._posture) + { + this._posture = posture; + + this.setAnimationForIndex(PetVisualization.POSTURE_ANIMATION_INDEX, this.data.postureToAnimation(this._scale, posture)); + } + + if(this.data.getGestureDisabled(this._scale, posture)) gesture = null; + + if(gesture !== this._gesture) + { + this._gesture = gesture; + + this.setAnimationForIndex(PetVisualization.GESTURE_ANIMATION_INDEX, this.data.gestureToAnimation(this._scale, gesture)); + } + } + + private getAnimationStateData(k: number): AnimationStateData + { + if((k >= 0) && (k < this._animationStates.length)) return this._animationStates[k]; + + return null; + } + + private setAnimationForIndex(k: number, _arg_2: number): void + { + const animationStateData = this.getAnimationStateData(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.setAnimationForIndex(index, stateData.animationAfterTransitionId); + + animationOver = false; + } + } + } + } + + index++; + } + + this._animationOver = animationOver; + + return _local_3; + } + + protected getSpriteAssetName(scale: number, layerId: number): string + { + if(this._headOnly && this.isNonHeadSprite(layerId)) return null; + + if(this._isRiding && this._parser3(layerId)) return null; + + const totalSprites = this.totalSprites; + + if(layerId < (totalSprites - PetVisualization.ADDITIONAL_SPRITE_COUNT)) + { + const validScale = this.getValidSize(scale); + + if(layerId < (totalSprites - (1 + PetVisualization.ADDITIONAL_SPRITE_COUNT))) + { + 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.ADDITIONAL_SPRITE_COUNT)) 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.isHeadSprite(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 isHeadSprite(layerId: number): boolean + { + if(this._headSprites[layerId] === undefined) + { + const isHead = (this.data.getLayerTag(this._scale, DirectionData.USE_DEFAULT_DIRECTION, layerId) === PetVisualization.HEAD); + const isHair = (this.data.getLayerTag(this._scale, DirectionData.USE_DEFAULT_DIRECTION, layerId) === PetVisualization.HAIR); + + if(isHead || isHair) this._headSprites[layerId] = true; + else this._headSprites[layerId] = false; + } + + return this._headSprites[layerId]; + } + + private isNonHeadSprite(layerId: number): boolean + { + if(this._nonHeadSprites[layerId] === undefined) + { + if(layerId < (this.totalSprites - (1 + PetVisualization.ADDITIONAL_SPRITE_COUNT))) + { + const tag = this.data.getLayerTag(this._scale, DirectionData.USE_DEFAULT_DIRECTION, 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.USE_DEFAULT_DIRECTION, 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.ADDITIONAL_SPRITE_COUNT; + } + + 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.animationToPosture(scale, (parseInt(part) / 100), false); + + if(!posture) posture = this.data.getGestureForAnimationId(scale, (parseInt(part) / 100)); + } + + return posture; + } + + protected get data(): PetVisualizationData + { + return this._data as PetVisualizationData; + } +} diff --git a/packages/room/src/object/visualization/pet/PetVisualizationData.ts b/packages/room/src/object/visualization/pet/PetVisualizationData.ts new file mode 100644 index 0000000..5f0a801 --- /dev/null +++ b/packages/room/src/object/visualization/pet/PetVisualizationData.ts @@ -0,0 +1,125 @@ +import { IAssetVisualizationData } from '@nitrots/api'; +import { AnimationSizeData, PetSizeData, SizeData } from '../data'; +import { FurnitureAnimatedVisualizationData } from '../furniture'; + +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 getGestureDisabled(scale: number, posture: string): boolean + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return false; + + return size.getGestureDisabled(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 animationToPosture(scale: number, index: number, useDefault: boolean): string + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return null; + + return size.animationToPosture(index, useDefault); + } + + public animationToGesture(scale: number, index: number): string + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return null; + + return size.animationToGesture(index); + } + + public getGestureForAnimationId(scale: number, _arg_2: number): string + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return null; + + return size.getGestureForAnimationId(_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/packages/room/src/object/visualization/pet/index.ts b/packages/room/src/object/visualization/pet/index.ts new file mode 100644 index 0000000..02a6ab3 --- /dev/null +++ b/packages/room/src/object/visualization/pet/index.ts @@ -0,0 +1,3 @@ +export * from './ExperienceData'; +export * from './PetVisualization'; +export * from './PetVisualizationData'; diff --git a/packages/room/src/object/visualization/room/PlaneDrawingData.ts b/packages/room/src/object/visualization/room/PlaneDrawingData.ts new file mode 100644 index 0000000..861712a --- /dev/null +++ b/packages/room/src/object/visualization/room/PlaneDrawingData.ts @@ -0,0 +1,103 @@ +import { IPlaneDrawingData } from '@nitrots/api'; +import { Point } from 'pixi.js'; + +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 addAssetColumn(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 maskAssetNames(): string[] + { + return this._maskAssetNames; + } + + public get maskAssetLocations(): Point[] + { + return this._maskAssetLocations; + } + + public get maskAssetFlipHs(): boolean[] + { + return this._maskAssetFlipHs; + } + + public get maskAssetFlipVs(): boolean[] + { + return this._maskAssetFlipVs; + } + + public isBottomAligned(): boolean + { + return this._alignBottom; + } + + public get assetNameColumns(): string[][] + { + return this._assetNames; + } +} diff --git a/packages/room/src/object/visualization/room/RoomPlane.ts b/packages/room/src/object/visualization/room/RoomPlane.ts new file mode 100644 index 0000000..3feaa5e --- /dev/null +++ b/packages/room/src/object/visualization/room/RoomPlane.ts @@ -0,0 +1,636 @@ +import { IAssetPlaneVisualizationLayer, IAssetRoomVisualizationData, IRoomGeometry, IRoomPlane, IVector3D } from '@nitrots/api'; +import { GetAssetManager } from '@nitrots/assets'; +import { GetRenderer, GetTexturePool, PlaneMaskFilter, Vector3d } from '@nitrots/utils'; +import { Container, Filter, Matrix, Point, Sprite, Texture, TilingSprite } from 'pixi.js'; +import { RoomGeometry } from '../../../utils'; +import { RoomPlaneBitmapMask } from './RoomPlaneBitmapMask'; +import { RoomPlaneRectangleMask } from './RoomPlaneRectangleMask'; +import { PlaneMaskManager } from './mask'; +import { Randomizer } from './utils'; + +export class RoomPlane implements IRoomPlane +{ + public static HORIZONTAL_ANGLE_DEFAULT: number = 45; + public static VERTICAL_ANGLE_DEFAULT: number = 30; + public static PLANE_GEOMETRY: IRoomGeometry = new RoomGeometry(64, new Vector3d(RoomPlane.HORIZONTAL_ANGLE_DEFAULT, RoomPlane.VERTICAL_ANGLE_DEFAULT), new Vector3d(-10, 0, 0)); + private static LANDSCAPE_COLOR: number = 0x0082F0; + + 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 = false; + private _randomSeed: number; + private _origin: IVector3D = new Vector3d(); + private _location: IVector3D = new Vector3d(); + private _leftSide: IVector3D = new Vector3d(); + private _rightSide: IVector3D = new Vector3d(); + private _normal: IVector3D = null; + private _secondaryNormals: IVector3D[] = []; + private _type: number; + private _isVisible: boolean = false; + private _offset: Point = new Point(); + private _relativeDepth: number = 0; + private _color: number = 0; + private _maskManager: PlaneMaskManager = null; + private _id: string = null; + private _uniqueId: number; + private _cornerA: IVector3D = new Vector3d(); + private _cornerB: IVector3D = new Vector3d(); + private _cornerC: IVector3D = new Vector3d(); + private _cornerD: IVector3D = new Vector3d(); + private _textureOffsetX: number; + private _textureOffsetY: number; + private _textureMaxX: number; + private _textureMaxY: number; + private _width: number = 0; + private _height: number = 0; + private _hasTexture: boolean = true; + private _canBeVisible: boolean = true; + private _geometryUpdateId: number = -1; + + private _useMask: boolean; + private _bitmapMasks: RoomPlaneBitmapMask[] = []; + private _rectangleMasks: RoomPlaneRectangleMask[] = []; + private _maskChanged: boolean = false; + private _bitmapMasksOld: RoomPlaneBitmapMask[] = []; + private _rectangleMasksOld: RoomPlaneRectangleMask[] = []; + + private _planeSprite: TilingSprite = null; + private _planeTexture: Texture = null; + private _maskFilter: Filter = null; + + constructor(origin: IVector3D, location: IVector3D, leftSide: IVector3D, rightSide: IVector3D, type: number, usesMask: boolean, secondaryNormals: IVector3D[], randomSeed: number, textureOffsetX: number = 0, textureOffsetY: number = 0, textureMaxX: number = 0, textureMaxY: number = 0) + { + this._randomSeed = randomSeed; + this._origin.assign(origin); + this._location.assign(location); + this._leftSide.assign(leftSide); + this._rightSide.assign(rightSide); + this._normal = Vector3d.crossProduct(this._leftSide, this._rightSide); + + if(this._normal.length > 0) this._normal.multiply((1 / this._normal.length)); + + if(secondaryNormals != null) + { + for(const entry of secondaryNormals) + { + if(!entry) continue; + + const vector = new Vector3d(); + + vector.assign(entry); + + this._secondaryNormals.push(vector); + } + } + + this._type = type; + this._textureOffsetX = textureOffsetX; + this._textureOffsetY = textureOffsetY; + this._textureMaxX = textureMaxX; + this._textureMaxY = textureMaxY; + this._useMask = usesMask; + this._uniqueId = ++RoomPlane._uniqueIdCounter; + } + + public dispose(): void + { + this._location = null; + this._origin = null; + this._leftSide = null; + this._rightSide = null; + this._normal = null; + this._cornerA = null; + this._cornerB = null; + this._cornerC = null; + this._cornerD = null; + + if(this._planeSprite) this._planeSprite.destroy(); + + if(this._planeTexture) + { + GetTexturePool().putTexture(this._planeTexture); + + this._planeTexture = null; + } + + this._disposed = true; + } + + public update(geometry: IRoomGeometry, timeSinceStartMs: number, needsUpdate: boolean = false): boolean + { + if(!geometry || this._disposed) return false; + + if(this._geometryUpdateId !== geometry.updateId) + { + this._geometryUpdateId = geometry.updateId; + + needsUpdate = true; + } + + if(!needsUpdate || !this._canBeVisible) + { + if(!this.visible) return false; + } + + if(needsUpdate) + { + let cosAngle = 0; + + cosAngle = Vector3d.cosAngle(geometry.directionAxis, this.normal); + + if(cosAngle > -0.001) + { + if(this._isVisible) + { + this._isVisible = false; + + return true; + } + + return false; + } + + let i = 0; + + while(i < this._secondaryNormals.length) + { + cosAngle = Vector3d.cosAngle(geometry.directionAxis, this._secondaryNormals[i]); + + if(cosAngle > -0.001) + { + if(this._isVisible) + { + this._isVisible = false; + return true; + } + + return false; + } + + i++; + } + + this.updateCorners(geometry); + + let relativeDepth = (Math.max(this._cornerA.z, this._cornerB.z, this._cornerC.z, this._cornerD.z) - geometry.getScreenPosition(this._origin).z); + + switch(this._type) + { + case RoomPlane.TYPE_FLOOR: + relativeDepth = (relativeDepth - ((this._location.z + Math.min(0, this._leftSide.z, this._rightSide.z)) * 8)); + break; + case RoomPlane.TYPE_LANDSCAPE: + relativeDepth = (relativeDepth + 0.02); + break; + } + + this._relativeDepth = relativeDepth; + this._isVisible = true; + + Randomizer.setSeed(this._randomSeed); + + let width = (this._leftSide.length * geometry.scale); + let height = (this._rightSide.length * geometry.scale); + const normal = geometry.getCoordinatePosition(this._normal); + + const getTextureAndColorForPlane = (planeId: string, planeType: number) => + { + const dataType: keyof IAssetRoomVisualizationData = (planeType === RoomPlane.TYPE_FLOOR) ? 'floorData' : (planeType === RoomPlane.TYPE_WALL) ? 'wallData' : 'landscapeData'; + + const roomCollection = GetAssetManager().getCollection('room'); + const planeVisualizationData = roomCollection?.data?.roomVisualization?.[dataType]; + const plane = planeVisualizationData?.planes?.find(plane => (plane.id === planeId)); + const planeVisualization = (dataType === 'landscapeData') ? plane?.animatedVisualization?.[0] : plane?.visualizations?.[0]; + const planeLayer = planeVisualization?.allLayers?.[0] as IAssetPlaneVisualizationLayer; + const planeMaterialId = planeLayer?.materialId; + const planeColor = planeLayer?.color; + const planeAssetName = planeVisualizationData?.textures?.find(texture => (texture.id === planeMaterialId))?.bitmaps?.[0]?.assetName; + const texture = GetAssetManager().getAsset(planeAssetName)?.texture; + + return { texture, color: planeColor }; + }; + + const planeData = getTextureAndColorForPlane(this._id, this._type); + const texture = this._hasTexture ? planeData.texture ?? Texture.WHITE : Texture.WHITE; + + switch(this._type) + { + case RoomPlane.TYPE_FLOOR: { + const _local_10 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 0, 0)); + const _local_11 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, (height / RoomPlane.PLANE_GEOMETRY.scale), 0)); + const _local_12 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d((width / RoomPlane.PLANE_GEOMETRY.scale), 0, 0)); + + let x = 0; + let y = 0; + + if(_local_10 && _local_11 && _local_12) + { + width = Math.round(Math.abs((_local_10.x - _local_12.x))); + height = Math.round(Math.abs((_local_10.x - _local_11.x))); + + const _local_15 = (_local_10.x - RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(1, 0, 0)).x); + + x = (this._textureOffsetX * Math.trunc(Math.abs(_local_15))); + y = (this._textureOffsetY * Math.trunc(Math.abs(_local_15))); + } + + if((x !== 0) || (y !== 0)) + { + while(x < 0) x += texture.width; + + while(y < 0) y += texture.height; + } + + this._planeSprite = new TilingSprite({ + texture, + width, + height, + tint: planeData.color, + tilePosition: { + x: (x % texture.width) + (this._textureOffsetX * texture.width), + y: (y % texture.height) + (this._textureOffsetY * texture.height) + } + }); + + break; + } + case RoomPlane.TYPE_WALL: { + const _local_8 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 0, 0)); + const _local_9 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 0, (height / RoomPlane.PLANE_GEOMETRY.scale))); + const _local_10 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, (width / RoomPlane.PLANE_GEOMETRY.scale), 0)); + + if(_local_8 && _local_9 && _local_10) + { + width = Math.round(Math.abs((_local_8.x - _local_10.x))); + height = Math.round(Math.abs((_local_8.y - _local_9.y))); + } + + this._planeSprite = new TilingSprite({ + texture, + width, + height, + tint: planeData.color, + tilePosition: { + x: (this._textureOffsetX * texture.width), + y: (this._textureOffsetY * texture.height) + } + }); + + break; + } + case RoomPlane.TYPE_LANDSCAPE: { + const _local_13 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 0, 0)); + const _local_14 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 0, 1)); + const _local_15 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 1, 0)); + + if(_local_13 && _local_14 && _local_15) + { + width = Math.round(Math.abs((((_local_13.x - _local_15.x) * width) / RoomPlane.PLANE_GEOMETRY.scale))); + height = Math.round(Math.abs((((_local_13.y - _local_14.y) * height) / RoomPlane.PLANE_GEOMETRY.scale))); + } + + const renderMaxX = Math.trunc(this._textureMaxX * Math.abs((_local_13.x - _local_15.x))); + const renderMaxY = Math.trunc(this._textureMaxY * Math.abs((_local_13.y - _local_14.y))); + + const renderOffsetX = Math.trunc(this._textureOffsetX * Math.abs((_local_13.x - _local_15.x))); + const renderOffsetY = Math.trunc(this._textureOffsetY * Math.abs((_local_13.y - _local_14.y))); + + this._planeSprite = new TilingSprite({ + texture, + width, + height, + tilePosition: { + x: renderOffsetX, + y: renderOffsetY + }, + tint: RoomPlane.LANDSCAPE_COLOR + }); + break; + } + default: { + this._planeSprite = new TilingSprite({ + texture: Texture.WHITE, + width: width, + height: height + }); + } + } + + this._planeSprite.allowChildren = true; + } + + if(needsUpdate || this._maskChanged) + { + this.updateMask(this._planeSprite, geometry); + + needsUpdate = true; + } + + if(this._planeTexture) + { + if(this._planeTexture.width !== this._width || this._planeTexture.height !== this._height) + { + GetTexturePool().putTexture(this._planeTexture); + + this._planeTexture = null; + } + } + + if(!this._planeTexture) this._planeTexture = GetTexturePool().getTexture(this._width, this._height); + + this._planeTexture.source.label = `room_plane_${ this._uniqueId.toString() }`; + + if(needsUpdate) + { + GetRenderer().render({ + target: this._planeTexture, + container: this._planeSprite, + transform: this.getMatrixForDimensions(this._planeSprite.width, this._planeSprite.height), + clear: true + }); + } + + return true; + } + + private updateCorners(geometry: IRoomGeometry): void + { + this._cornerA.assign(geometry.getScreenPosition(this._location)); + this._cornerB.assign(geometry.getScreenPosition(Vector3d.sum(this._location, this._rightSide))); + this._cornerC.assign(geometry.getScreenPosition(Vector3d.sum(Vector3d.sum(this._location, this._leftSide), this._rightSide))); + this._cornerD.assign(geometry.getScreenPosition(Vector3d.sum(this._location, this._leftSide))); + + this._offset = geometry.getScreenPoint(this._origin); + this._cornerA.x = Math.round(this._cornerA.x); + this._cornerA.y = Math.round(this._cornerA.y); + this._cornerB.x = Math.round(this._cornerB.x); + this._cornerB.y = Math.round(this._cornerB.y); + this._cornerC.x = Math.round(this._cornerC.x); + this._cornerC.y = Math.round(this._cornerC.y); + this._cornerD.x = Math.round(this._cornerD.x); + this._cornerD.y = Math.round(this._cornerD.y); + this._offset.x = Math.round(this._offset.x); + this._offset.y = Math.round(this._offset.y); + + const minX = Math.min(this._cornerA.x, this._cornerB.x, this._cornerC.x, this._cornerD.x); + const maxX = Math.max(this._cornerA.x, this._cornerB.x, this._cornerC.x, this._cornerD.x) - minX; + const minY = Math.min(this._cornerA.y, this._cornerB.y, this._cornerC.y, this._cornerD.y); + const maxY = Math.max(this._cornerA.y, this._cornerB.y, this._cornerC.y, this._cornerD.y) - minY; + + this._offset.x = (this._offset.x - minX); + this._cornerA.x = (this._cornerA.x - minX); + this._cornerB.x = (this._cornerB.x - minX); + this._cornerC.x = (this._cornerC.x - minX); + this._cornerD.x = (this._cornerD.x - minX); + + this._offset.y = (this._offset.y - minY); + this._cornerA.y = (this._cornerA.y - minY); + this._cornerB.y = (this._cornerB.y - minY); + this._cornerC.y = (this._cornerC.y - minY); + this._cornerD.y = (this._cornerD.y - minY); + + this._width = maxX; + this._height = maxY; + } + + private getMatrixForDimensions(width: number, height: number): Matrix + { + let a: number = (this._cornerD.x - this._cornerC.x); + let b: number = (this._cornerD.y - this._cornerC.y); + let c: number = (this._cornerB.x - this._cornerC.x); + let d: number = (this._cornerB.y - this._cornerC.y); + + if((this._type === RoomPlane.TYPE_WALL) || (this._type === RoomPlane.TYPE_LANDSCAPE)) + { + if(Math.abs((c - width)) <= 1) c = width; + + if(Math.abs((d - width)) <= 1) d = width; + + if(Math.abs((a - height)) <= 1) a = height; + + if(Math.abs((b - height)) <= 1) b = height; + } + + const xScale: number = (c / width); + const ySkew: number = (d / width); + const xSkew: number = (a / height); + const yScale: number = (b / height); + + const matrix = new Matrix(xScale, ySkew, xSkew, yScale); + + matrix.translate(this._cornerC.x, this._cornerC.y); + + return matrix; + } + + public resetBitmapMasks(): void + { + if(this._disposed || !this._useMask || !this._bitmapMasks.length) return; + + this._maskChanged = true; + this._bitmapMasks = []; + } + + public addBitmapMask(maskType: string, leftSideLoc: number, rightSideLoc: number): boolean + { + if(!this._useMask) return false; + + for(const mask of this._bitmapMasks) + { + if(!mask) continue; + + if((((mask.type === maskType) && (mask.leftSideLoc === leftSideLoc)) && (mask.rightSideLoc === rightSideLoc))) return false; + } + + const mask = new RoomPlaneBitmapMask(maskType, leftSideLoc, rightSideLoc); + + this._bitmapMasks.push(mask); + this._maskChanged = true; + + return true; + } + + public resetRectangleMasks(): void + { + if(!this._useMask || !this._rectangleMasks.length) return; + + this._maskChanged = true; + this._rectangleMasks = []; + } + + public addRectangleMask(leftLocation: number, rightLocation: number, leftLength: number, rightLength: number): boolean + { + if(this._useMask) + { + for(const mask of this._rectangleMasks) + { + if(!mask) continue; + + if((((mask.leftSideLoc === leftLocation) && (mask.rightSideLoc === rightLocation)) && (mask.leftSideLength === leftLength)) && (mask.rightSideLength === rightLength)) return false; + } + + this._rectangleMasks.push(new RoomPlaneRectangleMask(leftLocation, rightLocation, leftLength, rightLength)); + this._maskChanged = true; + + return true; + } + + return false; + } + + private updateMask(container: Container, geometry: IRoomGeometry): boolean + { + if(container.children?.length) container.removeChildren(); + + if(!container || !geometry || !this._useMask || (!this._bitmapMasks.length && !this._rectangleMasks.length) || !this._maskManager) return false; + + const normal = geometry.getCoordinatePosition(this._normal); + + let type: string = null; + let posX = 0; + let posY = 0; + let i = 0; + + while(i < this._bitmapMasks.length) + { + const mask = this._bitmapMasks[i]; + + if(mask) + { + type = mask.type; + posX = (container.width - ((container.width * mask.leftSideLoc) / this._leftSide.length)); + posY = (container.height - ((container.height * mask.rightSideLoc) / this._rightSide.length)); + + this._maskManager.addMaskToContainer(container, type, geometry.scale, normal, posX, posY); + } + + i++; + } + + i = 0; + + while(i < this._rectangleMasks.length) + { + const rectMask = this._rectangleMasks[i]; + + if(rectMask) + { + posX = (container.width - ((container.width * rectMask.leftSideLoc) / this._leftSide.length)); + posY = (container.height - ((container.height * rectMask.rightSideLoc) / this._rightSide.length)); + + const wd = ((container.width * rectMask.leftSideLength) / this._leftSide.length); + const ht = ((container.height * rectMask.rightSideLength) / this._rightSide.length); + + const maskSprite = new Sprite(Texture.WHITE); + + maskSprite.tint = 0x000000; + maskSprite.width = wd; + maskSprite.height = ht; + maskSprite.position.set(Math.trunc((posX - wd)), Math.trunc((posY - ht))); + + container.addChild(maskSprite); + } + + i++; + } + + this._maskChanged = false; + + if(!this._maskFilter) this._maskFilter = new PlaneMaskFilter({}); + + if(!container.filters) container.filters = [ this._maskFilter ]; + + return true; + } + + public get canBeVisible(): boolean + { + return this._canBeVisible; + } + + public set canBeVisible(flag: boolean) + { + if(flag !== this._canBeVisible) this._canBeVisible = flag; + } + + public get visible(): boolean + { + return (this._isVisible && this._canBeVisible); + } + + 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 leftSide(): IVector3D + { + return this._leftSide; + } + + public get rightSide(): IVector3D + { + return this._rightSide; + } + + public get location(): IVector3D + { + return this._location; + } + + public get normal(): IVector3D + { + return this._normal; + } + + public set id(k: string) + { + if(k === this._id) return; + + this._id = k; + } + + public set maskManager(k: PlaneMaskManager) + { + this._maskManager = k; + } + + public get uniqueId(): number + { + return this._uniqueId; + } + + public get planeTexture(): Texture + { + return this._planeTexture; + } + + public set hasTexture(flag: boolean) + { + this._hasTexture = flag; + } +} diff --git a/packages/room/src/object/visualization/room/RoomPlaneBitmapMask.ts b/packages/room/src/object/visualization/room/RoomPlaneBitmapMask.ts new file mode 100644 index 0000000..44f583c --- /dev/null +++ b/packages/room/src/object/visualization/room/RoomPlaneBitmapMask.ts @@ -0,0 +1,28 @@ +export class RoomPlaneBitmapMask +{ + private _type: string; + private _leftSideLoc: number; + private _rightSideLoc: number; + + constructor(maskType: string, leftSideLoc: number, rightSideLoc: number) + { + this._type = maskType; + this._leftSideLoc = leftSideLoc; + this._rightSideLoc = rightSideLoc; + } + + public get type(): string + { + return this._type; + } + + public get leftSideLoc(): number + { + return this._leftSideLoc; + } + + public get rightSideLoc(): number + { + return this._rightSideLoc; + } +} diff --git a/packages/room/src/object/visualization/room/RoomPlaneRectangleMask.ts b/packages/room/src/object/visualization/room/RoomPlaneRectangleMask.ts new file mode 100644 index 0000000..807dc20 --- /dev/null +++ b/packages/room/src/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 leftSideLoc(): number + { + return this._leftSideLoc; + } + + public get rightSideLoc(): number + { + return this._rightSideLoc; + } + + public get leftSideLength(): number + { + return this._leftSideLength; + } + + public get rightSideLength(): number + { + return this._rightSideLength; + } +} diff --git a/packages/room/src/object/visualization/room/RoomVisualization.ts b/packages/room/src/object/visualization/room/RoomVisualization.ts new file mode 100644 index 0000000..883fe5d --- /dev/null +++ b/packages/room/src/object/visualization/room/RoomVisualization.ts @@ -0,0 +1,812 @@ +import { ToInt32, Vector3d } from '@nitrots/utils'; +import { Rectangle, Texture } from 'pixi.js'; +import { AlphaTolerance, IObjectVisualizationData, IPlaneVisualization, IRoomGeometry, IRoomObjectModel, IRoomObjectSprite, IRoomPlane, RoomObjectSpriteType, RoomObjectVariable } from '../../../../../api'; +import { RoomMapData } from '../../RoomMapData'; +import { RoomMapMaskData } from '../../RoomMapMaskData'; +import { RoomPlaneBitmapMaskData } from '../../RoomPlaneBitmapMaskData'; +import { RoomPlaneBitmapMaskParser } from '../../RoomPlaneBitmapMaskParser'; +import { RoomPlaneData } from '../../RoomPlaneData'; +import { RoomPlaneParser } from '../../RoomPlaneParser'; +import { RoomObjectSpriteVisualization } from '../RoomObjectSpriteVisualization'; +import { RoomPlane } from './RoomPlane'; +import { RoomVisualizationData } from './RoomVisualizationData'; + +export class RoomVisualization extends RoomObjectSpriteVisualization implements IPlaneVisualization +{ + public static FLOOR_COLOR: number = 0xFFFFFF; + public static FLOOR_COLOR_LEFT: number = 0xDDDDDD; + public static FLOOR_COLOR_RIGHT: number = 0xBBBBBB; + private static WALL_COLOR_TOP: number = 0xFFFFFF; + private static WALL_COLOR_SIDE: number = 0xCCCCCC; + private static WALL_COLOR_BOTTOM: number = 0x999999; + private static WALL_COLOR_BORDER: number = 0x999999; + public static LANDSCAPE_COLOR_TOP: number = 0xFFFFFF; + public static LANDSCAPE_COLOR_SIDE: number = 0xCCCCCC; + public static LANDSCAPE_COLOR_BOTTOM: number = 0x999999; + private static ROOM_DEPTH_OFFSET: number = 1000; + + protected _data: RoomVisualizationData = null; + + private _roomPlaneParser: RoomPlaneParser = new RoomPlaneParser(); + private _roomPlaneBitmapMaskParser: RoomPlaneBitmapMaskParser = new RoomPlaneBitmapMaskParser(); + private _geometryUpdateId: number = -1; + private _boundingRectangle: Rectangle = null; + private _directionX: number = 0; + private _directionY: number = 0; + private _directionZ: number = 0; + private _floorThickness: number = 1; + private _wallThickness: number = 1; + private _holeUpdateTime: number = NaN; + private _planes: RoomPlane[] = []; + private _visiblePlanes: RoomPlane[] = []; + private _visiblePlaneSpriteNumbers: number[] = []; + private _roomScale: number = 0; + private _colorBackgroundOnly: boolean = true; + private _color: number = 0xFFFFFF; + private _redColor: number = 0xFFFFFF; + private _greenColor: number = 0xFFFFFF; + private _blueColor: number = 0xFFFFFF; + private _wallType: string = null; + private _floorType: string = null; + private _landscapeType: string = null; + private _typeVisibility: boolean[] = []; + private _assetUpdateCounter: number = 0; + private _maskData: RoomMapMaskData = null; + private _isPlaneSet: boolean = false; + + constructor() + { + super(); + + 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 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._planes = null; + this._visiblePlanes = null; + this._visiblePlaneSpriteNumbers = null; + + if(this._roomPlaneParser) + { + this._roomPlaneParser.dispose(); + + this._roomPlaneParser = null; + } + + if(this._roomPlaneBitmapMaskParser) + { + this._roomPlaneBitmapMaskParser.dispose(); + + this._roomPlaneBitmapMaskParser = null; + } + + + if(this._data) + { + this._data.clearCache(); + + this._data = null; + } + } + + 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; + + const geometryUpdate = this.updateGeometry(geometry); + const objectModel = this.object.model; + + let needsUpdate = geometryUpdate; + + if(this.updateThickness(objectModel)) needsUpdate = true; + + if(this.updateHole(objectModel)) needsUpdate = true; + + this.initializeRoomPlanes(); + + if(this.updateMasks(objectModel)) needsUpdate = true; + + if(this.updatePlaneTexturesAndVisibilities(objectModel)) needsUpdate = true; + + if(this.updatePlanes(geometry, geometryUpdate, time, needsUpdate)) needsUpdate = true; + + if(needsUpdate) + { + let index = 0; + + while(index < this._visiblePlanes.length) + { + const spriteIndex = this._visiblePlaneSpriteNumbers[index]; + const sprite = this.getSprite(spriteIndex); + const plane = this._visiblePlanes[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; + } + + 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 updatePlaneTexturesAndVisibilities(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); + + 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); + + let result = false; + + result = this.updatePlaneTypes(floorType, wallType, landscapeType); + + result = this.updatePlaneVisibility(floorVisibility, wallVisibility, landscapeVisibility) ? true : result; + + return result; + } + + private updateMasks(model: IRoomObjectModel): boolean + { + if(this.updateModelCounter === model.updateCounter) return false; + + let didUpdate = false; + + const planeMask = model.getValue(RoomObjectVariable.ROOM_PLANE_MASK_XML); + + if(planeMask !== this._maskData) + { + this.updatePlaneMasks(planeMask); + + this._maskData = planeMask; + + didUpdate = true; + } + + const backgroundColor = model.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 = (model.getValue(RoomObjectVariable.ROOM_COLORIZE_BG_ONLY) || false); + + if(backgroundOnly !== this._colorBackgroundOnly) + { + this._colorBackgroundOnly = backgroundOnly; + + didUpdate = true; + } + + return didUpdate; + } + + private clearPlanes(): void + { + if(this._planes) + { + while(this._planes.length) + { + const plane = this._planes[0]; + + if(plane) plane.dispose(); + + this._planes.shift(); + } + + this._planes = []; + } + + this._isPlaneSet = false; + this._assetUpdateCounter = (this._assetUpdateCounter + 1); + + this.reset(); + } + + protected initializeRoomPlanes(): void + { + if(!this.object || this._isPlaneSet) return; + + 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 maxX = this.getLandscapeWidth(); + const maxY = this.getLandscapeHeight(); + + let landscapeOffsetX = 0; + let randomSeed = 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); + + randomSeed = ToInt32(Math.trunc((randomSeed * 7613) + 517) >>> 0); + 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 textureOffsetX = (Math.trunc(_local_15) - _local_15); + const textureOffsetY = (Math.trunc(_local_16) - _local_16); + + plane = new RoomPlane(this.object.getLocation(), location, leftSide, rightSide, RoomPlane.TYPE_FLOOR, true, secondaryNormals, randomSeed, -(textureOffsetX), -(textureOffsetY)); + + plane.color = (_local_14.z !== 0) ? RoomVisualization.FLOOR_COLOR : ((_local_14.x !== 0) ? RoomVisualization.FLOOR_COLOR_RIGHT : RoomVisualization.FLOOR_COLOR_LEFT); + } + + else if(planeType === RoomPlaneData.PLANE_WALL) + { + plane = new RoomPlane(this.object.getLocation(), location, leftSide, rightSide, RoomPlane.TYPE_WALL, true, secondaryNormals, randomSeed); + + if((leftSide.length < 1) || (rightSide.length < 1)) plane.hasTexture = false; + + plane.color = ((_local_14.x === 0) && (_local_14.y === 0)) ? RoomVisualization.WALL_COLOR_BORDER : ((_local_14.y > 0) ? RoomVisualization.WALL_COLOR_TOP : ((_local_14.y === 0) ? RoomVisualization.WALL_COLOR_SIDE : RoomVisualization.WALL_COLOR_BOTTOM)); + } + + else if(planeType === RoomPlaneData.PLANE_LANDSCAPE) + { + plane = new RoomPlane(this.object.getLocation(), location, leftSide, rightSide, RoomPlane.TYPE_LANDSCAPE, true, secondaryNormals, randomSeed, landscapeOffsetX, 0, maxX, maxY); + + if((leftSide.length < 1) || (rightSide.length < 1)) plane.hasTexture = false; + + plane.color = (_local_14.y > 0) ? RoomVisualization.LANDSCAPE_COLOR_TOP : (_local_14.y === 0) ? RoomVisualization.LANDSCAPE_COLOR_SIDE : RoomVisualization.LANDSCAPE_COLOR_BOTTOM; + + landscapeOffsetX = (landscapeOffsetX + leftSide.length); + } + + if(plane) + { + plane.maskManager = this._data.maskManager; + + let i = 0; + + while(i < this._roomPlaneParser.getPlaneMaskCount(index)) + { + const _local_20 = this._roomPlaneParser.getPlaneMaskLeftSideLoc(index, i); + const _local_21 = this._roomPlaneParser.getPlaneMaskRightSideLoc(index, i); + const _local_22 = this._roomPlaneParser.getPlaneMaskLeftSideLength(index, i); + const _local_23 = this._roomPlaneParser.getPlaneMaskRightSideLength(index, i); + + plane.addRectangleMask(_local_20, _local_21, _local_22, _local_23); + + i++; + } + + this._planes.push(plane); + } + } + else + { + return; + } + + index++; + } + + this._isPlaneSet = true; + this.defineSprites(); + } + + protected defineSprites(): void + { + this.createSprites(this._planes.length); + + let planeIndex = 0; + + while(planeIndex < this._planes.length) + { + const plane = this._planes[planeIndex]; + const sprite = this.getSprite(planeIndex); + + if(plane && sprite && plane.leftSide && plane.rightSide) + { + if((plane.type === RoomPlane.TYPE_WALL) && ((plane.leftSide.length < 1) || (plane.rightSide.length < 1))) + { + sprite.alphaTolerance = AlphaTolerance.MATCH_NOTHING; + } + else + { + sprite.alphaTolerance = AlphaTolerance.MATCH_OPAQUE_PIXELS; + } + + 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.ROOM_PLANE; + } + + planeIndex++; + } + } + + private getLandscapeWidth(): 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 getLandscapeHeight(): 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._planes.length) + { + const plane = this._planes[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(floorVisibility: boolean, wallVisibility: boolean, landscapeVisibility: boolean): boolean + { + if((floorVisibility === this._typeVisibility[RoomPlane.TYPE_FLOOR]) && (wallVisibility === this._typeVisibility[RoomPlane.TYPE_WALL]) && (landscapeVisibility === this._typeVisibility[RoomPlane.TYPE_LANDSCAPE])) return false; + + this._typeVisibility[RoomPlane.TYPE_FLOOR] = floorVisibility; + this._typeVisibility[RoomPlane.TYPE_WALL] = wallVisibility; + this._typeVisibility[RoomPlane.TYPE_LANDSCAPE] = landscapeVisibility; + + this._visiblePlanes = []; + this._visiblePlaneSpriteNumbers = []; + + return true; + } + + protected updatePlanes(geometry: IRoomGeometry, geometryUpdate: boolean, timeSinceStartMs: number, needsUpdate: boolean = false): boolean + { + if(!geometry || !this.object) return false; + + this._assetUpdateCounter++; + + if(geometryUpdate) + { + this._visiblePlanes = []; + this._visiblePlaneSpriteNumbers = []; + } + + const hasVisiblePlanes = (this._visiblePlanes.length > 0); + + let visiblePlanes = this._visiblePlanes; + + if(!this._visiblePlanes.length) visiblePlanes = this._planes; + + let depth = 0; + let updated = false; + let index = 0; + + while(index < visiblePlanes.length) + { + let id = index; + + if(hasVisiblePlanes) id = this._visiblePlaneSpriteNumbers[index]; + + const sprite = this.getSprite(id); + + if(sprite) + { + const plane = visiblePlanes[index]; + + if(plane) + { + sprite.id = plane.uniqueId; + + if(plane.update(geometry, timeSinceStartMs, needsUpdate)) + { + if(plane.visible) + { + depth = ((plane.relativeDepth + this.floorRelativeDepth) + (id / 1000)); + + if(plane.type !== RoomPlane.TYPE_FLOOR) + { + depth = ((plane.relativeDepth + this.wallRelativeDepth) + (id / 1000)); + + if((plane.leftSide.length < 1) || (plane.rightSide.length < 1)) + { + depth = (depth + (RoomVisualization.ROOM_DEPTH_OFFSET * 0.5)); + } + } + + this.updateSprite(sprite, geometry, plane, `plane ${ id } ${ geometry.scale }`, depth); + } + + updated = true; + } + + if(sprite.visible != ((plane.visible) && (this._typeVisibility[plane.type]))) + { + sprite.visible = (!(sprite.visible)); + updated = true; + } + + if(sprite.visible) + { + if(!hasVisiblePlanes) + { + this._visiblePlanes.push(plane); + this._visiblePlaneSpriteNumbers.push(index); + } + } + } + else + { + sprite.id = 0; + + if(sprite.visible) + { + sprite.visible = false; + updated = true; + } + } + } + + index++; + } + + return updated; + } + + protected updatePlaneMasks(maskData: RoomMapMaskData): void + { + if(!maskData) return; + + this._roomPlaneBitmapMaskParser.initialize(maskData); + + const _local_4: number[] = []; + const _local_5: number[] = []; + + let _local_6 = false; + let index = 0; + + while(index < this._planes.length) + { + const plane = this._planes[index]; + + if(plane) + { + plane.resetBitmapMasks(); + + if(plane.type === RoomPlane.TYPE_LANDSCAPE) _local_4.push(index); + } + + index++; + } + + for(const mask of this._roomPlaneBitmapMaskParser.masks.values()) + { + const maskType = this._roomPlaneBitmapMaskParser.getMaskType(mask); + const maskLocation = this._roomPlaneBitmapMaskParser.getMaskLocation(mask); + const maskCategory = this._roomPlaneBitmapMaskParser.getMaskCategory(mask); + + if(maskLocation) + { + let i = 0; + + while(i < this._planes.length) + { + const plane = this._planes[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.leftSide && plane.rightSide) + { + const leftSideLoc = Vector3d.scalarProjection(_local_14, plane.leftSide); + const rightSideLoc = Vector3d.scalarProjection(_local_14, plane.rightSide); + + if((plane.type === RoomPlane.TYPE_WALL) || ((plane.type === RoomPlane.TYPE_LANDSCAPE) && (maskCategory === RoomPlaneBitmapMaskData.HOLE))) + { + plane.addBitmapMask(maskType, leftSideLoc, rightSideLoc); + } + else + { + if(plane.type === RoomPlane.TYPE_LANDSCAPE) + { + if(!plane.canBeVisible) _local_6 = true; + + plane.canBeVisible = 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._planes[planeIndex]; + + plane.canBeVisible = false; + _local_6 = true; + } + + index++; + } + + if(_local_6) + { + this._visiblePlanes = []; + this._visiblePlaneSpriteNumbers = []; + } + } + + private updateSprite(sprite: IRoomObjectSprite, geometry: IRoomGeometry, plane: RoomPlane, _arg_3: string, relativeDepth: number): void + { + const offset = plane.offset; + + sprite.offsetX = -(offset.x); + sprite.offsetY = -(offset.y); + sprite.relativeDepth = relativeDepth; + sprite.color = plane.color; + sprite.texture = plane.planeTexture ?? Texture.EMPTY; + sprite.name = ((_arg_3 + '_') + this._assetUpdateCounter); + } + + 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 planes(): IRoomPlane[] + { + const planes: IRoomPlane[] = []; + + for(const plane of this._visiblePlanes) planes.push(plane); + + return planes; + } + + public get floorRelativeDepth(): number + { + return RoomVisualization.ROOM_DEPTH_OFFSET + 0.1; + } + + public get wallRelativeDepth(): number + { + return RoomVisualization.ROOM_DEPTH_OFFSET + 0.5; + } +} diff --git a/packages/room/src/object/visualization/room/RoomVisualizationData.ts b/packages/room/src/object/visualization/room/RoomVisualizationData.ts new file mode 100644 index 0000000..9059d98 --- /dev/null +++ b/packages/room/src/object/visualization/room/RoomVisualizationData.ts @@ -0,0 +1,47 @@ +import { IAssetData, IGraphicAssetCollection, IObjectVisualizationData } from '@nitrots/api'; +import { PlaneMaskManager } from './mask'; + +export class RoomVisualizationData implements IObjectVisualizationData +{ + private _maskManager: PlaneMaskManager = new PlaneMaskManager(); + private _initialized: boolean = false; + + public initialize(asset: IAssetData): boolean + { + if(!asset.roomVisualization) return false; + + const maskData = asset.roomVisualization.maskData; + + if(maskData) this._maskManager.initialize(maskData); + + return true; + } + + public dispose(): void + { + if(this._maskManager) + { + this._maskManager.dispose(); + + this._maskManager = null; + } + } + + public setGraphicAssetCollection(collection: IGraphicAssetCollection): void + { + if(this._initialized) return; + + this._maskManager.initializeAssetCollection(collection); + + this._initialized = true; + } + + public clearCache(): void + { + } + + public get maskManager(): PlaneMaskManager + { + return this._maskManager; + } +} diff --git a/packages/room/src/object/visualization/room/TileCursorVisualization.ts b/packages/room/src/object/visualization/room/TileCursorVisualization.ts new file mode 100644 index 0000000..ffc217f --- /dev/null +++ b/packages/room/src/object/visualization/room/TileCursorVisualization.ts @@ -0,0 +1,26 @@ +import { RoomObjectVariable } from '@nitrots/api'; +import { FurnitureAnimatedVisualization } from '../furniture'; + +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); + } +} diff --git a/packages/room/src/object/visualization/room/index.ts b/packages/room/src/object/visualization/room/index.ts new file mode 100644 index 0000000..37a12a9 --- /dev/null +++ b/packages/room/src/object/visualization/room/index.ts @@ -0,0 +1,9 @@ +export * from './PlaneDrawingData'; +export * from './RoomPlane'; +export * from './RoomPlaneBitmapMask'; +export * from './RoomPlaneRectangleMask'; +export * from './RoomVisualization'; +export * from './RoomVisualizationData'; +export * from './TileCursorVisualization'; +export * from './mask'; +export * from './utils'; diff --git a/packages/room/src/object/visualization/room/mask/PlaneMask.ts b/packages/room/src/object/visualization/room/mask/PlaneMask.ts new file mode 100644 index 0000000..b01381c --- /dev/null +++ b/packages/room/src/object/visualization/room/mask/PlaneMask.ts @@ -0,0 +1,119 @@ +import { IGraphicAsset, IVector3D } from '@nitrots/api'; +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 createMaskVisualization(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 getSizeIndex(k: number): number + { + let sizeIndex = 0; + let 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; + + index++; + } + + return sizeIndex; + } + + protected getMaskVisualization(k: number): PlaneMaskVisualization + { + if(k === this._lastSize) return this._lastMaskVisualization; + + const sizeIndex = this.getSizeIndex(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 getGraphicAsset(k: number, _arg_2: IVector3D): IGraphicAsset + { + const visualization = this.getMaskVisualization(k); + + if(!visualization) return null; + + return visualization.getAsset(_arg_2); + } + + public getAssetName(k: number): string + { + if(!this._assetNames) return null; + + return this._assetNames.get(k) || null; + } + + public setAssetName(k: number, _arg_2: string): void + { + if(!this._assetNames) return; + + this._assetNames.set(k, _arg_2); + } +} diff --git a/packages/room/src/object/visualization/room/mask/PlaneMaskBitmap.ts b/packages/room/src/object/visualization/room/mask/PlaneMaskBitmap.ts new file mode 100644 index 0000000..c02022a --- /dev/null +++ b/packages/room/src/object/visualization/room/mask/PlaneMaskBitmap.ts @@ -0,0 +1,52 @@ +import { IGraphicAsset } from '@nitrots/api'; + +export class PlaneMaskBitmap +{ + public static MIN_NORMAL_COORDINATE_VALUE: number = -1; + public static MAX_NORMAL_COORDINATE_VALUE: 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; + } +} diff --git a/packages/room/src/object/visualization/room/mask/PlaneMaskManager.ts b/packages/room/src/object/visualization/room/mask/PlaneMaskManager.ts new file mode 100644 index 0000000..53f3c71 --- /dev/null +++ b/packages/room/src/object/visualization/room/mask/PlaneMaskManager.ts @@ -0,0 +1,257 @@ +import { IAssetPlaneMaskData, IAssetPlaneTextureBitmap, IGraphicAssetCollection, IVector3D } from '@nitrots/api'; +import { GetRenderer } from '@nitrots/utils'; +import { Container, Matrix, Point, Sprite, Texture } from 'pixi.js'; +import { PlaneMask } from './PlaneMask'; +import { PlaneMaskVisualization } from './PlaneMaskVisualization'; + +export class PlaneMaskManager +{ + private _assetCollection: IGraphicAssetCollection; + private _masks: Map; + private _data: IAssetPlaneMaskData; + + constructor() + { + this._assetCollection = null; + this._masks = new Map(); + this._data = null; + } + + public get data(): IAssetPlaneMaskData + { + 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: IAssetPlaneMaskData): void + { + this._data = k; + } + + public initializeAssetCollection(k: IGraphicAssetCollection): void + { + if(!this.data) return; + + this._assetCollection = k; + + this.parseMasks(this.data, k); + } + + private parseMasks(maskData: IAssetPlaneMaskData, _arg_2: IGraphicAssetCollection): void + { + if(!maskData || !_arg_2) return; + + if(maskData.masks && maskData.masks.length) + { + let index = 0; + + while(index < maskData.masks.length) + { + const mask = maskData.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; + const maskVisualization = newMask.createMaskVisualization(size); + + if(maskVisualization) + { + const assetName = this.parseMaskBitmaps(visualization.bitmaps, maskVisualization, _arg_2); + + newMask.setAssetName(size, assetName); + } + } + + visualIndex++; + } + } + + this._masks.set(id, newMask); + } + + index++; + } + } + } + + private parseMaskBitmaps(bitmaps: IAssetPlaneTextureBitmap[], maskVisualization: PlaneMaskVisualization, assetCollection: IGraphicAssetCollection): string + { + if(!bitmaps || !bitmaps.length) return null; + + let graphicName: string = null; + + for(const bitmap of bitmaps) + { + if(!bitmap) continue; + + const assetName = bitmap.assetName; + const asset = assetCollection.getAsset(assetName); + + if(!asset) continue; + + let normalMinX = PlaneMaskVisualization.MIN_NORMAL_COORDINATE_VALUE; + let normalMaxX = PlaneMaskVisualization.MAX_NORMAL_COORDINATE_VALUE; + let normalMinY = PlaneMaskVisualization.MIN_NORMAL_COORDINATE_VALUE; + let normalMaxY = PlaneMaskVisualization.MAX_NORMAL_COORDINATE_VALUE; + + 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; + + maskVisualization.addBitmap(asset, normalMinX, normalMaxX, normalMinY, normalMaxY); + } + + return graphicName; + } + + public addMaskToContainer(container: Container, type: string, scale: number, normal: IVector3D, posX: number, posY: number): boolean + { + const mask = this._masks.get(type); + + if(!mask) return true; + + const asset = mask.getGraphicAsset(scale, normal); + + if(!asset) return true; + + const texture = asset.texture; + + if(!texture) return true; + + const point = new Point((posX + asset.offsetX), (posY + asset.offsetY)); + + const matrix = new Matrix(); + + let xScale = 1; + let ySkew = 1; + let xSkew = 0; + let yScale = 0; + let tx = (point.x + xSkew); + let ty = (point.y + yScale); + + if(asset.flipH) + { + xScale = -1; + xSkew = texture.width; + + tx = ((point.x + xSkew) - texture.width); + } + + if(asset.flipV) + { + ySkew = -1; + yScale = texture.height; + + ty = ((point.y + yScale) - texture.height); + } + + matrix.scale(xScale, ySkew); + matrix.translate(tx, ty); + + const sprite = new Sprite(texture); + + sprite.setFromMatrix(matrix); + + container.addChild(sprite); + + return true; + } + + public writeMaskToTexture(targetTexture: Texture, type: string, scale: number, normal: IVector3D, posX: number, posY: number): boolean + { + const mask = this._masks.get(type); + + if(!mask) return true; + + const asset = mask.getGraphicAsset(scale, normal); + + if(!asset) return true; + + const texture = asset.texture; + + if(!texture) return true; + + const point = new Point((posX + asset.offsetX), (posY + asset.offsetY)); + + const matrix = new Matrix(); + + let xScale = 1; + let ySkew = 1; + let xSkew = 0; + let yScale = 0; + let tx = (point.x + xSkew); + let ty = (point.y + yScale); + + if(asset.flipH) + { + xScale = -1; + xSkew = texture.width; + + tx = ((point.x + xSkew) - texture.width); + } + + if(asset.flipV) + { + ySkew = -1; + yScale = texture.height; + + ty = ((point.y + yScale) - texture.height); + } + + matrix.scale(xScale, ySkew); + matrix.translate(tx, ty); + + GetRenderer().render({ + target: targetTexture, + container: new Sprite(texture), + clear: false, + transform: matrix + }); + + return true; + } + + public getMask(k: string): PlaneMask + { + if(!this._masks || !this._masks.size) return null; + + return this._masks.get(k) || null; + } +} diff --git a/packages/room/src/object/visualization/room/mask/PlaneMaskVisualization.ts b/packages/room/src/object/visualization/room/mask/PlaneMaskVisualization.ts new file mode 100644 index 0000000..dcee40c --- /dev/null +++ b/packages/room/src/object/visualization/room/mask/PlaneMaskVisualization.ts @@ -0,0 +1,49 @@ +import { IGraphicAsset, IVector3D } from '@nitrots/api'; +import { PlaneMaskBitmap } from './PlaneMaskBitmap'; + +export class PlaneMaskVisualization +{ + public static MIN_NORMAL_COORDINATE_VALUE: number = -1; + public static MAX_NORMAL_COORDINATE_VALUE: 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 addBitmap(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; + } +} diff --git a/packages/room/src/object/visualization/room/mask/index.ts b/packages/room/src/object/visualization/room/mask/index.ts new file mode 100644 index 0000000..51da625 --- /dev/null +++ b/packages/room/src/object/visualization/room/mask/index.ts @@ -0,0 +1,4 @@ +export * from './PlaneMask'; +export * from './PlaneMaskBitmap'; +export * from './PlaneMaskManager'; +export * from './PlaneMaskVisualization'; diff --git a/packages/room/src/object/visualization/room/utils/PlaneBitmapData.ts b/packages/room/src/object/visualization/room/utils/PlaneBitmapData.ts new file mode 100644 index 0000000..2c5319c --- /dev/null +++ b/packages/room/src/object/visualization/room/utils/PlaneBitmapData.ts @@ -0,0 +1,28 @@ +import { Texture } from 'pixi.js'; + +export class PlaneBitmapData +{ + private _texture: Texture; + private _timeStamp: number; + + constructor(texture: Texture, timestamp: number) + { + this._texture = texture; + this._timeStamp = timestamp; + } + + public dispose(): void + { + this._texture = null; + } + + public get texture(): Texture + { + return this._texture; + } + + public get timeStamp(): number + { + return this._timeStamp; + } +} diff --git a/packages/room/src/object/visualization/room/utils/Randomizer.ts b/packages/room/src/object/visualization/room/utils/Randomizer.ts new file mode 100644 index 0000000..7125a71 --- /dev/null +++ b/packages/room/src/object/visualization/room/utils/Randomizer.ts @@ -0,0 +1,128 @@ +import { ToInt32 } from '@nitrots/utils'; + +export class Randomizer +{ + public static DEFAULT_SEED: number = 1; + public static DEFAULT_MODULUS: number = 16777216; + + private static _randomizer:Randomizer = null; + + private _seed: number = 1; + private _modulus: number = 16777216; + private _multiplier: number = 69069; + private _increment: number = 5; + + public static setSeed(k: number = 1): void + { + if(!Randomizer._randomizer) Randomizer._randomizer = new Randomizer(); + + Randomizer._randomizer.seed = k; + } + + public static setModulus(k: number = 16777216): void + { + if(!Randomizer._randomizer) Randomizer._randomizer = new Randomizer(); + + Randomizer._randomizer.modulus = k; + } + + public static getValues(k: number, _arg_2: number, _arg_3: number): number[] + { + if(!Randomizer._randomizer) Randomizer._randomizer = new Randomizer(); + + return Randomizer._randomizer.getRandomValues(k, _arg_2, _arg_3); + } + + public static getArray(k: number, _arg_2: number): number[] + { + if(!Randomizer._randomizer) Randomizer._randomizer = new Randomizer(); + + return Randomizer._randomizer.getRandomArray(k, _arg_2); + } + + public set seed(k: number) + { + this._seed = k; + } + + public set modulus(k: number) + { + if(k < 1) k = 1; + + this._modulus = k; + } + + public dispose(): void + { + } + + public getRandomValues(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.iterateScaled(_arg_2, (_arg_3 - _arg_2))); + _local_5++; + } + + return _local_4; + } + + public getRandomArray(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.iterateScaled(0, (_local_3.length - 1)); + + _local_5.push(_local_3[_local_7]); + _local_3.splice(_local_7, 1); + + _local_6++; + } + + return _local_5; + } + + private iterate(): number + { + let k: number = ToInt32(Math.trunc(this._multiplier * this._seed) + this._increment); + + if(k < 0) k = -(k); + + k = (k % this._modulus); + + this._seed = k; + + return k; + } + + private iterateScaled(k: number, _arg_2: number): number + { + let _local_3: number = this.iterate(); + + if(_arg_2 < 1) return k; + + _local_3 = Math.trunc(k + ((_local_3 / this._modulus) * _arg_2)); + + return _local_3; + } +} diff --git a/packages/room/src/object/visualization/room/utils/index.ts b/packages/room/src/object/visualization/room/utils/index.ts new file mode 100644 index 0000000..beb9718 --- /dev/null +++ b/packages/room/src/object/visualization/room/utils/index.ts @@ -0,0 +1,2 @@ +export * from './PlaneBitmapData'; +export * from './Randomizer'; diff --git a/packages/room/src/renderer/RoomRenderer.ts b/packages/room/src/renderer/RoomRenderer.ts new file mode 100644 index 0000000..dd6f0c4 --- /dev/null +++ b/packages/room/src/renderer/RoomRenderer.ts @@ -0,0 +1,160 @@ +import { IRoomObject, IRoomRenderer, IRoomRenderingCanvas, IRoomSpriteCanvasContainer } from '@nitrots/api'; +import { RoomSpriteCanvas } from './RoomSpriteCanvas'; + +export class RoomRenderer implements IRoomRenderer, IRoomSpriteCanvasContainer +{ + private _objects: Map = new Map(); + private _canvases: Map = new Map(); + + private _disposed: boolean = false; + private _roomObjectVariableAccurateZ: string = 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 null; + + 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(id, this, 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; + } +} diff --git a/packages/room/src/renderer/RoomSpriteCanvas.ts b/packages/room/src/renderer/RoomSpriteCanvas.ts new file mode 100644 index 0000000..1fcab92 --- /dev/null +++ b/packages/room/src/renderer/RoomSpriteCanvas.ts @@ -0,0 +1,1180 @@ +import { IRoomCanvasMouseListener, IRoomGeometry, IRoomObject, IRoomObjectSprite, IRoomObjectSpriteVisualization, IRoomRenderingCanvas, IRoomSpriteCanvasContainer, IRoomSpriteMouseEvent, MouseEventType, RoomObjectSpriteData, RoomObjectSpriteType } from '@nitrots/api'; +import { GetConfiguration } from '@nitrots/configuration'; +import { RoomSpriteMouseEvent } from '@nitrots/events'; +import { GetTicker, TextureUtils, Vector3d } from '@nitrots/utils'; +import { Container, Matrix, Point, Rectangle, Sprite, Texture } from 'pixi.js'; +import { RoomEnterEffect, RoomGeometry, RoomRotatingEffect, RoomShakingEffect } from '../utils'; +import { RoomObjectCache, RoomObjectCacheItem } from './cache'; +import { ExtendedSprite, ObjectMouseData, SortableSprite } from './utils'; + +export class RoomSpriteCanvas implements IRoomRenderingCanvas +{ + private _geometry: RoomGeometry; + private _animationFPS: number; + private _renderTimestamp: number = 0; + private _totalTimeRunning: number = 0; + private _lastFrame: number = 0; + + private _master: Container = null; + private _display: Container = null; + private _mask: Sprite = null; + + private _sortableSprites: SortableSprite[] = []; + private _spriteCount: number = 0; + private _activeSpriteCount: number = 0; + private _spritePool: ExtendedSprite[] = []; + private _skipObjectUpdate: boolean = false; + private _runningSlow: boolean = false; + + private _width: number = 0; + private _height: number = 0; + private _renderedWidth: number = 0; + private _renderedHeight: number = 0; + private _screenOffsetX: number = 0; + private _screenOffsetY: number = 0; + private _mouseLocation: Point = new Point(); + private _mouseOldX: number = 0; + private _mouseOldY: number = 0; + private _mouseCheckCount: number = 0; + private _mouseSpriteWasHit: boolean = false; + private _mouseActiveObjects: Map = new Map(); + private _eventCache: Map = new Map(); + private _eventId: number = 0; + private _scale: number = 1; + + private _SafeStr_4507: boolean = false; + private _rotation: number = 0; + private _rotationOrigin: Vector3d = null; + private _rotationRodLength: number = 0; + private _effectDirection: Vector3d; + private _effectLocation: Vector3d; + private _SafeStr_795: number = 0; + + private _noSpriteVisibilityChecking: boolean = false; + private _usesExclusionRectangles: boolean = false; + private _usesMask: boolean = true; + private _canvasUpdated: boolean = false; + + private _objectCache: RoomObjectCache; + + private _mouseListener: IRoomCanvasMouseListener = null; + + constructor( + private _id: number, + private _container: IRoomSpriteCanvasContainer, + width: number, + height: number, + scale: number) + { + this._geometry = new RoomGeometry(scale, new Vector3d(-135, 30, 0), new Vector3d(11, 11, 5), new Vector3d(-135, 0.5, 0)); + this._animationFPS = GetConfiguration().getValue('system.fps.animation', 24); + this._objectCache = new RoomObjectCache(this._container.roomObjectVariableAccurateZ); + + this.setupCanvas(); + this.initialize(width, height); + } + + private setupCanvas(): void + { + if(!this._master) this._master = new Container(); + + this._master.cullableChildren = false; + + if(!this._display) + { + const display = new Container(); + + display.isRenderGroup = true; + + display.cullableChildren = false; + + display.interactive = false; + display.interactiveChildren = false; + + this._master.addChild(display); + + this._display = display; + } + } + + public dispose(): void + { + this.cleanSprites(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.cleanSprite(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 Sprite(Texture.WHITE); + + this._mask.tint = 0xFF0000; + this._mask.width = width; + this._mask.height = height; + + if(this._master) + { + this._master.addChild(this._mask); + + if(this._display) this._display.mask = this._mask; + } + } + else + { + this._mask.width = width; + this._mask.height = height; + } + } + + if(this._master) + { + 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): void + { + if(!this._master || !this._display) return; + + if(!point) point = new Point((this._width / 2), (this._height / 2)); + + if(!offsetPoint) offsetPoint = point; + + point = this._display.toLocal(point); + + 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; + + this._totalTimeRunning += GetTicker().deltaTime; + + if(this._totalTimeRunning === this._renderTimestamp) return; + + if(time === -1) time = (this._renderTimestamp + 1); + + if(!this._container || !this._geometry) 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.position.set(this._screenOffsetX, this._screenOffsetY); + + update = true; + } + + if(this._display.scale.x !== this._scale) + { + this._display.scale.set(this._scale); + + update = true; + } + + this.doMagic(); + + const frame = Math.round(this._totalTimeRunning / (60 / this._animationFPS)); + + let updateVisuals = false; + + if(frame !== this._lastFrame) + { + this._lastFrame = frame; + + updateVisuals = 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, updateVisuals, spriteCount)); + } + } + + this._sortableSprites.sort((a, b) => (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.cleanSprites(spriteCount); + + if(update || updateVisuals) this._canvasUpdated = true; + + this._renderTimestamp = this._totalTimeRunning; + this._renderedWidth = this._width; + this._renderedHeight = this._height; + } + + public skipSpriteVisibilityChecking(): void + { + this._noSpriteVisibilityChecking = true; + + this.render(-1, true); + } + + public resumeSpriteVisibilityChecking(): void + { + this._noSpriteVisibilityChecking = false; + } + + public getSortableSpriteList(): RoomObjectSpriteData[] + { + return this._objectCache.getSortableSpriteList(); + } + + public getPlaneSortableSprites(): SortableSprite[] + { + return this._objectCache.getPlaneSortableSprites(); + } + + public removeFromCache(identifier: string): void + { + this._objectCache.removeObjectCache(identifier); + } + + private renderObject(object: IRoomObject, identifier: string, time: number, update: boolean, updateVisuals: 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.objectId = object.instanceId; + + const locationCache = cache.location; + const sortableCache = cache.sprites; + + const vector = locationCache.updateLocation(object, this._geometry); + + if(!vector) + { + this.removeFromCache(identifier); + + return 0; + } + + if(updateVisuals) visualization.update(this._geometry, time, (!sortableCache.isEmpty || update), (this._skipObjectUpdate && this._runningSlow)); + + if(locationCache.locationChanged) update = true; + + if(!sortableCache.needsUpdate(visualization.instanceId, visualization.updateSpriteCounter) && !update) + { + return sortableCache.spriteCount; + } + + 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.source; + + 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.getSprite(spriteCount); + + if(!sortableSprite) + { + sortableSprite = new SortableSprite(); + + sortableCache.addSprite(sortableSprite); + + this._sortableSprites.push(sortableSprite); + + sortableSprite.name = identifier; + } + + sortableSprite.sprite = sprite; + + if((sprite.spriteType === RoomObjectSpriteType.AVATAR) || (sprite.spriteType === RoomObjectSpriteType.AVATAR_OWN)) + { + sortableSprite.sprite.libraryAssetName = '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.setSpriteCount(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) as ExtendedSprite); + + if(!sprite) return null; + + return sprite; + } + + protected getExtendedSpriteIdentifier(sprite: ExtendedSprite): string + { + if(!sprite) return ''; + + return sprite.label; + } + + 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.varyingDepth !== objectSprite.varyingDepth) + { + if(extendedSprite.varyingDepth && !objectSprite.varyingDepth) + { + 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.label = sprite.name; + extendedSprite.varyingDepth = objectSprite.varyingDepth; + 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.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.updateEnterRoomEffect(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.label = sprite.name; + extendedSprite.varyingDepth = sprite.varyingDepth; + extendedSprite.clickHandling = sprite.clickHandling; + extendedSprite.blendMode = sprite.blendMode; + extendedSprite.filters = sprite.filters; + + extendedSprite.setTexture(sprite.texture); + + if(sprite.flipH) extendedSprite.scale.x = -1; + + if(sprite.flipV) extendedSprite.scale.y = -1; + + this.updateEnterRoomEffect(extendedSprite, sprite); + + if((index < 0) || (index >= this._spriteCount)) + { + this._display.addChild(extendedSprite); + + this._spriteCount++; + } + else + { + this._display.addChildAt(extendedSprite, index); + } + + this._activeSpriteCount++; + } + + private cleanSprites(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.cleanSprite(this.getExtendedSprite(iterator), _arg_2); + + iterator--; + } + } + + this._activeSpriteCount = spriteCount; + } + + private updateEnterRoomEffect(sprite: ExtendedSprite, _arg_2: IRoomObjectSprite): void + { + if(!RoomEnterEffect.isVisualizationOn() || !_arg_2) return; + + switch(_arg_2.spriteType) + { + case RoomObjectSpriteType.AVATAR_OWN: + return; + case RoomObjectSpriteType.ROOM_PLANE: + sprite.alpha = RoomEnterEffect.getDelta(0.9); + return; + case RoomObjectSpriteType.AVATAR: + sprite.alpha = RoomEnterEffect.getDelta(0.5); + return; + default: + sprite.alpha = RoomEnterEffect.getDelta(0.1); + } + } + + private cleanSprite(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.checkMouseHits(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 handleMouseEvent(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.checkMouseHits(Math.trunc(x / this._scale), Math.trunc(y / this._scale), type, altKey, ctrlKey, shiftKey, buttonDown); + + this._mouseCheckCount++; + + return this._mouseSpriteWasHit; + } + + private checkMouseHits(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: IRoomSpriteMouseEvent = 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.createMouseEvent(0, 0, 0, 0, MouseEventType.ROLL_OUT, mouseData.spriteTag, altKey, ctrlKey, shiftKey, buttonDown); + + this.bufferMouseEvent(mouseEvent, identifier); + } + } + + if((type === MouseEventType.MOUSE_MOVE) && (!mouseData || (mouseData.spriteTag !== tag))) + { + mouseEvent = this.createMouseEvent(x, y, (x - extendedSprite.x), (y - extendedSprite.y), MouseEventType.ROLL_OVER, tag, altKey, ctrlKey, shiftKey, buttonDown); + } + else + { + mouseEvent = this.createMouseEvent(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.bufferMouseEvent(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.createMouseEvent(0, 0, 0, 0, MouseEventType.ROLL_OUT, existing.spriteTag, altKey, ctrlKey, shiftKey, buttonDown); + + this.bufferMouseEvent(mouseEvent, key); + } + + index++; + } + + this.processMouseEvents(); + this._mouseOldX = x; + this._mouseOldY = y; + + return didHitSprite; + } + + protected createMouseEvent(x: number, y: number, localX: number, localY: number, type: string, tag: string, altKey: boolean, ctrlKey: boolean, shiftKey: boolean, buttonDown: boolean): IRoomSpriteMouseEvent + { + 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, tag, screenX, screenY, localX, localY, ctrlKey, altKey, shiftKey, buttonDown); + } + + protected bufferMouseEvent(k: IRoomSpriteMouseEvent, _arg_2: string): void + { + if(!k || !this._eventCache) return; + + this._eventCache.delete(_arg_2); + this._eventCache.set(_arg_2, k); + } + + protected processMouseEvents(): 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.processRoomCanvasMouseEvent(event, roomObject, this._geometry); + } + else + { + const logic = roomObject.mouseHandler; + + if(logic) + { + logic.mouseEvent(event, this._geometry); + } + } + } + + if(this._eventCache) this._eventCache.clear(); + } + + public getDisplayAsTexture(): Texture + { + this._noSpriteVisibilityChecking = true; + + const currentScale = this._scale; + const currentOffsetX = this._screenOffsetX; + const currentOffsetY = this._screenOffsetY; + + this.setScale(1); + + this._screenOffsetX = 0; + this._screenOffsetY = 0; + + this.render(-1, true); + + this._display.mask = null; + + const bounds = this._display.getBounds(); + const texture = TextureUtils.createAndWriteRenderTexture(this._display.width, this._display.height, this._display, new Matrix(1, 0, 0, 1, -(bounds.x), -(bounds.y))); + + this._display.mask = this._mask; + + this._noSpriteVisibilityChecking = false; + + this.setScale(currentScale); + + this._screenOffsetX = currentOffsetX; + this._screenOffsetY = currentOffsetY; + + return texture; + } + + private doMagic(): void + { + const geometry = (this.geometry as RoomGeometry); + + if(this._rotation !== 0) + { + let direction = this._effectDirection; + + geometry.direction = new Vector3d((direction.x + this._rotation), direction.y, direction.z); + + direction = (geometry.direction as Vector3d); + + geometry.setDepthVector(new Vector3d(direction.x, direction.y, 5)); + + const location = new Vector3d(); + + location.assign(this._rotationOrigin); + + location.x = (location.x + ((this._rotationRodLength * Math.cos((((direction.x + 180) / 180) * Math.PI))) * Math.cos(((direction.y / 180) * Math.PI)))); + location.y = (location.y + ((this._rotationRodLength * Math.sin((((direction.x + 180) / 180) * Math.PI))) * Math.cos(((direction.y / 180) * Math.PI)))); + location.z = (location.z + (this._rotationRodLength * Math.sin(((direction.y / 180) * Math.PI)))); + + geometry.location = location; + + this._effectLocation = new Vector3d(); + this._effectLocation.assign(location); + this._effectDirection = new Vector3d(); + this._effectDirection.assign(geometry.direction); + } + + if(RoomShakingEffect.isVisualizationOn() && !this._SafeStr_4507) + { + this.changeShaking(); + } + else + { + if(!RoomShakingEffect.isVisualizationOn() && this._SafeStr_4507) this.changeShaking(); + } + + if(RoomRotatingEffect.isVisualizationOn()) this.changeRotation(); + + if(this._SafeStr_4507) + { + this._SafeStr_795++; + + const _local_4 = this._effectDirection; + const _local_1 = Vector3d.sum(_local_4, new Vector3d((Math.sin((((this._SafeStr_795 * 5) / 180) * Math.PI)) * 2), (Math.sin(((this._SafeStr_795 / 180) * Math.PI)) * 5), (Math.sin((((this._SafeStr_795 * 10) / 180) * Math.PI)) * 2))); + + geometry.direction = _local_1; + } + else + { + this._SafeStr_795 = 0; + + geometry.direction = this._effectDirection; + } + } + + private changeShaking(): void + { + this._SafeStr_4507 = !this._SafeStr_4507; + + if(this._SafeStr_4507) + { + const direction = this.geometry.direction; + + this._effectDirection = new Vector3d(direction.x, direction.y, direction.z); + } + } + + private changeRotation(): void + { + if(this._SafeStr_4507) return; + + const geometry = (this.geometry as RoomGeometry); + + if(!geometry) return; + + if(this._rotation === 0) + { + const location = geometry.location; + const directionAxis = geometry.directionAxis; + + this._effectLocation = new Vector3d(); + this._effectLocation.assign(location); + this._effectDirection = new Vector3d(); + this._effectDirection.assign(geometry.direction); + + const intersection = RoomGeometry.getIntersectionVector(location, directionAxis, new Vector3d(0, 0, 0), new Vector3d(0, 0, 1)); + + if(intersection !== null) + { + this._rotationOrigin = new Vector3d(intersection.x, intersection.y, intersection.z); + this._rotationRodLength = Vector3d.dif(intersection, location).length; + this._rotation = 1; + } + + return; + } + + this._rotation = 0; + + geometry.location = this._effectLocation; + geometry.direction = this._effectDirection; + geometry.setDepthVector(new Vector3d(this._effectDirection.x, this._effectDirection.y, 5)); + } + + public moveLeft(): void + { + if(this._rotation !== 0) + { + if(this._rotation === 1) + { + this._rotation = -1; + } + else + { + this._rotation = (this._rotation - 1); + } + + return; + } + + const geometry = (this.geometry as RoomGeometry); + const direction = (((geometry.direction.x - 90) / 180) * Math.PI); + + geometry.location = Vector3d.sum(geometry.location, new Vector3d((Math.cos(direction) * Math.sqrt(2)), (Math.sin(direction) * Math.sqrt(2)))); + } + + public moveRight(): void + { + if(this._rotation !== 0) + { + if(this._rotation === -1) + { + this._rotation = 1; + } + else + { + this._rotation = (this._rotation + 1); + } + + return; + } + + const geometry = (this.geometry as RoomGeometry); + const direction = (((geometry.direction.x + 90) / 180) * Math.PI); + + geometry.location = Vector3d.sum(geometry.location, new Vector3d((Math.cos(direction) * Math.sqrt(2)), (Math.sin(direction) * Math.sqrt(2)))); + } + + public moveUp(): void + { + if(this._rotation !== 0) return; + + const geometry = (this.geometry as RoomGeometry); + const direction = ((geometry.direction.x / 180) * Math.PI); + + geometry.location = Vector3d.sum(geometry.location, new Vector3d((Math.cos(direction) * Math.sqrt(2)), (Math.sin(direction) * Math.sqrt(2)))); + } + + public moveDown(): void + { + if(this._rotation !== 0) return; + + const geometry = (this.geometry as RoomGeometry); + const direction = (((geometry.direction.x + 180) / 180) * Math.PI); + + geometry.location = Vector3d.sum(geometry.location, new Vector3d((Math.cos(direction) * Math.sqrt(2)), (Math.sin(direction) * Math.sqrt(2)))); + } + + public get id(): number + { + return this._id; + } + + public get geometry(): IRoomGeometry + { + return this._geometry; + } + + public get master(): Container + { + return this._master; + } + + public get display(): Container + { + 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 canvasUpdated(): boolean + { + return this._canvasUpdated; + } + + public set canvasUpdated(flag: boolean) + { + this._canvasUpdated = flag; + } +} diff --git a/packages/room/src/renderer/cache/RoomObjectCache.ts b/packages/room/src/renderer/cache/RoomObjectCache.ts new file mode 100644 index 0000000..bdff1cb --- /dev/null +++ b/packages/room/src/renderer/cache/RoomObjectCache.ts @@ -0,0 +1,142 @@ +import { IRoomObjectSprite, RoomObjectSpriteData, RoomObjectSpriteType } from '@nitrots/api'; +import { SortableSprite } from '../utils'; +import { RoomObjectCacheItem } from './RoomObjectCacheItem'; + +export class RoomObjectCache +{ + private static MAX_SIZE_FOR_AVG_COLOR: number = 200; + + private _data: Map = new Map(); + private _roomObjectVariableAccurateZ: string; + + constructor(accurateZ: string) + { + 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.sprites; + + if(!sprites || !sprites.length) continue; + + for(const sprite of sprites) + { + if(!sprite) continue; + + if((sprite.sprite.spriteType !== RoomObjectSpriteType.ROOM_PLANE) && (sprite.sprite.name !== '')) + { + const data = new RoomObjectSpriteData(); + + data.objectId = item.objectId; + 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.sprites) + { + if(sprite.sprite.spriteType === RoomObjectSpriteType.ROOM_PLANE) sprites.push(sprite); + } + } + + return sprites; + } +} diff --git a/packages/room/src/renderer/cache/RoomObjectCacheItem.ts b/packages/room/src/renderer/cache/RoomObjectCacheItem.ts new file mode 100644 index 0000000..12de528 --- /dev/null +++ b/packages/room/src/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 dispose(): void + { + if(this._location) + { + this._location.dispose(); + + this._location = null; + } + + if(this._sprites) + { + this._sprites.dispose(); + + this._sprites = null; + } + } + + public get objectId(): number + { + return this._objectId; + } + + public set objectId(k: number) + { + this._objectId = k; + } + + public get location(): RoomObjectLocationCacheItem + { + return this._location; + } + + public get sprites(): RoomObjectSortableSpriteCacheItem + { + return this._sprites; + } +} diff --git a/packages/room/src/renderer/cache/RoomObjectLocationCacheItem.ts b/packages/room/src/renderer/cache/RoomObjectLocationCacheItem.ts new file mode 100644 index 0000000..799655f --- /dev/null +++ b/packages/room/src/renderer/cache/RoomObjectLocationCacheItem.ts @@ -0,0 +1,96 @@ +import { IRoomGeometry, IRoomObject, IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; + +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; + } +} diff --git a/packages/room/src/renderer/cache/RoomObjectSortableSpriteCacheItem.ts b/packages/room/src/renderer/cache/RoomObjectSortableSpriteCacheItem.ts new file mode 100644 index 0000000..9d4a5ca --- /dev/null +++ b/packages/room/src/renderer/cache/RoomObjectSortableSpriteCacheItem.ts @@ -0,0 +1,68 @@ +import { SortableSprite } from '../utils'; + +export class RoomObjectSortableSpriteCacheItem +{ + private _sprites: SortableSprite[] = []; + private _updateId1: number = -1; + private _updateId2: number = -1; + private _isEmpty: boolean = false; + + public dispose(): void + { + this.setSpriteCount(0); + } + + public addSprite(sprite: SortableSprite): void + { + this._sprites.push(sprite); + } + + public getSprite(index: number): SortableSprite + { + return this._sprites[index]; + } + + public needsUpdate(id1: number, id2: number): boolean + { + if((id1 === this._updateId1) && (id2 === this._updateId2)) return false; + + this._updateId1 = id1; + this._updateId2 = id2; + + return true; + } + + public setSpriteCount(count: number): void + { + if(count < this._sprites.length) + { + let i = count; + + while(i < this._sprites.length) + { + this._sprites[i]?.dispose(); + + i++; + } + + this._sprites.splice(count, (this._sprites.length - count)); + } + + this._isEmpty = (this._sprites.length) ? false : true; + } + + public get sprites(): SortableSprite[] + { + return this._sprites; + } + + public get spriteCount(): number + { + return this._sprites.length; + } + + public get isEmpty(): boolean + { + return this._isEmpty; + } +} diff --git a/packages/room/src/renderer/cache/index.ts b/packages/room/src/renderer/cache/index.ts new file mode 100644 index 0000000..361f724 --- /dev/null +++ b/packages/room/src/renderer/cache/index.ts @@ -0,0 +1,4 @@ +export * from './RoomObjectCache'; +export * from './RoomObjectCacheItem'; +export * from './RoomObjectLocationCacheItem'; +export * from './RoomObjectSortableSpriteCacheItem'; diff --git a/packages/room/src/renderer/index.ts b/packages/room/src/renderer/index.ts new file mode 100644 index 0000000..a09ea46 --- /dev/null +++ b/packages/room/src/renderer/index.ts @@ -0,0 +1,4 @@ +export * from './RoomRenderer'; +export * from './RoomSpriteCanvas'; +export * from './cache'; +export * from './utils'; diff --git a/packages/room/src/renderer/utils/ExtendedSprite.ts b/packages/room/src/renderer/utils/ExtendedSprite.ts new file mode 100644 index 0000000..0eed5d3 --- /dev/null +++ b/packages/room/src/renderer/utils/ExtendedSprite.ts @@ -0,0 +1,170 @@ +import { AlphaTolerance } from '@nitrots/api'; +import { GetRenderer } from '@nitrots/utils'; +import { GlRenderTarget, Point, Sprite, Texture, TextureSource, WebGLRenderer } from 'pixi.js'; + +const BYTES_PER_PIXEL = 4; + +export class ExtendedSprite extends Sprite +{ + private _offsetX: number = 0; + private _offsetY: number = 0; + private _tag: string = ''; + private _alphaTolerance: number = AlphaTolerance.MATCH_OPAQUE_PIXELS; + private _varyingDepth: boolean = false; + private _clickHandling: boolean = false; + + private _updateId1: number = -1; + private _updateId2: number = -1; + + public needsUpdate(updateId1: number, updateId2: number): boolean + { + if((this._updateId1 === updateId1) && (this._updateId2 === updateId2)) return false; + + this._updateId1 = updateId1; + this._updateId2 = updateId2; + + return true; + } + + public setTexture(texture: Texture): void + { + if(!texture) texture = Texture.EMPTY; + + if(texture === this.texture) return; + + if(texture === Texture.EMPTY) + { + this._updateId1 = -1; + this._updateId2 = -1; + } + + this.texture = texture; + } + + public containsPoint(point: Point): boolean + { + if(!point || (this.alphaTolerance > 255) || !this.texture || (this.texture === Texture.EMPTY) || (this.blendMode !== 'normal')) return false; + + point = new Point((point.x * this.scale.x), (point.y * this.scale.y)); + + if(!super.containsPoint(point)) return false; + + const texture = this.texture; + const textureSource = this.texture.source; + + //@ts-ignore + if((!textureSource || !textureSource.hitMap) && !ExtendedSprite.generateHitMapForTextureSource(textureSource)) return false; + + //@ts-ignore + const hitMap = (textureSource.hitMap as U8intclampedArray); + + let dx = (point.x + texture.frame.x); + let dy = (point.y + texture.frame.y); + + if(this.texture.trim) + { + dx -= texture.trim.x; + dy -= texture.trim.y; + } + + dx = (Math.round(dx) * textureSource.resolution); + dy = (Math.round(dy) * textureSource.resolution); + + const index = (dx + dy * textureSource.width) * 4; + + return (hitMap[index + 3] >= this.alphaTolerance); + } + + private static generateHitMapForTextureSource(textureSource: TextureSource): boolean + { + if(!textureSource) return false; + + const width = Math.max(Math.round(textureSource.width * textureSource.resolution), 1); + const height = Math.max(Math.round(textureSource.height * textureSource.resolution), 1); + const pixels = new Uint8Array(BYTES_PER_PIXEL * width * height); + + const renderer = GetRenderer() as WebGLRenderer; + + const renderTarget = renderer.renderTarget.getRenderTarget(textureSource); + const glRenterTarget = renderer.renderTarget.getGpuRenderTarget(renderTarget) as GlRenderTarget; + + const gl = renderer.gl; + + gl.bindFramebuffer(gl.FRAMEBUFFER, glRenterTarget.resolveTargetFramebuffer); + + gl.readPixels( + 0, + 0, + width, + height, + gl.RGBA, + gl.UNSIGNED_BYTE, + pixels + ); + + //@ts-ignore + textureSource.hitMap = pixels; + + 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 varyingDepth(): boolean + { + return this._varyingDepth; + } + + public set varyingDepth(flag: boolean) + { + this._varyingDepth = flag; + } + + public get clickHandling(): boolean + { + return this._clickHandling; + } + + public set clickHandling(flag: boolean) + { + this._clickHandling = flag; + } +} diff --git a/packages/room/src/renderer/utils/ObjectMouseData.ts b/packages/room/src/renderer/utils/ObjectMouseData.ts new file mode 100644 index 0000000..ed47437 --- /dev/null +++ b/packages/room/src/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/packages/room/src/renderer/utils/SortableSprite.ts b/packages/room/src/renderer/utils/SortableSprite.ts new file mode 100644 index 0000000..4f6e2c3 --- /dev/null +++ b/packages/room/src/renderer/utils/SortableSprite.ts @@ -0,0 +1,79 @@ +import { IRoomObjectSprite, ISortableSprite } from '@nitrots/api'; + +export class SortableSprite implements ISortableSprite +{ + public static Z_INFINITY: 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.Z_INFINITY); + 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; + } +} diff --git a/packages/room/src/renderer/utils/index.ts b/packages/room/src/renderer/utils/index.ts new file mode 100644 index 0000000..65ca238 --- /dev/null +++ b/packages/room/src/renderer/utils/index.ts @@ -0,0 +1,3 @@ +export * from './ExtendedSprite'; +export * from './ObjectMouseData'; +export * from './SortableSprite'; diff --git a/packages/room/src/utils/FurnitureStackingHeightMap.ts b/packages/room/src/utils/FurnitureStackingHeightMap.ts new file mode 100644 index 0000000..4e2ee52 --- /dev/null +++ b/packages/room/src/utils/FurnitureStackingHeightMap.ts @@ -0,0 +1,121 @@ +import { IFurnitureStackingHeightMap } from '@nitrots/api'; + +export class FurnitureStackingHeightMap implements IFurnitureStackingHeightMap +{ + 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; + } +} diff --git a/packages/room/src/utils/LegacyWallGeometry.ts b/packages/room/src/utils/LegacyWallGeometry.ts new file mode 100644 index 0000000..45bdff3 --- /dev/null +++ b/packages/room/src/utils/LegacyWallGeometry.ts @@ -0,0 +1,322 @@ +import { ILegacyWallGeometry, IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; + +export class LegacyWallGeometry implements ILegacyWallGeometry +{ + 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(width: number, height: number, localX: number, localY: number, direction: string): IVector3D + { + let _local_7: number; + if(((width == 0) && (height == 0))) + { + width = this._width; + height = this._height; + const _local_12 = Math.round((this.scale / 10)); + if(direction == LegacyWallGeometry.R) + { + let _local_7 = (this._width - 1); + while(_local_7 >= 0) + { + let _local_6 = 1; + while(_local_6 < this._height) + { + if(this.getHeight(_local_7, _local_6) <= this._floorHeight) + { + if((_local_6 - 1) < height) + { + width = _local_7; + height = (_local_6 - 1); + } + break; + } + _local_6++; + } + _local_7--; + } + localY = (localY + ((this.scale / 4) - (_local_12 / 2))); + localX = (localX + (this.scale / 2)); + } + else + { + let _local_6 = (this._height - 1); + while(_local_6 >= 0) + { + let _local_7 = 1; + while(_local_7 < this._width) + { + if(this.getHeight(_local_7, _local_6) <= this._floorHeight) + { + if((_local_7 - 1) < width) + { + width = (_local_7 - 1); + height = _local_6; + } + break; + } + _local_7++; + } + _local_6--; + } + localY = (localY + ((this.scale / 4) - (_local_12 / 2))); + localX = (localX - _local_12); + } + } + let _local_8: number = width; + let _local_9: number = height; + let _local_10: number = this.getHeight(width, height); + if(direction == LegacyWallGeometry.R) + { + _local_8 = (_local_8 + ((localX / (this._scale / 2)) - 0.5)); + _local_9 = (_local_9 + 0.5); + _local_10 = (_local_10 - ((localY - (localX / 2)) / (this._scale / 2))); + } + else + { + _local_9 = (_local_9 + ((((this._scale / 2) - localX) / (this._scale / 2)) - 0.5)); + _local_8 = (_local_8 + 0.5); + _local_10 = (_local_10 - ((localY - (((this._scale / 2) - localX) / 2)) / (this._scale / 2))); + } + const _local_11: IVector3D = new Vector3d(_local_8, _local_9, _local_10); + return _local_11; + } + + public getLocationOldFormat(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 getOldLocation(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 getOldLocationString(k: IVector3D, _arg_2: number): string + { + const _local_3 = this.getOldLocation(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 getFloorAltitude(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 isRoomTile(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); + } +} diff --git a/packages/room/src/utils/RoomCamera.ts b/packages/room/src/utils/RoomCamera.ts new file mode 100644 index 0000000..e05c42b --- /dev/null +++ b/packages/room/src/utils/RoomCamera.ts @@ -0,0 +1,288 @@ +import { IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; + +export class RoomCamera +{ + private static MOVE_SPEED_DENOMINATOR: number = 12; + + private _targetId: number = -1; + private _targetCategory: number = -2; + private _targetLoc: IVector3D = null; + private _moveDistance: number = 0; + private _previousMoveSpeed: number = 0; + private _maintainPreviousMoveSpeed: boolean = false; + private _currentLoc: IVector3D = null; + private _targetObjectLoc: IVector3D; + 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 targetId(): number + { + return this._targetId; + } + + public set targetId(k: number) + { + this._targetId = k; + } + + public get targetCategory(): number + { + return this._targetCategory; + } + + public set targetCategory(k: number) + { + this._targetCategory = k; + } + + public get targetObjectLoc(): IVector3D + { + return this._targetObjectLoc; + } + + public set targetObjectLoc(k: IVector3D) + { + this._targetObjectLoc.assign(k); + } + + public get limitedLocationX(): boolean + { + return this._limitedLocX; + } + + public set limitedLocationX(k: boolean) + { + this._limitedLocX = k; + } + + public get limitedLocationY(): boolean + { + return this._limitedLocY; + } + + public set limitedLocationY(k: boolean) + { + this._limitedLocY = k; + } + + public get centeredLocX(): boolean + { + return this._centeredLocX; + } + + public set centeredLocX(k: boolean) + { + this._centeredLocX = k; + } + + public get centeredLocY(): boolean + { + return this._centeredLocY; + } + + public set centeredLocY(k: boolean) + { + this._centeredLocY = k; + } + + public get screenWd(): number + { + return this._screenWd; + } + + public set screenWd(k: number) + { + this._screenWd = k; + } + + public get screenHt(): number + { + return this._screenHt; + } + + public set screenHt(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 roomWd(): number + { + return this._roomWd; + } + + public set roomWd(k: number) + { + this._roomWd = k; + } + + public get roomHt(): number + { + return this._roomHt; + } + + public set roomHt(k: number) + { + this._roomHt = k; + } + + public get geometryUpdateId(): number + { + return this._geometryUpdateId; + } + + public set geometryUpdateId(k: number) + { + this._geometryUpdateId = k; + } + + public get isMoving(): boolean + { + if(((!(this._targetLoc == null)) && (!(this._currentLoc == null)))) + { + return true; + } + return false; + } + + public set target(k: IVector3D) + { + let _local_2: IVector3D; + 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 initializeLocation(k: IVector3D): void + { + if(this._currentLoc != null) + { + return; + } + this._currentLoc = new Vector3d(); + this._currentLoc.assign(k); + } + + public resetLocation(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: IVector3D; + 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 activateFollowing(k: number): void + { + this._followDuration = k; + } +} diff --git a/packages/room/src/utils/RoomData.ts b/packages/room/src/utils/RoomData.ts new file mode 100644 index 0000000..c3a2629 --- /dev/null +++ b/packages/room/src/utils/RoomData.ts @@ -0,0 +1,59 @@ +import { RoomMapData } from '../object'; + +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; + } +} diff --git a/packages/room/src/utils/RoomEnterEffect.ts b/packages/room/src/utils/RoomEnterEffect.ts new file mode 100644 index 0000000..c2ed7dc --- /dev/null +++ b/packages/room/src/utils/RoomEnterEffect.ts @@ -0,0 +1,78 @@ +import { GetTickerTime } from '@nitrots/utils'; + +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 = GetTickerTime(); + 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 = (GetTickerTime() - 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/packages/room/src/utils/RoomFurnitureData.ts b/packages/room/src/utils/RoomFurnitureData.ts new file mode 100644 index 0000000..3475406 --- /dev/null +++ b/packages/room/src/utils/RoomFurnitureData.ts @@ -0,0 +1,119 @@ +import { IObjectData, IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; + +export class RoomFurnitureData +{ + private _id: number; + private _typeId: number; + private _type: string; + private _location: IVector3D; + private _direction: IVector3D; + 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; + } +} diff --git a/packages/room/src/utils/RoomGeometry.ts b/packages/room/src/utils/RoomGeometry.ts new file mode 100644 index 0000000..b82cad9 --- /dev/null +++ b/packages/room/src/utils/RoomGeometry.ts @@ -0,0 +1,432 @@ +import { IRoomGeometry, IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; +import { Point } from 'pixi.js'; + +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: IVector3D; + private _y: IVector3D; + private _z: IVector3D; + private _directionAxis: IVector3D; + private _location: IVector3D; + private _direction: IVector3D; + private _depth: IVector3D; + 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: IVector3D; + private _dir: IVector3D; + 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: IVector3D = Vector3d.dif(k, _arg_3); + const _local_7: number = (-(Vector3d.dotProduct(_arg_4, _local_6)) / _local_5); + const _local_8: IVector3D = 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(scale: number) + { + if(scale <= 1) + { + scale = 1; + } + scale = (scale * Math.sqrt(0.5)); + if(scale != this._scale) + { + this._scale = scale; + 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(location: IVector3D) + { + if(location == 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(location); + 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(direction: IVector3D) + { + let _local_21: number; + let _local_22: number; + let _local_23: IVector3D; + let _local_24: IVector3D; + let _local_25: IVector3D; + if(direction == 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(direction); + this._direction.assign(direction); + if((((!(this._dir.x == _local_2)) || (!(this._dir.y == _local_3))) || (!(this._dir.z == _local_4)))) + { + this._updateId++; + } + const _local_5: IVector3D = new Vector3d(0, 1, 0); + const _local_6: IVector3D = new Vector3d(0, 0, 1); + const _local_7: IVector3D = new Vector3d(1, 0, 0); + const _local_8: number = ((direction.x / 180) * Math.PI); + const _local_9: number = ((direction.y / 180) * Math.PI); + const _local_10: number = ((direction.z / 180) * Math.PI); + const _local_11: number = Math.cos(_local_8); + const _local_12: number = Math.sin(_local_8); + const _local_13: IVector3D = Vector3d.sum(Vector3d.product(_local_5, _local_11), Vector3d.product(_local_7, -(_local_12))); + const _local_14: IVector3D = new Vector3d(_local_6.x, _local_6.y, _local_6.z); + const _local_15: IVector3D = 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: IVector3D = new Vector3d(_local_13.x, _local_13.y, _local_13.z); + const _local_19: IVector3D = Vector3d.sum(Vector3d.product(_local_14, _local_16), Vector3d.product(_local_15, _local_17)); + const _local_20: IVector3D = 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(xScale: number) + { + if(this._x_scale != (xScale * this._x_scale_internal)) + { + this._x_scale = (xScale * this._x_scale_internal); + this._updateId++; + } + } + + public set y_scale(yScale: number) + { + if(this._y_scale != (yScale * this._y_scale_internal)) + { + this._y_scale = (yScale * this._y_scale_internal); + this._updateId++; + } + } + + public set z_scale(zScale: number) + { + if(this._z_scale != (zScale * this._z_scale_internal)) + { + this._z_scale = (zScale * 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: IVector3D; + 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: IVector3D; + let _local_21: IVector3D; + let _local_22: IVector3D; + const _local_2: IVector3D = new Vector3d(0, 1, 0); + const _local_3: IVector3D = new Vector3d(0, 0, 1); + const _local_4: IVector3D = 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: IVector3D = Vector3d.sum(Vector3d.product(_local_2, _local_8), Vector3d.product(_local_4, -(_local_9))); + const _local_11: IVector3D = new Vector3d(_local_3.x, _local_3.y, _local_3.z); + const _local_12: IVector3D = 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: IVector3D = new Vector3d(_local_10.x, _local_10.y, _local_10.z); + const _local_16: IVector3D = Vector3d.sum(Vector3d.product(_local_11, _local_13), Vector3d.product(_local_12, _local_14)); + const _local_17: IVector3D = 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: IVector3D = Vector3d.product(this._z, -(_arg_2)); + const _local_4: IVector3D = 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: IVector3D = new Vector3d(_local_2, _local_3, _local_4); + return _local_5; + } + + public getScreenPosition(k: IVector3D): IVector3D + { + let _local_2: IVector3D = 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: IVector3D = Vector3d.product(this._x, _local_5); + _local_7.add(Vector3d.product(this._y, _local_6)); + const _local_8: IVector3D = 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: IVector3D = new Vector3d((_arg_2.x * this._x_scale), (_arg_2.y * this._y_scale), (_arg_2.z * this._z_scale)); + const _local_11: IVector3D = new Vector3d((_arg_3.x * this._x_scale), (_arg_3.y * this._y_scale), (_arg_3.z * this._z_scale)); + const _local_12: IVector3D = 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: IVector3D = 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; + } +} diff --git a/packages/room/src/utils/RoomInstanceData.ts b/packages/room/src/utils/RoomInstanceData.ts new file mode 100644 index 0000000..37fd4cb --- /dev/null +++ b/packages/room/src/utils/RoomInstanceData.ts @@ -0,0 +1,234 @@ +import { IFurnitureStackingHeightMap, ILegacyWallGeometry, ISelectedRoomObjectData, ITileObjectMap } from '@nitrots/api'; +import { LegacyWallGeometry } from './LegacyWallGeometry'; +import { RoomCamera } from './RoomCamera'; +import { RoomFurnitureData } from './RoomFurnitureData'; +import { TileObjectMap } from './TileObjectMap'; + +export class RoomInstanceData +{ + private _roomId: number; + + private _modelName: string; + private _legacyGeometry: ILegacyWallGeometry; + private _tileObjectMap: ITileObjectMap; + private _roomCamera: RoomCamera; + private _selectedObject: ISelectedRoomObjectData; + private _placedObject: ISelectedRoomObjectData; + private _furnitureStackingHeightMap: IFurnitureStackingHeightMap; + + 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: ISelectedRoomObjectData): void + { + if(this._selectedObject) + { + this._selectedObject.dispose(); + } + + this._selectedObject = data; + } + + public setPlacedObject(data: ISelectedRoomObjectData): void + { + if(this._placedObject) + { + this._placedObject.dispose(); + } + + this._placedObject = data; + } + + public setFurnitureStackingHeightMap(heightMap: IFurnitureStackingHeightMap): 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: RoomFurnitureData): void + { + if(!data) return; + + this._floorStack.delete(data.id); + this._floorStack.set(data.id, data); + } + + public removePendingFunitureFloor(id: number): RoomFurnitureData + { + const existing = this._floorStack.get(id); + + if(!existing) return null; + + this._floorStack.delete(id); + + return existing; + } + + public getPendingFurnitureFloor(id: number): RoomFurnitureData + { + const existing = this._floorStack.get(id); + + if(!existing) return null; + + this._floorStack.delete(id); + + return existing; + } + + public getNextPendingFurnitureFloor(): RoomFurnitureData + { + if(!this._floorStack.size) return null; + + const keys = this._floorStack.keys(); + + return this.getPendingFurnitureFloor(keys.next().value as number); + } + + public addPendingFurnitureWall(data: RoomFurnitureData): void + { + if(!data) return; + + this._wallStack.delete(data.id); + this._wallStack.set(data.id, data); + } + + public removePendingFurnitureWall(id: number): RoomFurnitureData + { + const existing = this._wallStack.get(id); + + if(!existing) return null; + + this._wallStack.delete(id); + + return existing; + } + + public getPendingFurnitureWall(id: number): RoomFurnitureData + { + const existing = this._wallStack.get(id); + + if(!existing) return null; + + this._wallStack.delete(id); + + return existing; + } + + public getNextPendingFurnitureWall(): RoomFurnitureData + { + if(!this._wallStack.size) return null; + + const keys = this._wallStack.keys(); + + return this.getPendingFurnitureWall(keys.next().value as number); + } + + public addButtonMouseCursorOwner(k: string): boolean + { + const _local_2 = this._mouseButtonCursorOwners.indexOf(k); + + if(_local_2 === -1) + { + this._mouseButtonCursorOwners.push(k); + + return true; + } + + return false; + } + + public removeButtonMouseCursorOwner(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 hasButtonMouseCursorOwners(): boolean + { + return this._mouseButtonCursorOwners.length > 0; + } + + public get roomId(): number + { + return this._roomId; + } + + public get modelName(): string + { + return this._modelName; + } + + public get legacyGeometry(): ILegacyWallGeometry + { + return this._legacyGeometry; + } + + public get tileObjectMap(): ITileObjectMap + { + return this._tileObjectMap; + } + + public get roomCamera(): RoomCamera + { + return this._roomCamera; + } + + public get selectedObject(): ISelectedRoomObjectData + { + return this._selectedObject; + } + + public get placedObject(): ISelectedRoomObjectData + { + return this._placedObject; + } + + public get furnitureStackingHeightMap(): IFurnitureStackingHeightMap + { + return this._furnitureStackingHeightMap; + } +} diff --git a/packages/room/src/utils/RoomObjectBadgeImageAssetListener.ts b/packages/room/src/utils/RoomObjectBadgeImageAssetListener.ts new file mode 100644 index 0000000..a7d2de3 --- /dev/null +++ b/packages/room/src/utils/RoomObjectBadgeImageAssetListener.ts @@ -0,0 +1,23 @@ +import { IRoomObjectController } from '@nitrots/api'; + +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; + } +} diff --git a/packages/room/src/utils/RoomRotatingEffect.ts b/packages/room/src/utils/RoomRotatingEffect.ts new file mode 100644 index 0000000..217859a --- /dev/null +++ b/packages/room/src/utils/RoomRotatingEffect.ts @@ -0,0 +1,75 @@ +import { GetTickerTime } from '@nitrots/utils'; + +export class RoomRotatingEffect +{ + 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 _SafeStr_448: number = 0; + private static _SafeStr_4512: boolean = false; + private static _SafeStr_4513: number = 0; + private static _SafeStr_4514: number = 0; + private static _SafeStr_4515: number = 20000; + private static _SafeStr_4516: number = 5000; + private static _SafeStr_4524: ReturnType; + + public static init(_arg_1: number, _arg_2: number): void + { + this._SafeStr_4513 = 0; + this._SafeStr_4515 = _arg_1; + this._SafeStr_4516 = _arg_2; + this._SafeStr_4514 = GetTickerTime(); + this._SafeStr_448 = 1; + } + + public static turnVisualizationOn(): void + { + if((this._SafeStr_448 === 0) || (this._SafeStr_448 === 3)) return; + + if(!this._SafeStr_4524) this._SafeStr_4524 = setTimeout(() => this.turnVisualizationOff(), this._SafeStr_4516); + + const _local_1 = (GetTickerTime() - this._SafeStr_4514); + + if(_local_1 > (this._SafeStr_4515 + this._SafeStr_4516)) + { + this._SafeStr_448 = 3; + + return; + } + + this._SafeStr_4512 = true; + + if(_local_1 < this._SafeStr_4515) + { + this._SafeStr_448 = 1; + + return; + } + + this._SafeStr_448 = 2; + this._SafeStr_4513 = ((_local_1 - this._SafeStr_4515) / this._SafeStr_4516); + } + + public static turnVisualizationOff(): void + { + this._SafeStr_4512 = false; + + clearTimeout(this._SafeStr_4524); + + this._SafeStr_4524 = null; + } + + public static isVisualizationOn(): boolean + { + return (this._SafeStr_4512 && this.isRunning()); + } + + private static isRunning(): boolean + { + if((this._SafeStr_448 === 1) || (this._SafeStr_448 === 2)) return true; + + return false; + } +} diff --git a/packages/room/src/utils/RoomShakingEffect.ts b/packages/room/src/utils/RoomShakingEffect.ts new file mode 100644 index 0000000..b89a64c --- /dev/null +++ b/packages/room/src/utils/RoomShakingEffect.ts @@ -0,0 +1,75 @@ +import { GetTickerTime } from '@nitrots/utils'; + +export class RoomShakingEffect +{ + 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 _SafeStr_448: number = 0; + private static _SafeStr_4512: boolean = false; + private static _SafeStr_4513: number; + private static _SafeStr_4514: number = 0; + private static _SafeStr_4515: number = 20000; + private static _SafeStr_4516: number = 5000; + private static _SafeStr_4524: ReturnType; + + public static init(_arg_1: number, _arg_2: number): void + { + this._SafeStr_4513 = 0; + this._SafeStr_4515 = _arg_1; + this._SafeStr_4516 = _arg_2; + this._SafeStr_4514 = GetTickerTime(); + this._SafeStr_448 = 1; + } + + public static turnVisualizationOn(): void + { + if((this._SafeStr_448 === 0) || (this._SafeStr_448 === 3)) return; + + if(!this._SafeStr_4524) this._SafeStr_4524 = setTimeout(() => this.turnVisualizationOff(), this._SafeStr_4516); + + const _local_1 = (GetTickerTime() - this._SafeStr_4514); + + if(_local_1 > (this._SafeStr_4515 + this._SafeStr_4516)) + { + this._SafeStr_448 = 3; + + return; + } + + this._SafeStr_4512 = true; + + if(_local_1 < this._SafeStr_4515) + { + this._SafeStr_448 = 1; + + return; + } + + this._SafeStr_448 = 2; + this._SafeStr_4513 = ((_local_1 - this._SafeStr_4515) / this._SafeStr_4516); + } + + public static turnVisualizationOff(): void + { + this._SafeStr_4512 = false; + + clearTimeout(this._SafeStr_4524); + + this._SafeStr_4524 = null; + } + + public static isVisualizationOn(): boolean + { + return (this._SafeStr_4512 && this.isRunning()); + } + + private static isRunning(): boolean + { + if((this._SafeStr_448 === 1) || (this._SafeStr_448 === 2)) return true; + + return false; + } +} diff --git a/packages/room/src/utils/SelectedRoomObjectData.ts b/packages/room/src/utils/SelectedRoomObjectData.ts new file mode 100644 index 0000000..f88d5b5 --- /dev/null +++ b/packages/room/src/utils/SelectedRoomObjectData.ts @@ -0,0 +1,95 @@ +import { IObjectData, ISelectedRoomObjectData, IVector3D } from '@nitrots/api'; +import { Vector3d } from '@nitrots/utils'; + +export class SelectedRoomObjectData implements ISelectedRoomObjectData +{ + private _id: number = 0; + private _category: number = 0; + private _operation: string = ''; + private _loc: IVector3D = null; + private _dir: IVector3D = 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(): IVector3D + { + return this._loc; + } + + public get dir(): IVector3D + { + return this._dir; + } + + public get typeId(): number + { + return this._typeId; + } + + public get instanceData(): string + { + return this._instanceData; + } + + public get stuffData(): IObjectData + { + return this._stuffData; + } + + public get state(): number + { + return this._state; + } + + public get animFrame(): number + { + return this._animFrame; + } + + public get posture(): string + { + return this._posture; + } + + public dispose(): void + { + this._loc = null; + this._dir = null; + } +} diff --git a/packages/room/src/utils/SpriteDataCollector.ts b/packages/room/src/utils/SpriteDataCollector.ts new file mode 100644 index 0000000..d29996f --- /dev/null +++ b/packages/room/src/utils/SpriteDataCollector.ts @@ -0,0 +1,453 @@ +import { IPlaneDrawingData, IPlaneVisualization, IRoomObjectSpriteVisualization, IRoomPlane, IRoomRenderingCanvas, RoomObjectCategory, RoomObjectSpriteData } from '@nitrots/api'; +import { GetStage, Vector3d } from '@nitrots/utils'; +import { Point, Rectangle } from 'pixi.js'; +import { RoomEngine } from '../RoomEngine'; +import { PlaneDrawingData } from '../object'; + +export class SpriteDataCollector +{ + private static MANNEQUIN_MAGIC_X_OFFSET: number = 1; + private static MANNEQUIN_MAGIC_Y_OFFSET: number = -16; + private static AVATAR_WATER_EFFECT_MAGIC_Y_OFFSET: number = -52; + private static MAX_EXTERNAL_IMAGE_COUNT: number = 30; + + private maxZ: number; + private spriteCount: number = 0; + private externalImageCount: number = 0; + + private static addMannequinSprites(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.MANNEQUIN_MAGIC_X_OFFSET)); + sprite.y = (sprite.y + ((data.y + data.height) + SpriteDataCollector.MANNEQUIN_MAGIC_Y_OFFSET)); + sprite.z = (sprite.z + data.z); + datas.push(sprite); + } + } + } + } + else + { + datas.push(data); + } + } + + return datas; + } + + private static sortSpriteDataObjects(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 isSpriteInViewPort(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 sortQuadPoints(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 getFurniData(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.getRoomObjects(_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.AVATAR_WATER_EFFECT_MAGIC_Y_OFFSET); + } + + _local_6.push(_local_16); + } + } + } + } + } + + _local_6 = SpriteDataCollector.addMannequinSprites(_local_6, _arg_3); + _local_6.sort(SpriteDataCollector.sortSpriteDataObjects); + + 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.isSpriteInViewPort(_local_9, k, _arg_2))) && ((_arg_4 < 0) || (!(_local_9.objectId == _arg_4))))) + { + _local_5.push(this.getSpriteDataObject(_local_9, k, _arg_2, _arg_3)); + + if(!this.maxZ) this.maxZ = _local_9.z; + + this.spriteCount++; + } + } + + return JSON.stringify(_local_5); + } + + public getRoomRenderingModifiers(k: RoomEngine): string + { + return JSON.stringify(new Object()); + } + + private getSpriteDataObject(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.externalImageCount++; + + if(this.externalImageCount > SpriteDataCollector.MAX_EXTERNAL_IMAGE_COUNT) _local_5.name = 'box'; + } + + if(k.posture) _local_5.posture = k.posture; + + return _local_5; + } + + private makeBackgroundPlane(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.sortQuadPoints(_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.maxZ) _local_9 = Math.max(this.maxZ, _local_9); + } + else + { + _local_9 = ((this.maxZ) ? this.maxZ : 0); + } + + _local_9 = (_local_9 + ((this.spriteCount * 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 sortRoomPlanes(k: IRoomPlane[], _arg_2: IRoomRenderingCanvas, _arg_3: RoomEngine): { plane: IRoomPlane, z: number }[] + { + const _local_4: Map = new Map(); + + let _local_5 = 1; + + if(this.maxZ) + { + _local_5 = (_local_5 + this.maxZ); + } + + 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.getPlaneSortableSprites(); + + 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 getRoomPlanes(k: Rectangle, _arg_2: IRoomRenderingCanvas, _arg_3: RoomEngine, _arg_4: number): IPlaneDrawingData[] + { + const _local_5: IPlaneDrawingData[] = []; + + 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.sortRoomPlanes(visualization.planes, _arg_2, _arg_3); + const _local_10 = GetStage(); + + 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.leftSide); + 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.rightSide)); + const _local_18 = _local_8.getScreenPoint(Vector3d.sum(_local_14, _local_12.rightSide)); + + _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.sortQuadPoints(_local_15, _local_16, _local_17, _local_18); + + /* for(const _local_23 of _local_12.getDrawingDatas(_local_8)) + { + _local_23.cornerPoints = _local_22; + _local_23.z = _local_11.z; + + _local_5.push(_local_23); + } */ + } + } + + _local_5.unshift(this.makeBackgroundPlane(k, _arg_4, _local_5)); + } + + return _local_5; + } +} diff --git a/packages/room/src/utils/TileObjectMap.ts b/packages/room/src/utils/TileObjectMap.ts new file mode 100644 index 0000000..5c7ae89 --- /dev/null +++ b/packages/room/src/utils/TileObjectMap.ts @@ -0,0 +1,122 @@ +import { IRoomObject, ITileObjectMap, RoomObjectVariable } from '@nitrots/api'; +import { NitroLogger } from '@nitrots/utils'; + +export class TileObjectMap implements ITileObjectMap +{ + 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.addRoomObject(_local_2); + } + + public dispose(): void + { + this._tileObjectMap = null; + this._width = 0; + this._height = 0; + } + + public getObjectIntTile(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 setObjectInTile(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 addRoomObject(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.getObjectIntTile(x, y); + + if((!(roomObject)) || ((!(roomObject === k)) && (roomObject.getLocation().z <= location.z))) + { + this.setObjectInTile(x, y, k); + } + + x++; + } + + y++; + } + } +} diff --git a/packages/room/src/utils/index.ts b/packages/room/src/utils/index.ts new file mode 100644 index 0000000..3b335e5 --- /dev/null +++ b/packages/room/src/utils/index.ts @@ -0,0 +1,14 @@ +export * from './FurnitureStackingHeightMap'; +export * from './LegacyWallGeometry'; +export * from './RoomCamera'; +export * from './RoomData'; +export * from './RoomEnterEffect'; +export * from './RoomFurnitureData'; +export * from './RoomGeometry'; +export * from './RoomInstanceData'; +export * from './RoomObjectBadgeImageAssetListener'; +export * from './RoomRotatingEffect'; +export * from './RoomShakingEffect'; +export * from './SelectedRoomObjectData'; +export * from './SpriteDataCollector'; +export * from './TileObjectMap'; diff --git a/packages/room/tsconfig.json b/packages/room/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/room/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/session/.eslintrc.json b/packages/session/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/session/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/session/.gitignore b/packages/session/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/session/.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/packages/session/index.ts b/packages/session/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/session/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/session/package.json b/packages/session/package.json new file mode 100644 index 0000000..65b6d7f --- /dev/null +++ b/packages/session/package.json @@ -0,0 +1,25 @@ +{ + "name": "@nitrots/session", + "description": "Nitro session module", + "version": "1.0.0", + "type": "module", + "license": "GPL-3.0", + "scripts": { + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/assets": "1.0.0", + "@nitrots/communication": "1.0.0", + "@nitrots/configuration": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "@nitrots/events": "1.0.0", + "@nitrots/localization": "1.0.0", + "pixi.js": "^8.0.4" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/session/src/GetRoomSessionManager.ts b/packages/session/src/GetRoomSessionManager.ts new file mode 100644 index 0000000..63ea5fa --- /dev/null +++ b/packages/session/src/GetRoomSessionManager.ts @@ -0,0 +1,5 @@ +import { RoomSessionManager } from './RoomSessionManager'; + +const roomSessionManager = new RoomSessionManager(); + +export const GetRoomSessionManager = () => roomSessionManager; diff --git a/packages/session/src/GetSessionDataManager.ts b/packages/session/src/GetSessionDataManager.ts new file mode 100644 index 0000000..e0a4aab --- /dev/null +++ b/packages/session/src/GetSessionDataManager.ts @@ -0,0 +1,5 @@ +import { SessionDataManager } from './SessionDataManager'; + +const sessionDataManager = new SessionDataManager(); + +export const GetSessionDataManager = () => sessionDataManager; diff --git a/packages/session/src/GroupInformationManager.ts b/packages/session/src/GroupInformationManager.ts new file mode 100644 index 0000000..fe93aeb --- /dev/null +++ b/packages/session/src/GroupInformationManager.ts @@ -0,0 +1,30 @@ +import { IGroupInformationManager } from '@nitrots/api'; +import { GetCommunication, GetHabboGroupBadgesMessageComposer, HabboGroupBadgesMessageEvent, RoomReadyMessageEvent } from '@nitrots/communication'; + +export class GroupInformationManager implements IGroupInformationManager +{ + private _groupBadges: Map = new Map(); + + public init(): void + { + GetCommunication().registerMessageEvent(new RoomReadyMessageEvent(this.onRoomReadyMessageEvent.bind(this))); + GetCommunication().registerMessageEvent(new HabboGroupBadgesMessageEvent(this.onGroupBadgesEvent.bind(this))); + } + + private onRoomReadyMessageEvent(event: RoomReadyMessageEvent): void + { + GetCommunication().connection.send(new GetHabboGroupBadgesMessageComposer()); + } + + private onGroupBadgesEvent(event: HabboGroupBadgesMessageEvent): void + { + const parser = event.getParser(); + + for(const [groupId, badgeId] of parser.badges.entries()) this._groupBadges.set(groupId, badgeId); + } + + public getGroupBadge(groupId: number): string + { + return this._groupBadges.get(groupId) ?? ''; + } +} diff --git a/packages/session/src/HabboClubLevelEnum.ts b/packages/session/src/HabboClubLevelEnum.ts new file mode 100644 index 0000000..3986c8e --- /dev/null +++ b/packages/session/src/HabboClubLevelEnum.ts @@ -0,0 +1,6 @@ +export class HabboClubLevelEnum +{ + public static NO_CLUB: number = 0; + public static CLUB: number = 1; + public static VIP: number = 2; +} diff --git a/packages/session/src/IgnoredUsersManager.ts b/packages/session/src/IgnoredUsersManager.ts new file mode 100644 index 0000000..77f1cd0 --- /dev/null +++ b/packages/session/src/IgnoredUsersManager.ts @@ -0,0 +1,88 @@ +import { IIgnoredUsersManager } from '@nitrots/api'; +import { GetCommunication, GetIgnoredUsersComposer, IgnoreResultEvent, IgnoreUserComposer, IgnoreUserIdComposer, IgnoredUsersEvent, UnignoreUserComposer } from '@nitrots/communication'; + +export class IgnoredUsersManager implements IIgnoredUsersManager +{ + private _ignoredUsers: string[] = []; + + public init(): void + { + GetCommunication().registerMessageEvent(new IgnoredUsersEvent(this.onIgnoredUsersEvent.bind(this))); + GetCommunication().registerMessageEvent(new IgnoreResultEvent(this.onIgnoreResultEvent.bind(this))); + } + + public requestIgnoredUsers(username: string): void + { + GetCommunication().connection.send(new GetIgnoredUsersComposer(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.addUserToIgnoreList(name); + return; + case 2: + this.addUserToIgnoreList(name); + this._ignoredUsers.shift(); + return; + case 3: + this.removeUserFromIgnoreList(name); + return; + } + } + + private addUserToIgnoreList(name: string): void + { + if(this._ignoredUsers.indexOf(name) < 0) this._ignoredUsers.push(name); + } + + private removeUserFromIgnoreList(name: string): void + { + const index = this._ignoredUsers.indexOf(name); + + if(index >= 0) this._ignoredUsers.splice(index, 1); + } + + public ignoreUserId(id: number): void + { + GetCommunication().connection.send(new IgnoreUserIdComposer(id)); + } + + public ignoreUser(name: string): void + { + GetCommunication().connection.send(new IgnoreUserComposer(name)); + } + + public unignoreUser(name: string): void + { + GetCommunication().connection.send(new UnignoreUserComposer(name)); + } + + public isIgnored(name: string): boolean + { + return (this._ignoredUsers.indexOf(name) >= 0); + } +} diff --git a/packages/session/src/RoomPetData.ts b/packages/session/src/RoomPetData.ts new file mode 100644 index 0000000..3cf720d --- /dev/null +++ b/packages/session/src/RoomPetData.ts @@ -0,0 +1,297 @@ +import { IRoomPetData } from '@nitrots/api'; + +export class RoomPetData implements IRoomPetData +{ + 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 _skillThresholds: 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 _adultLevel: 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 skillTresholds(): number[] + { + return this._skillThresholds; + } + + public set skillTresholds(k: number[]) + { + this._skillThresholds = 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 adultLevel(): number + { + return this._adultLevel; + } +} diff --git a/packages/session/src/RoomSession.ts b/packages/session/src/RoomSession.ts new file mode 100644 index 0000000..2b4e2c9 --- /dev/null +++ b/packages/session/src/RoomSession.ts @@ -0,0 +1,413 @@ +import { IRoomSession, IUserDataManager, RoomControllerLevel, RoomTradingLevelEnum } from '@nitrots/api'; +import { BotRemoveComposer, ChangeQueueMessageComposer, CompostPlantMessageComposer, FurnitureMultiStateComposer, GetCommunication, GetPetCommandsComposer, HarvestPetMessageComposer, MoodlightSettingsComposer, MoodlightSettingsSaveComposer, MoodlightTogggleStateComposer, NewUserExperienceScriptProceedComposer, OpenPetPackageMessageComposer, OpenPresentComposer, PeerUsersClassificationMessageComposer, PetMountComposer, PetRemoveComposer, PollAnswerComposer, PollRejectComposer, PollStartComposer, RemovePetSaddleComposer, RoomAmbassadorAlertComposer, RoomBanUserComposer, RoomDoorbellAccessComposer, RoomEnterComposer, RoomGiveRightsComposer, RoomKickUserComposer, RoomModerationSettings, RoomMuteUserComposer, RoomTakeRightsComposer, RoomUnitActionComposer, RoomUnitChatComposer, RoomUnitChatShoutComposer, RoomUnitChatWhisperComposer, RoomUnitDanceComposer, RoomUnitPostureComposer, RoomUnitSignComposer, RoomUnitTypingStartComposer, RoomUnitTypingStopComposer, RoomUsersClassificationMessageComposer, SetClothingChangeDataMessageComposer, TogglePetBreedingComposer, TogglePetRidingComposer, UsePetProductComposer, UserMottoComposer, VotePollCounterMessageComposer } from '@nitrots/communication'; +import { RoomSessionEvent } from '@nitrots/events'; +import { UserDataManager } from './UserDataManager'; + +export class RoomSession implements IRoomSession +{ + private _userData: IUserDataManager = new UserDataManager(); + + private _roomId: number = 0; + private _password: string = null; + private _state: string = RoomSessionEvent.CREATED; + private _tradeMode: number = RoomTradingLevelEnum.NO_TRADING; + private _doorMode: number = 0; + private _allowPets: boolean = false; + private _controllerLevel: number = RoomControllerLevel.NONE; + private _ownRoomIndex: number = -1; + private _isGuildRoom: boolean = false; + private _isRoomOwner: boolean = false; + private _isDecorating: boolean = false; + private _isSpectator: boolean = false; + + private _moderationSettings: RoomModerationSettings = null; + + 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 || !GetCommunication().connection) return false; + + this._state = RoomSessionEvent.STARTED; + + return this.enterRoom(); + } + + private enterRoom(): boolean + { + if(!GetCommunication().connection) return false; + + GetCommunication().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 + { + GetCommunication().connection.send(new RoomUnitChatComposer(text, styleId)); + } + + public sendShoutMessage(text: string, styleId: number): void + { + GetCommunication().connection.send(new RoomUnitChatShoutComposer(text, styleId)); + } + + public sendWhisperMessage(recipientName: string, text: string, styleId: number): void + { + GetCommunication().connection.send(new RoomUnitChatWhisperComposer(recipientName, text, styleId)); + } + + public sendChatTypingMessage(isTyping: boolean): void + { + if(isTyping) GetCommunication().connection.send(new RoomUnitTypingStartComposer()); + else GetCommunication().connection.send(new RoomUnitTypingStopComposer()); + } + + public sendMottoMessage(motto: string): void + { + GetCommunication().connection.send(new UserMottoComposer(motto)); + } + + public sendDanceMessage(danceId: number): void + { + GetCommunication().connection.send(new RoomUnitDanceComposer(danceId)); + } + + public sendExpressionMessage(expression: number): void + { + GetCommunication().connection.send(new RoomUnitActionComposer(expression)); + } + + public sendSignMessage(sign: number): void + { + if((sign < 0) || (sign > 17)) return; + + GetCommunication().connection.send(new RoomUnitSignComposer(sign)); + } + + public sendPostureMessage(posture: number): void + { + GetCommunication().connection.send(new RoomUnitPostureComposer(posture)); + } + + public sendDoorbellApprovalMessage(userName: string, flag: boolean): void + { + GetCommunication().connection.send(new RoomDoorbellAccessComposer(userName, flag)); + } + + public sendAmbassadorAlertMessage(userId: number): void + { + GetCommunication().connection.send(new RoomAmbassadorAlertComposer(userId)); + } + + public sendKickMessage(userId: number): void + { + GetCommunication().connection.send(new RoomKickUserComposer(userId)); + } + + public sendMuteMessage(userId: number, minutes: number): void + { + GetCommunication().connection.send(new RoomMuteUserComposer(userId, minutes, this._roomId)); + } + + public sendBanMessage(userId: number, type: string): void + { + GetCommunication().connection.send(new RoomBanUserComposer(userId, this._roomId, type)); + } + + public sendGiveRightsMessage(userId: number): void + { + GetCommunication().connection.send(new RoomGiveRightsComposer(userId)); + } + + public sendTakeRightsMessage(userId: number): void + { + GetCommunication().connection.send(new RoomTakeRightsComposer(userId)); + } + + public sendPollStartMessage(pollId: number): void + { + GetCommunication().connection.send(new PollStartComposer(pollId)); + } + + public sendPollRejectMessage(pollId: number): void + { + GetCommunication().connection.send(new PollRejectComposer(pollId)); + } + + public sendPollAnswerMessage(pollId: number, questionId: number, answers: string[]): void + { + GetCommunication().connection.send(new PollAnswerComposer(pollId, questionId, answers)); + } + + public sendPeerUsersClassificationMessage(userClassType: string): void + { + GetCommunication().connection.send(new PeerUsersClassificationMessageComposer(userClassType)); + } + + public sendOpenPetPackageMessage(objectId: number, petName: string): void + { + GetCommunication().connection.send(new OpenPetPackageMessageComposer(objectId, petName)); + } + + public sendRoomUsersClassificationMessage(userClassType: string): void + { + GetCommunication().connection.send(new RoomUsersClassificationMessageComposer(userClassType)); + } + + public updateMoodlightData(id: number, effectId: number, color: number, brightness: number, apply: boolean): void + { + let colorString = '000000' + color.toString(16).toUpperCase(); + colorString = '#' + colorString.substring((colorString.length - 6)); + + GetCommunication().connection.send(new MoodlightSettingsSaveComposer(id, effectId, colorString, brightness, apply)); + } + + public toggleMoodlightState(): void + { + GetCommunication().connection.send(new MoodlightTogggleStateComposer()); + } + + public pickupPet(id: number): void + { + if(!GetCommunication().connection) return; + + GetCommunication().connection.send(new PetRemoveComposer(id)); + } + + public pickupBot(id: number): void + { + if(!GetCommunication().connection) return; + + GetCommunication().connection.send(new BotRemoveComposer(id)); + } + + public requestMoodlightSettings(): void + { + if(!GetCommunication().connection) return; + + GetCommunication().connection.send(new MoodlightSettingsComposer()); + } + + public openGift(objectId: number): void + { + GetCommunication().connection.send(new OpenPresentComposer(objectId)); + } + + public mountPet(id: number): void + { + GetCommunication().connection.send(new PetMountComposer(id, true)); + } + + public dismountPet(id: number): void + { + GetCommunication().connection.send(new PetMountComposer(id, false)); + } + + public usePetProduct(itemId: number, petId: number): void + { + GetCommunication().connection.send(new UsePetProductComposer(itemId, petId)); + } + + public removePetSaddle(id: number): void + { + GetCommunication().connection.send(new RemovePetSaddleComposer(id)); + } + + public togglePetBreeding(id: number): void + { + GetCommunication().connection.send(new TogglePetBreedingComposer(id)); + } + + public togglePetRiding(id: number): void + { + GetCommunication().connection.send(new TogglePetRidingComposer(id)); + } + + public useMultistateItem(id: number): void + { + GetCommunication().connection.send(new FurnitureMultiStateComposer(id)); + } + + public harvestPet(id: number): void + { + GetCommunication().connection.send(new HarvestPetMessageComposer(id)); + } + + public compostPlant(id: number): void + { + GetCommunication().connection.send(new CompostPlantMessageComposer(id)); + } + + public requestPetCommands(id: number):void + { + GetCommunication().connection.send(new GetPetCommandsComposer(id)); + } + + public sendScriptProceed(): void + { + GetCommunication().connection.send(new NewUserExperienceScriptProceedComposer()); + } + + public sendUpdateClothingChangeFurniture(objectId: number, gender: string, look: string):void + { + GetCommunication().connection.send(new SetClothingChangeDataMessageComposer(objectId, gender, look)); + } + + public changeQueue(targetQueue: number): void + { + GetCommunication().connection.send(new ChangeQueueMessageComposer(targetQueue)); + } + + public votePoll(counter: number): void + { + GetCommunication().connection.send(new VotePollCounterMessageComposer(counter)); + } + + public get userDataManager(): IUserDataManager + { + 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 isPrivateRoom(): 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(): RoomModerationSettings + { + return this._moderationSettings; + } + + public set moderationSettings(parser: RoomModerationSettings) + { + this._moderationSettings = parser; + } +} diff --git a/packages/session/src/RoomSessionManager.ts b/packages/session/src/RoomSessionManager.ts new file mode 100644 index 0000000..073b9c8 --- /dev/null +++ b/packages/session/src/RoomSessionManager.ts @@ -0,0 +1,173 @@ +import { IRoomHandlerListener, IRoomSession, IRoomSessionManager } from '@nitrots/api'; +import { GetCommunication } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionEvent } from '@nitrots/events'; +import { RoomSession } from './RoomSession'; +import { BaseHandler, GenericErrorHandler, PetPackageHandler, PollHandler, RoomChatHandler, RoomDataHandler, RoomDimmerPresetsHandler, RoomPermissionsHandler, RoomPresentHandler, RoomSessionHandler, RoomUsersHandler, WordQuizHandler } from './handler'; + +export class RoomSessionManager implements IRoomSessionManager, IRoomHandlerListener +{ + private _handlers: BaseHandler[] = []; + private _sessions: Map = new Map(); + private _pendingSession: IRoomSession = null; + + private _sessionStarting: boolean = false; + private _viewerSession: IRoomSession = null; + + public async init(): Promise + { + this.createHandlers(); + this.processPendingSession(); + } + + private createHandlers(): void + { + const connection = GetCommunication().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), + new WordQuizHandler(connection, this), + new PollHandler(connection, this), + new PetPackageHandler(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); + } + } + + private processPendingSession(): void + { + if(!this._pendingSession) 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 + { + this._sessionStarting = true; + + if(this._sessions.get(this.getRoomId(roomSession.roomId))) this.removeSession(roomSession.roomId, false); + + this._sessions.set(this.getRoomId(roomSession.roomId), roomSession); + + GetEventDispatcher().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; + } + + GetEventDispatcher().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)); + + GetEventDispatcher().dispatchEvent(new RoomSessionEvent(RoomSessionEvent.ENDED, session, openLandingView)); + } + + 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 viewerSession(): IRoomSession + { + return this._viewerSession; + } +} diff --git a/packages/session/src/RoomUserData.ts b/packages/session/src/RoomUserData.ts new file mode 100644 index 0000000..6cddd62 --- /dev/null +++ b/packages/session/src/RoomUserData.ts @@ -0,0 +1,258 @@ +import { IRoomUserData } from '@nitrots/api'; + +export class RoomUserData implements IRoomUserData +{ + 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: number = 0; + 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 _isModerator: 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 groupId(): number + { + return this._groupID; + } + + public set groupId(groupId: number) + { + this._groupID = groupId; + } + + 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._isModerator; + } + + public set isModerator(k: boolean) + { + this._isModerator = k; + } +} diff --git a/packages/session/src/SessionDataManager.ts b/packages/session/src/SessionDataManager.ts new file mode 100644 index 0000000..ee93e7e --- /dev/null +++ b/packages/session/src/SessionDataManager.ts @@ -0,0 +1,532 @@ +import { ICommunicationManager, IFurnitureData, IGroupInformationManager, IMessageComposer, IProductData, ISessionDataManager, NoobnessLevelEnum, SecurityLevel } from '@nitrots/api'; +import { AccountSafetyLockStatusChangeMessageEvent, AccountSafetyLockStatusChangeParser, AvailabilityStatusMessageEvent, ChangeUserNameResultMessageEvent, EmailStatusResultEvent, FigureUpdateEvent, GetCommunication, GetUserTagsComposer, InClientLinkEvent, MysteryBoxKeysEvent, NoobnessLevelMessageEvent, PetRespectComposer, PetScratchFailedMessageEvent, RoomReadyMessageEvent, RoomUnitChatComposer, UserInfoEvent, UserNameChangeMessageEvent, UserPermissionsEvent, UserRespectComposer, UserTagsMessageEvent } from '@nitrots/communication'; +import { GetConfiguration } from '@nitrots/configuration'; +import { GetEventDispatcher, MysteryBoxKeysUpdateEvent, NitroSettingsEvent, SessionDataPreferencesEvent, UserNameUpdateEvent } from '@nitrots/events'; +import { CreateLinkEvent, HabboWebTools } from '@nitrots/utils'; +import { Texture } from 'pixi.js'; +import { GroupInformationManager } from './GroupInformationManager'; +import { IgnoredUsersManager } from './IgnoredUsersManager'; +import { BadgeImageManager } from './badge/BadgeImageManager'; +import { FurnitureDataLoader } from './furniture/FurnitureDataLoader'; +import { ProductDataLoader } from './product/ProductDataLoader'; + +export class SessionDataManager implements ISessionDataManager +{ + 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 _safetyLocked: boolean; + + private _ignoredUsersManager: IgnoredUsersManager = new IgnoredUsersManager(); + private _groupInformationManager: IGroupInformationManager = new GroupInformationManager(); + + private _clubLevel: number = 0; + private _securityLevel: number = 0; + private _isAmbassador: boolean = false; + private _noobnessLevel: number = -1; + private _isEmailVerified: boolean = false; + + private _systemOpen: boolean = false; + private _systemShutdown: boolean = false; + private _isAuthenticHabbo: boolean = false; + private _isRoomCameraFollowDisabled: boolean = false; + private _uiFlags: number = 0; + + private _floorItems: Map = new Map(); + private _wallItems: Map = new Map(); + private _products: Map = new Map(); + private _furnitureData: FurnitureDataLoader = new FurnitureDataLoader(this._floorItems, this._wallItems); + private _productData: ProductDataLoader = new ProductDataLoader(this._products); + private _tags: string[] = []; + + private _badgeImageManager: BadgeImageManager = new BadgeImageManager(); + + constructor() + { + this.resetUserInfo(); + + this.onNitroSettingsEvent = this.onNitroSettingsEvent.bind(this); + } + + public async init(): Promise + { + await Promise.all([ + this._furnitureData.init(), + this._productData.init(), + this._badgeImageManager.init(), + this._ignoredUsersManager.init(), + this._groupInformationManager.init() + ]); + + GetCommunication().registerMessageEvent(new FigureUpdateEvent((event: FigureUpdateEvent) => + { + this._figure = event.getParser().figure; + this._gender = event.getParser().gender; + + HabboWebTools.updateFigure(this._figure); + })); + + GetCommunication().registerMessageEvent(new UserInfoEvent(this.onUserInfoEvent.bind(this))); + GetCommunication().registerMessageEvent(new UserPermissionsEvent(this.onUserPermissionsEvent.bind(this))); + GetCommunication().registerMessageEvent(new AvailabilityStatusMessageEvent(this.onAvailabilityStatusMessageEvent.bind(this))); + GetCommunication().registerMessageEvent(new PetScratchFailedMessageEvent(this.onPetRespectFailed.bind(this))); + GetCommunication().registerMessageEvent(new ChangeUserNameResultMessageEvent(this.onChangeNameUpdateEvent.bind(this))); + GetCommunication().registerMessageEvent(new UserNameChangeMessageEvent(this.onUserNameChangeMessageEvent.bind(this))); + GetCommunication().registerMessageEvent(new UserTagsMessageEvent(this.onUserTags.bind(this))); + GetCommunication().registerMessageEvent(new RoomReadyMessageEvent(this.onRoomModelNameEvent.bind(this))); + GetCommunication().registerMessageEvent(new InClientLinkEvent(this.onInClientLinkEvent.bind(this))); + GetCommunication().registerMessageEvent(new MysteryBoxKeysEvent(this.onMysteryBoxKeysEvent.bind(this))); + GetCommunication().registerMessageEvent(new NoobnessLevelMessageEvent(this.onNoobnessLevelMessageEvent.bind(this))); + GetCommunication().registerMessageEvent(new AccountSafetyLockStatusChangeMessageEvent(this.onAccountSafetyLockStatusChangeMessageEvent.bind(this))); + GetCommunication().registerMessageEvent(new EmailStatusResultEvent(this.onEmailStatus.bind(this))); + + GetEventDispatcher().addEventListener(NitroSettingsEvent.SETTINGS_UPDATED, this.onNitroSettingsEvent); + } + + private resetUserInfo(): void + { + this._userId = 0; + this._name = null; + this._figure = null; + this._gender = null; + this._realName = null; + this._canChangeName = false; + this._safetyLocked = false; + } + + public getAllFurnitureData(): IFurnitureData[] + { + return [ ...Array.from(this._floorItems.values()), ...Array.from(this._wallItems.values()) ]; + } + + 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._safetyLocked = userInfo.safetyLocked; + + this._ignoredUsersManager.requestIgnoredUsers(userInfo.username); + } + + 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 onPetRespectFailed(event: PetScratchFailedMessageEvent): void + { + if(!event || !event.connection) return; + + this._respectsPetLeft++; + } + + private onChangeNameUpdateEvent(event: ChangeUserNameResultMessageEvent): void + { + if(!event || !event.connection) return; + + const parser = event.getParser(); + + if(!parser) return; + + if(parser.resultCode !== ChangeUserNameResultMessageEvent.NAME_OK) return; + + this._canChangeName = false; + + GetEventDispatcher().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; + + GetEventDispatcher().dispatchEvent(new UserNameUpdateEvent(this._name)); + } + + private onUserTags(event: UserTagsMessageEvent): void + { + if(!event || !event.connection) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._tags = parser.tags; + } + + private onRoomModelNameEvent(event: RoomReadyMessageEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + HabboWebTools.roomVisited(parser.roomId); + } + + private onInClientLinkEvent(event: InClientLinkEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + CreateLinkEvent(parser.link); + } + + private onMysteryBoxKeysEvent(event: MysteryBoxKeysEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + GetEventDispatcher().dispatchEvent(new MysteryBoxKeysUpdateEvent(parser.boxColor, parser.keyColor)); + } + + private onNoobnessLevelMessageEvent(event: NoobnessLevelMessageEvent): void + { + this._noobnessLevel = event.getParser().noobnessLevel; + + if(this._noobnessLevel !== NoobnessLevelEnum.OLD_IDENTITY) GetConfiguration().setValue('new.identity', 1); + } + + private onAccountSafetyLockStatusChangeMessageEvent(event: AccountSafetyLockStatusChangeMessageEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._safetyLocked = (parser.status === AccountSafetyLockStatusChangeParser.SAFETY_LOCK_STATUS_LOCKED); + } + + private onEmailStatus(event: EmailStatusResultEvent): void + { + this._isEmailVerified = event?.getParser()?.isVerified ?? false; + } + + private onNitroSettingsEvent(event: NitroSettingsEvent): void + { + this._isRoomCameraFollowDisabled = event.cameraFollow; + this._uiFlags = event.flags; + + GetEventDispatcher().dispatchEvent(new SessionDataPreferencesEvent(this._uiFlags)); + } + + 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; + } + + return null; + } + + 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; + } + + return null; + } + + public getProductData(type: string): IProductData + { + 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 getUserTags(roomUnitId: number): string[] + { + if(roomUnitId < 0) return; + + this.send(new GetUserTagsComposer(roomUnitId)); + } + + 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 ignoreUser(name: string): void + { + this._ignoredUsersManager.ignoreUser(name); + } + + public unignoreUser(name: string): void + { + this._ignoredUsersManager.unignoreUser(name); + } + + public isUserIgnored(name: string): boolean + { + return this._ignoredUsersManager.isIgnored(name); + } + + public getGroupBadge(groupId: number): string + { + return this._groupInformationManager.getGroupBadge(groupId); + } + + public send(composer: IMessageComposer): void + { + GetCommunication().connection.send(composer); + } + + public get communication(): ICommunicationManager + { + return GetCommunication(); + } + + 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 groupInformationManager(): IGroupInformationManager + { + return this._groupInformationManager; + } + + 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 isEmailVerified(): boolean + { + return this._isEmailVerified; + } + + public get isNoob(): boolean + { + return (this._noobnessLevel !== NoobnessLevelEnum.OLD_IDENTITY); + } + + public get isRealNoob(): boolean + { + return (this._noobnessLevel === NoobnessLevelEnum.REAL_NOOB); + } + + 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 isCameraFollowDisabled(): boolean + { + return this._isRoomCameraFollowDisabled; + } + + public get uiFlags(): number + { + return this._uiFlags; + } + + public get tags(): string[] + { + return this._tags; + } +} diff --git a/packages/session/src/UserDataManager.ts b/packages/session/src/UserDataManager.ts new file mode 100644 index 0000000..41f8be6 --- /dev/null +++ b/packages/session/src/UserDataManager.ts @@ -0,0 +1,184 @@ +import { IRoomUserData, IUserDataManager } from '@nitrots/api'; +import { GetCommunication, RequestPetInfoComposer, UserCurrentBadgesComposer } from '@nitrots/communication'; + +export class UserDataManager implements IUserDataManager +{ + 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 _userDataByType: Map> = new Map(); + private _userDataByRoomIndex: Map = new Map(); + private _userBadges: Map = new Map(); + + public getUserData(webID: number): IRoomUserData + { + return this.getDataByType(webID, UserDataManager.TYPE_USER); + } + + public getPetData(webID: number): IRoomUserData + { + return this.getDataByType(webID, UserDataManager.TYPE_PET); + } + + public getBotData(webID: number): IRoomUserData + { + return this.getDataByType(webID, UserDataManager.TYPE_BOT); + } + + public getRentableBotData(webID: number): IRoomUserData + { + return this.getDataByType(webID, UserDataManager.TYPE_RENTABLE_BOT); + } + + public getDataByType(webID: number, type: number): IRoomUserData + { + 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): IRoomUserData + { + const existing = this._userDataByRoomIndex.get(roomIndex); + + if(!existing) return null; + + return existing; + } + + public getUserDataByName(name: string): IRoomUserData + { + for(const userData of this._userDataByRoomIndex.values()) + { + if(!userData || (userData.name !== name)) continue; + + return userData; + } + + return null; + } + + public updateUserData(data: IRoomUserData): 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[] + { + GetCommunication().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 updateAchievementScore(roomIndex: number, score: number): void + { + const userData = this.getUserDataByIndex(roomIndex); + + if(!userData) return; + + userData.activityPoints = score; + } + + public updatePetLevel(roomIndex: number, level: number): void + { + const userData = this.getUserDataByIndex(roomIndex); + + if(userData) userData.petLevel = level; + } + + public updatePetBreedingStatus(roomIndex: number, canBreed: boolean, canHarvest: boolean, canRevive: boolean, hasBreedingPermission: boolean): void + { + const userData = this.getUserDataByIndex(roomIndex); + + if(!userData) return; + + userData.canBreed = canBreed; + userData.canHarvest = canHarvest; + userData.canRevive = canRevive; + userData.hasBreedingPermission = hasBreedingPermission; + } + + public requestPetInfo(id: number): void + { + const petData = this.getPetData(id); + + if(!petData) return; + + GetCommunication().connection.send(new RequestPetInfoComposer(id)); + } +} diff --git a/packages/session/src/badge/BadgeImageManager.ts b/packages/session/src/badge/BadgeImageManager.ts new file mode 100644 index 0000000..0151ed5 --- /dev/null +++ b/packages/session/src/badge/BadgeImageManager.ts @@ -0,0 +1,194 @@ +import { GetAssetManager } from '@nitrots/assets'; +import { GetCommunication, GroupBadgePartsEvent } from '@nitrots/communication'; +import { GetConfiguration } from '@nitrots/configuration'; +import { BadgeImageReadyEvent, GetEventDispatcher } from '@nitrots/events'; +import { TextureUtils } from '@nitrots/utils'; +import { Container, Sprite, Texture } from 'pixi.js'; +import { BadgeInfo } from './BadgeInfo'; +import { GroupBadge } from './GroupBadge'; +import { GroupBadgePart } from './GroupBadgePart'; + +export class BadgeImageManager +{ + public static GROUP_BADGE: string = 'group_badge'; + public static NORMAL_BADGE: string = 'normal_badge'; + + private _groupBases: Map = new Map(); + private _groupSymbols: Map = new Map(); + private _groupPartColors: Map = new Map(); + private _requestedBadges: Map = new Map(); + private _groupBadgesQueue: Map = new Map(); + private _readyToGenerateGroupBadges: boolean = false; + + public init(): void + { + GetCommunication().registerMessageEvent(new GroupBadgePartsEvent(this.onGroupBadgePartsEvent.bind(this))); + } + + public getBadgeImage(badgeName: string, type: string = BadgeImageManager.NORMAL_BADGE, load: boolean = true): Texture + { + return this.getBadgeTexture(badgeName, type); + } + + 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 = BadgeImageManager.NORMAL_BADGE): string + { + if(GetAssetManager().getTexture(this.getBadgeUrl(badgeName, type))) return badgeName; + + this.getBadgeTexture(badgeName, type); + + return null; + } + + private getBadgeTexture(badgeName: string, type: string = BadgeImageManager.NORMAL_BADGE): Texture + { + const url = this.getBadgeUrl(badgeName, type); + + if(!url || !url.length) return null; + + const texture = GetAssetManager().getTexture(url); + + if(texture) return texture; + + if(type === BadgeImageManager.NORMAL_BADGE) + { + const loadBadge = async () => + { + await GetAssetManager().downloadAsset(url); + + const texture = GetAssetManager().getTexture(url); + + if(texture) GetEventDispatcher().dispatchEvent(new BadgeImageReadyEvent(badgeName, texture)); + }; + + loadBadge(); + } + + else if(type === BadgeImageManager.GROUP_BADGE) + { + if(this._groupBadgesQueue.get(badgeName)) return; + + this._groupBadgesQueue.set(badgeName, true); + + if(this._readyToGenerateGroupBadges) this.loadGroupBadge(badgeName); + } + + return this.getBadgePlaceholder(); + } + + private getBadgePlaceholder(): Texture + { + return GetAssetManager().getTexture(GetConfiguration().getValue('images.url') + '/loading_icon.png'); + } + + public getBadgeUrl(badge: string, type: string = BadgeImageManager.NORMAL_BADGE): string + { + let url = null; + + switch(type) + { + case BadgeImageManager.NORMAL_BADGE: + url = (GetConfiguration().getValue('badge.asset.url')).replace('%badgename%', badge); + break; + case BadgeImageManager.GROUP_BADGE: + url = badge; + break; + } + + return url; + } + + private loadGroupBadge(badgeCode: string): void + { + const groupBadge = new GroupBadge(badgeCode); + const partMatches = [...badgeCode.matchAll(/[b|s][0-9]{4,6}/g)]; + + for(const partMatch of partMatches) + { + const partCode = partMatch[0]; + const shortMethod = (partCode.length === 6); + const partType = partCode[0]; + const partId = parseInt(partCode.slice(1, shortMethod ? 3 : 4)); + const partColor = parseInt(partCode.slice(shortMethod ? 3 : 4, shortMethod ? 5 : 6)); + const partPosition = partCode.length < 6 ? 0 : parseInt(partCode.slice(shortMethod ? 5 : 6, shortMethod ? 6 : 7)); // sometimes position is ommitted + const part = new GroupBadgePart(partType, partId, partColor, partPosition); + + groupBadge.parts.push(part); + } + + this.renderGroupBadge(groupBadge); + } + + private renderGroupBadge(groupBadge: GroupBadge): void + { + const container = new Container(); + const tempSprite = new Sprite(Texture.EMPTY); + + tempSprite.width = GroupBadgePart.IMAGE_WIDTH; + tempSprite.height = GroupBadgePart.IMAGE_HEIGHT; + + container.addChild(tempSprite); + + for(const part of groupBadge.parts) + { + let isFirst = true; + + const partNames = ((part.type === 'b') ? this._groupBases.get(part.key) : this._groupSymbols.get(part.key)); + + if(partNames) + { + for(const partName of partNames) + { + if(!partName || !partName.length) continue; + + const texture = GetAssetManager().getTexture(`badgepart_${partName}`); + + if(!texture) continue; + + const { x, y } = part.calculatePosition(texture); + const sprite = new Sprite(texture); + + sprite.position.set(x, y); + + if(isFirst) sprite.tint = parseInt(this._groupPartColors.get(part.color), 16); + + isFirst = false; + + container.addChild(sprite); + } + } + } + + this._requestedBadges.delete(groupBadge.code); + this._groupBadgesQueue.delete(groupBadge.code); + + const texture = TextureUtils.generateTexture(container); + GetAssetManager().setTexture(groupBadge.code, texture); + + GetEventDispatcher().dispatchEvent(new BadgeImageReadyEvent(groupBadge.code, texture)); + } + + private onGroupBadgePartsEvent(event: GroupBadgePartsEvent): void + { + if(!event) return; + + const data = event.getParser(); + + if(!data) return; + + data.bases.forEach((names, id) => this._groupBases.set(id, names.map(val => val.replace('.png', '').replace('.gif', '')))); + + data.symbols.forEach((names, id) => this._groupSymbols.set(id, names.map(val => val.replace('.png', '').replace('.gif', '')))); + + this._groupPartColors = data.partColors; + this._readyToGenerateGroupBadges = true; + + for(const badgeCode of this._groupBadgesQueue.keys()) this.loadGroupBadge(badgeCode); + } +} diff --git a/packages/session/src/badge/BadgeInfo.ts b/packages/session/src/badge/BadgeInfo.ts new file mode 100644 index 0000000..d47cf75 --- /dev/null +++ b/packages/session/src/badge/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; + } +} diff --git a/packages/session/src/badge/GroupBadge.ts b/packages/session/src/badge/GroupBadge.ts new file mode 100644 index 0000000..5ede983 --- /dev/null +++ b/packages/session/src/badge/GroupBadge.ts @@ -0,0 +1,23 @@ +import { GroupBadgePart } from './GroupBadgePart'; + +export class GroupBadge +{ + private _code: string; + private _parts: GroupBadgePart[]; + + constructor(code: string) + { + this._code = code; + this._parts = []; + } + + public get code(): string + { + return this._code; + } + + public get parts(): GroupBadgePart[] + { + return this._parts; + } +} diff --git a/packages/session/src/badge/GroupBadgePart.ts b/packages/session/src/badge/GroupBadgePart.ts new file mode 100644 index 0000000..5385715 --- /dev/null +++ b/packages/session/src/badge/GroupBadgePart.ts @@ -0,0 +1,66 @@ +import { Point, Texture } from 'pixi.js'; + +export class GroupBadgePart +{ + public static BASE: string = 'b'; + public static SYMBOL: string = 's'; + public static SYMBOL_ALT: string = 't'; + public static BASE_PART: number = 0; + public static LAYER_PART: number = 1; + public static IMAGE_WIDTH: number = 39; + public static IMAGE_HEIGHT: number = 39; + public static CELL_WIDTH: number = 13; + public static CELL_HEIGHT: number = 13; + + public type: string; + public key: number; + public color: number; + public position: number; + + constructor(type: string, key: number = 0, color: number = 0, position: number = 0) + { + this.type = type; + this.key = key; + this.color = color; + this.position = position; + } + + public get code(): string + { + if(this.key === 0) return null; + + return GroupBadgePart.getCode(this.type, this.key, this.color, this.position); + } + + public static getCode(type: string, key: number, color: number, position: number): string + { + return (type === GroupBadgePart.BASE ? type : key >= 100 ? GroupBadgePart.SYMBOL_ALT : GroupBadgePart.SYMBOL) + (key < 10 ? '0' : '') + (type === GroupBadgePart.BASE ? key : key >= 100 ? key - 100 : key) + (color < 10 ? '0' : '') + color + position; + } + + public calculatePosition(asset: Texture): Point + { + const gridPos = this.calculateGridPos(this.position); + + let x: number = (((GroupBadgePart.CELL_WIDTH * gridPos.x) + (GroupBadgePart.CELL_WIDTH / 2)) - (asset.width / 2)); + let y: number = (((GroupBadgePart.CELL_HEIGHT * gridPos.y) + (GroupBadgePart.CELL_HEIGHT / 2)) - (asset.height / 2)); + + if(x < 0) x = 0; + + if((x + asset.width) > GroupBadgePart.IMAGE_WIDTH) x = (GroupBadgePart.IMAGE_WIDTH - asset.width); + + if(y < 0) y = 0; + + if((y + asset.height) > GroupBadgePart.IMAGE_HEIGHT) y = (GroupBadgePart.IMAGE_HEIGHT - asset.height); + + return new Point(Math.floor(x), Math.floor(y)); + } + + private calculateGridPos(gridVal: number): Point + { + const point = new Point(); + point.x = Math.floor((gridVal % 3)); + point.y = Math.floor((gridVal / 3)); + + return point; + } +} diff --git a/packages/session/src/badge/index.ts b/packages/session/src/badge/index.ts new file mode 100644 index 0000000..dd81f9c --- /dev/null +++ b/packages/session/src/badge/index.ts @@ -0,0 +1,4 @@ +export * from './BadgeImageManager'; +export * from './BadgeInfo'; +export * from './GroupBadge'; +export * from './GroupBadgePart'; diff --git a/packages/session/src/furniture/FurnitureData.ts b/packages/session/src/furniture/FurnitureData.ts new file mode 100644 index 0000000..3b43f15 --- /dev/null +++ b/packages/session/src/furniture/FurnitureData.ts @@ -0,0 +1,222 @@ +import { IFurnitureData } from '@nitrots/api'; + +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/packages/session/src/furniture/FurnitureDataLoader.ts b/packages/session/src/furniture/FurnitureDataLoader.ts new file mode 100644 index 0000000..6f7a096 --- /dev/null +++ b/packages/session/src/furniture/FurnitureDataLoader.ts @@ -0,0 +1,106 @@ +import { FurnitureType, IFurnitureData } from '@nitrots/api'; +import { GetConfiguration } from '@nitrots/configuration'; +import { GetLocalizationManager } from '@nitrots/localization'; +import { FurnitureData } from './FurnitureData'; + +export class FurnitureDataLoader +{ + private _floorItems: Map; + private _wallItems: Map; + + constructor(floorItems: Map, wallItems: Map) + { + this._floorItems = floorItems; + this._wallItems = wallItems; + } + + public async init(): Promise + { + const url = GetConfiguration().getValue('furnidata.url'); + + if(!url || !url.length) throw new Error('invalid furni data url'); + + const response = await fetch(url); + + if(response.status !== 200) throw new Error('Invalid furni data file'); + + const responseData = await response.json(); + + if(responseData.roomitemtypes) this.parseFloorItems(responseData.roomitemtypes); + + if(responseData.wallitemtypes) this.parseWallItems(responseData.wallitemtypes); + } + + 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 + { + switch(furniture.type) + { + case FurnitureType.FLOOR: + GetLocalizationManager().setValue(('roomItem.name.' + furniture.id), furniture.name); + GetLocalizationManager().setValue(('roomItem.desc.' + furniture.id), furniture.description); + return; + case FurnitureType.WALL: + GetLocalizationManager().setValue(('wallItem.name.' + furniture.id), furniture.name); + GetLocalizationManager().setValue(('wallItem.desc.' + furniture.id), furniture.description); + return; + } + } +} diff --git a/packages/session/src/furniture/index.ts b/packages/session/src/furniture/index.ts new file mode 100644 index 0000000..6b2d9e3 --- /dev/null +++ b/packages/session/src/furniture/index.ts @@ -0,0 +1,2 @@ +export * from './FurnitureData'; +export * from './FurnitureDataLoader'; diff --git a/packages/session/src/handler/BaseHandler.ts b/packages/session/src/handler/BaseHandler.ts new file mode 100644 index 0000000..3bd699b --- /dev/null +++ b/packages/session/src/handler/BaseHandler.ts @@ -0,0 +1,41 @@ +import { IConnection, IRoomHandlerListener } from '@nitrots/api'; + +export class BaseHandler +{ + private _connection: IConnection; + private _listener: IRoomHandlerListener; + private _roomId: number; + + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + this._connection = connection; + this._listener = listener; + this._roomId = 0; + } + + public dispose(): 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; + } +} diff --git a/packages/session/src/handler/GenericErrorHandler.ts b/packages/session/src/handler/GenericErrorHandler.ts new file mode 100644 index 0000000..0d7bebf --- /dev/null +++ b/packages/session/src/handler/GenericErrorHandler.ts @@ -0,0 +1,42 @@ +import { GenericErrorEnum, IConnection, IRoomHandlerListener } from '@nitrots/api'; +import { GenericErrorEvent } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionErrorMessageEvent } from '@nitrots/events'; +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 = ''; + + switch(parser.errorCode) + { + case GenericErrorEnum.KICKED_OUT_OF_ROOM: + type = RoomSessionErrorMessageEvent.RSEME_KICKED; + break; + default: + return; + } + + if(!type || type.length == 0) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionErrorMessageEvent(type, roomSession)); + } +} diff --git a/packages/session/src/handler/PetPackageHandler.ts b/packages/session/src/handler/PetPackageHandler.ts new file mode 100644 index 0000000..5931d76 --- /dev/null +++ b/packages/session/src/handler/PetPackageHandler.ts @@ -0,0 +1,45 @@ +import { IConnection, IRoomHandlerListener } from '@nitrots/api'; +import { GetCommunication, OpenPetPackageRequestedMessageEvent, OpenPetPackageResultMessageEvent } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionPetPackageEvent } from '@nitrots/events'; +import { BaseHandler } from './BaseHandler'; + +export class PetPackageHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + GetCommunication().registerMessageEvent(new OpenPetPackageRequestedMessageEvent(this.onOpenPetPackageRequested.bind(this))); + GetCommunication().registerMessageEvent(new OpenPetPackageResultMessageEvent(this.onOpenPetPackageResult.bind(this))); + } + + private onOpenPetPackageRequested(event: OpenPetPackageRequestedMessageEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionPetPackageEvent(RoomSessionPetPackageEvent.RSOPPE_OPEN_PET_PACKAGE_REQUESTED, session, parser.objectId, parser.figureData, 0, null)); + } + + private onOpenPetPackageResult(event: OpenPetPackageResultMessageEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionPetPackageEvent(RoomSessionPetPackageEvent.RSOPPE_OPEN_PET_PACKAGE_RESULT, session, parser.objectId, null, parser.nameValidationStatus, parser.nameValidationInfo)); + } +} diff --git a/packages/session/src/handler/PollHandler.ts b/packages/session/src/handler/PollHandler.ts new file mode 100644 index 0000000..41c5f44 --- /dev/null +++ b/packages/session/src/handler/PollHandler.ts @@ -0,0 +1,114 @@ +import { IConnection, IRoomHandlerListener } from '@nitrots/api'; +import { PollContentsEvent, PollErrorEvent, PollOfferEvent, RoomPollResultEvent, StartRoomPollEvent } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionPollEvent, RoomSessionVoteEvent } from '@nitrots/events'; +import { BaseHandler } from './BaseHandler'; + +export class PollHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new PollContentsEvent(this.onPollContentsEvent.bind(this))); + connection.addMessageEvent(new PollOfferEvent(this.onPollOfferEvent.bind(this))); + connection.addMessageEvent(new PollErrorEvent(this.onPollErrorEvent.bind(this))); + connection.addMessageEvent(new StartRoomPollEvent(this.onStartRoomPollEvent.bind(this))); + connection.addMessageEvent(new RoomPollResultEvent(this.onRoomPollResultEvent.bind(this))); + } + + private onPollContentsEvent(event: PollContentsEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const pollEvent = new RoomSessionPollEvent(RoomSessionPollEvent.CONTENT, session, parser.id); + + pollEvent.startMessage = parser.startMessage; + pollEvent.endMessage = parser.endMessage; + pollEvent.numQuestions = parser.numQuestions; + pollEvent.questionArray = parser.questionArray; + pollEvent.npsPoll = parser.npsPoll; + + GetEventDispatcher().dispatchEvent(pollEvent); + } + + private onPollOfferEvent(event: PollOfferEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const pollEvent = new RoomSessionPollEvent(RoomSessionPollEvent.OFFER, session, parser.id); + + pollEvent.summary = parser.headline; + pollEvent.summary = parser.summary; + + GetEventDispatcher().dispatchEvent(pollEvent); + } + + private onPollErrorEvent(event: PollErrorEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const pollEvent = new RoomSessionPollEvent(RoomSessionPollEvent.ERROR, session, -1); + pollEvent.headline = '???'; + pollEvent.summary = '???'; + + GetEventDispatcher().dispatchEvent(pollEvent); + } + + private onStartRoomPollEvent(event: StartRoomPollEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const pollEvent = new RoomSessionVoteEvent(RoomSessionVoteEvent.VOTE_QUESTION, session, parser.question, parser.choices); + + GetEventDispatcher().dispatchEvent(pollEvent); + } + + private onRoomPollResultEvent(event: RoomPollResultEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const pollEvent = new RoomSessionVoteEvent(RoomSessionVoteEvent.VOTE_RESULT, session, parser.question, parser.choices, parser.SafeStr_7651, parser.SafeStr_7654); + + GetEventDispatcher().dispatchEvent(pollEvent); + } +} diff --git a/packages/session/src/handler/RoomChatHandler.ts b/packages/session/src/handler/RoomChatHandler.ts new file mode 100644 index 0000000..67903f7 --- /dev/null +++ b/packages/session/src/handler/RoomChatHandler.ts @@ -0,0 +1,173 @@ +import { IConnection, IRoomHandlerListener, SystemChatStyleEnum } from '@nitrots/api'; +import { FloodControlEvent, PetRespectNoficationEvent, PetSupplementTypeEnum, PetSupplementedNotificationEvent, RemainingMuteEvent, RespectReceivedEvent, RoomUnitChatEvent, RoomUnitChatShoutEvent, RoomUnitChatWhisperEvent, RoomUnitHandItemReceivedEvent } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionChatEvent } from '@nitrots/events'; +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 PetRespectNoficationEvent(this.onPetRespectNoficationEvent.bind(this))); + connection.addMessageEvent(new PetSupplementedNotificationEvent(this.onPetSupplementedNotificationEvent.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_TYPE_SPEAK; + + if(event instanceof RoomUnitChatShoutEvent) chatType = RoomSessionChatEvent.CHAT_TYPE_SHOUT; + else if(event instanceof RoomUnitChatWhisperEvent) chatType = RoomSessionChatEvent.CHAT_TYPE_WHISPER; + + const chatEvent = new RoomSessionChatEvent(RoomSessionChatEvent.CHAT_EVENT, session, parser.roomIndex, parser.message, chatType, parser.bubble); + + GetEventDispatcher().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; + + GetEventDispatcher().dispatchEvent(new RoomSessionChatEvent(RoomSessionChatEvent.CHAT_EVENT, session, parser.giverUserId, '', RoomSessionChatEvent.CHAT_TYPE_HAND_ITEM_RECEIVED, SystemChatStyleEnum.GENERIC, [], 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; + + GetEventDispatcher().dispatchEvent(new RoomSessionChatEvent(RoomSessionChatEvent.CHAT_EVENT, session, userData.roomIndex, '', RoomSessionChatEvent.CHAT_TYPE_RESPECT, SystemChatStyleEnum.GENERIC)); + } + + private onPetRespectNoficationEvent(event: PetRespectNoficationEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const petData = session.userDataManager.getPetData(parser.petData.id); + + if(!petData) return; + + let chatType = RoomSessionChatEvent.CHAT_TYPE_PETRESPECT; + + if(parser.isTreat) chatType = RoomSessionChatEvent.CHAT_TYPE_PETTREAT; + + GetEventDispatcher().dispatchEvent(new RoomSessionChatEvent(RoomSessionChatEvent.CHAT_EVENT, session, petData.roomIndex, '', chatType, SystemChatStyleEnum.GENERIC)); + } + + private onPetSupplementedNotificationEvent(event: PetSupplementedNotificationEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const petData = session.userDataManager.getPetData(parser.petId); + + if(!petData) return; + + let userRoomIndex = -1; + + const userData = session.userDataManager.getUserData(parser.userId); + + if(userData) userRoomIndex = userData.roomIndex; + + let chatType = RoomSessionChatEvent.CHAT_TYPE_PETREVIVE; + + switch(parser.supplementType) + { + case PetSupplementTypeEnum.REVIVE: + chatType = RoomSessionChatEvent.CHAT_TYPE_PETREVIVE; + break; + case PetSupplementTypeEnum.REBREED_FERTILIZER: + chatType = RoomSessionChatEvent.CHAT_TYPE_PET_REBREED_FERTILIZE; + break; + case PetSupplementTypeEnum.SPEED_FERTILIZER: + chatType = RoomSessionChatEvent.CHAT_TYPE_PET_SPEED_FERTILIZE; + break; + } + + GetEventDispatcher().dispatchEvent(new RoomSessionChatEvent(RoomSessionChatEvent.CHAT_EVENT, session, petData.roomIndex, '', chatType, SystemChatStyleEnum.GENERIC, null, userRoomIndex)); + } + + 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; + + GetEventDispatcher().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; + + GetEventDispatcher().dispatchEvent(new RoomSessionChatEvent(RoomSessionChatEvent.CHAT_EVENT, session, session.ownRoomIndex, '', RoomSessionChatEvent.CHAT_TYPE_MUTE_REMAINING, SystemChatStyleEnum.GENERIC, [], parser.seconds)); + } +} diff --git a/packages/session/src/handler/RoomDataHandler.ts b/packages/session/src/handler/RoomDataHandler.ts new file mode 100644 index 0000000..67aa7d3 --- /dev/null +++ b/packages/session/src/handler/RoomDataHandler.ts @@ -0,0 +1,40 @@ +import { IConnection, IRoomHandlerListener } from '@nitrots/api'; +import { GetGuestRoomResultEvent } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionEvent, RoomSessionPropertyUpdateEvent } from '@nitrots/events'; +import { BaseHandler } from './BaseHandler'; + +export class RoomDataHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new GetGuestRoomResultEvent(this.onGetGuestRoomResultEvent.bind(this))); + } + + private onGetGuestRoomResultEvent(event: GetGuestRoomResultEvent): void + { + if(!(event instanceof GetGuestRoomResultEvent)) 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; + + GetEventDispatcher().dispatchEvent(new RoomSessionPropertyUpdateEvent(RoomSessionPropertyUpdateEvent.RSDUE_ALLOW_PETS, roomSession)); + GetEventDispatcher().dispatchEvent(new RoomSessionEvent(RoomSessionEvent.ROOM_DATA, roomSession)); + } +} diff --git a/packages/session/src/handler/RoomDimmerPresetsHandler.ts b/packages/session/src/handler/RoomDimmerPresetsHandler.ts new file mode 100644 index 0000000..09b5b5b --- /dev/null +++ b/packages/session/src/handler/RoomDimmerPresetsHandler.ts @@ -0,0 +1,44 @@ +import { IConnection, IRoomHandlerListener } from '@nitrots/api'; +import { RoomDimmerPresetsEvent } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionDimmerPresetsEvent } from '@nitrots/events'; +import { BaseHandler } from './BaseHandler'; + +export class RoomDimmerPresetsHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new RoomDimmerPresetsEvent(this.onRoomDimmerPresets.bind(this))); + } + + private onRoomDimmerPresets(event: RoomDimmerPresetsEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const presetEvent = new RoomSessionDimmerPresetsEvent(RoomSessionDimmerPresetsEvent.ROOM_DIMMER_PRESETS, session); + + presetEvent.selectedPresetId = parser.selectedPresetId; + + let i = 0; + + while(i < parser.presetCount) + { + const preset = parser.getPreset(i); + + if(preset) presetEvent.storePreset(preset.id, preset.type, preset.color, preset.brightness); + + i++; + } + + GetEventDispatcher().dispatchEvent(presetEvent); + } +} diff --git a/packages/session/src/handler/RoomPermissionsHandler.ts b/packages/session/src/handler/RoomPermissionsHandler.ts new file mode 100644 index 0000000..3655cde --- /dev/null +++ b/packages/session/src/handler/RoomPermissionsHandler.ts @@ -0,0 +1,48 @@ +import { IConnection, IRoomHandlerListener, RoomControllerLevel } from '@nitrots/api'; +import { RoomRightsClearEvent, RoomRightsEvent, RoomRightsOwnerEvent } from '@nitrots/communication'; +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(); + } +} diff --git a/packages/session/src/handler/RoomPresentHandler.ts b/packages/session/src/handler/RoomPresentHandler.ts new file mode 100644 index 0000000..3fd8525 --- /dev/null +++ b/packages/session/src/handler/RoomPresentHandler.ts @@ -0,0 +1,33 @@ +import { IConnection, IRoomHandlerListener } from '@nitrots/api'; +import { PresentOpenedMessageEvent } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionPresentEvent } from '@nitrots/events'; +import { BaseHandler } from './BaseHandler'; + +export class RoomPresentHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + if(!connection) return; + + connection.addMessageEvent(new PresentOpenedMessageEvent(this.onFurnitureGiftOpenedEvent.bind(this))); + } + + private onFurnitureGiftOpenedEvent(event: PresentOpenedMessageEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionPresentEvent(RoomSessionPresentEvent.RSPE_PRESENT_OPENED, session, parser.classId, parser.itemType, parser.productCode, parser.placedItemId, parser.placedItemType, parser.placedInRoom, parser.petFigureString)); + + } + +} diff --git a/packages/session/src/handler/RoomSessionHandler.ts b/packages/session/src/handler/RoomSessionHandler.ts new file mode 100644 index 0000000..717c9e3 --- /dev/null +++ b/packages/session/src/handler/RoomSessionHandler.ts @@ -0,0 +1,113 @@ +import { IConnection, IRoomHandlerListener } from '@nitrots/api'; +import { DesktopViewEvent, FlatAccessDeniedMessageEvent, GoToFlatMessageComposer, RoomDoorbellAcceptedEvent, RoomEnterEvent, RoomReadyMessageEvent, YouAreSpectatorMessageEvent } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionDoorbellEvent, RoomSessionSpectatorModeEvent } from '@nitrots/events'; +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 RoomReadyMessageEvent(this.onRoomReadyMessageEvent.bind(this))); + connection.addMessageEvent(new DesktopViewEvent(this.onDesktopViewEvent.bind(this))); + connection.addMessageEvent(new RoomDoorbellAcceptedEvent(this.onRoomDoorbellAcceptedEvent.bind(this))); + connection.addMessageEvent(new FlatAccessDeniedMessageEvent(this.onRoomDoorbellRejectedEvent.bind(this))); + connection.addMessageEvent(new YouAreSpectatorMessageEvent(this.onYouAreSpectatorMessageEvent.bind(this))); + } + + private onRoomEnterEvent(event: RoomEnterEvent): void + { + if(!(event instanceof RoomEnterEvent)) return; + + if(this.listener) this.listener.sessionUpdate(this.roomId, RoomSessionHandler.RS_CONNECTED); + } + + private onRoomReadyMessageEvent(event: RoomReadyMessageEvent): void + { + if(!(event instanceof RoomReadyMessageEvent)) 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(new GoToFlatMessageComposer(this.roomId)); + } + else + { + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionDoorbellEvent(RoomSessionDoorbellEvent.RSDE_ACCEPTED, session, username)); + } + } + + private onRoomDoorbellRejectedEvent(event: FlatAccessDeniedMessageEvent): void + { + if(!(event instanceof FlatAccessDeniedMessageEvent) || !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 + { + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionDoorbellEvent(RoomSessionDoorbellEvent.RSDE_REJECTED, session, username)); + } + } + + private onYouAreSpectatorMessageEvent(event: YouAreSpectatorMessageEvent): void + { + if(this.listener) + { + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + session.isSpectator = true; + + GetEventDispatcher().dispatchEvent(new RoomSessionSpectatorModeEvent(RoomSessionSpectatorModeEvent.SPECTATOR_MODE, session)); + } + } +} diff --git a/packages/session/src/handler/RoomUsersHandler.ts b/packages/session/src/handler/RoomUsersHandler.ts new file mode 100644 index 0000000..772502e --- /dev/null +++ b/packages/session/src/handler/RoomUsersHandler.ts @@ -0,0 +1,475 @@ +import { IConnection, IRoomHandlerListener, IRoomUserData } from '@nitrots/api'; +import { BotErrorEvent, ConfirmBreedingRequestEvent, ConfirmBreedingResultEvent, DoorbellMessageEvent, FavoriteMembershipUpdateMessageEvent, NestBreedingSuccessEvent, NewFriendRequestEvent, PetBreedingMessageEvent, PetBreedingResultEvent, PetFigureUpdateEvent, PetInfoEvent, PetLevelUpdateMessageEvent, PetPlacingErrorEvent, PetStatusUpdateEvent, RoomUnitDanceEvent, RoomUnitEvent, RoomUnitInfoEvent, RoomUnitRemoveEvent, UserCurrentBadgesEvent, UserNameChangeMessageEvent } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionConfirmPetBreedingEvent, RoomSessionConfirmPetBreedingResultEvent, RoomSessionDanceEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionFavoriteGroupUpdateEvent, RoomSessionFriendRequestEvent, RoomSessionNestBreedingSuccessEvent, RoomSessionPetBreedingEvent, RoomSessionPetBreedingResultEvent, RoomSessionPetFigureUpdateEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPetLevelUpdateEvent, RoomSessionPetStatusUpdateEvent, RoomSessionUserBadgesEvent, RoomSessionUserDataUpdateEvent, RoomSessionUserFigureUpdateEvent } from '@nitrots/events'; +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 DoorbellMessageEvent(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 PetStatusUpdateEvent(this.onPetStatusUpdateEvent.bind(this))); + connection.addMessageEvent(new PetBreedingMessageEvent(this.onPetBreedingMessageEvent.bind(this))); + connection.addMessageEvent(new PetLevelUpdateMessageEvent(this.onPetLevelUpdateMessageEvent.bind(this))); + connection.addMessageEvent(new ConfirmBreedingResultEvent(this.onConfirmBreedingResultEvent.bind(this))); + connection.addMessageEvent(new NestBreedingSuccessEvent(this.onNestBreedingSuccessEvent.bind(this))); + connection.addMessageEvent(new ConfirmBreedingRequestEvent(this.onConfirmBreedingRequestEvent.bind(this))); + connection.addMessageEvent(new PetFigureUpdateEvent(this.onPetFigureUpdateEvent.bind(this))); + connection.addMessageEvent(new PetBreedingResultEvent(this.onPetBreedingResultEvent.bind(this))); + connection.addMessageEvent(new PetPlacingErrorEvent(this.onPetPlacingError.bind(this))); + connection.addMessageEvent(new BotErrorEvent(this.onBotError.bind(this))); + connection.addMessageEvent(new FavoriteMembershipUpdateMessageEvent(this.onFavoriteMembershipUpdateMessageEvent.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: IRoomUserData[] = []; + + 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.groupId = 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); + } + } + + GetEventDispatcher().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); + session.userDataManager.updateAchievementScore(parser.unitId, parser.achievementScore); + + GetEventDispatcher().dispatchEvent(new RoomSessionUserFigureUpdateEvent(session, parser.unitId, parser.figure, parser.gender, parser.motto, parser.achievementScore)); + + } + + 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; + + GetEventDispatcher().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); + + GetEventDispatcher().dispatchEvent(new RoomSessionUserBadgesEvent(session, parser.userId, parser.badges)); + } + + private onRoomDoorbellEvent(event: DoorbellMessageEvent): 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; + + GetEventDispatcher().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; + + GetEventDispatcher().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.skillTresholds = parser.skillTresholds; + petData.publiclyRideable = parser.publiclyRideable; + petData.maximumTimeToLive = parser.maximumTimeToLive; + petData.remainingTimeToLive = parser.remainingTimeToLive; + petData.remainingGrowTime = parser.remainingGrowTime; + petData.publiclyBreedable = parser.publiclyBreedable; + + GetEventDispatcher().dispatchEvent(new RoomSessionPetInfoUpdateEvent(session, petData)); + } + + private onPetStatusUpdateEvent(event: PetStatusUpdateEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + session.userDataManager.updatePetBreedingStatus(parser.roomIndex, parser.canBreed, parser.canHarvest, parser.canRevive, parser.hasBreedingPermission); + + GetEventDispatcher().dispatchEvent(new RoomSessionPetStatusUpdateEvent(session, parser.petId, parser.canBreed, parser.canHarvest, parser.canRevive, parser.hasBreedingPermission)); + } + + private onPetBreedingMessageEvent(event: PetBreedingMessageEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionPetBreedingEvent(session, parser.state, parser.ownPetId, parser.otherPetId)); + } + + private onPetLevelUpdateMessageEvent(event: PetLevelUpdateMessageEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + session.userDataManager.updatePetLevel(parser.roomIndex, parser.level); + + GetEventDispatcher().dispatchEvent(new RoomSessionPetLevelUpdateEvent(session, parser.petId, parser.level)); + } + + private onConfirmBreedingResultEvent(event: ConfirmBreedingResultEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionConfirmPetBreedingResultEvent(session, parser.breedingNestStuffId, parser.result)); + } + + private onNestBreedingSuccessEvent(event: NestBreedingSuccessEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionNestBreedingSuccessEvent(session, parser.petId, parser.rarityCategory)); + } + + private onConfirmBreedingRequestEvent(event: ConfirmBreedingRequestEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionConfirmPetBreedingEvent(session, parser.nestId, parser.pet1, parser.pet2, parser.rarityCategories, parser.resultPetType)); + } + + private onPetFigureUpdateEvent(event: PetFigureUpdateEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const figure = parser.figureData.figuredata; + + session.userDataManager.updateFigure(parser.roomIndex, figure, '', parser.hasSaddle, parser.isRiding); + + GetEventDispatcher().dispatchEvent(new RoomSessionPetFigureUpdateEvent(session, parser.petId, figure)); + } + + private onPetBreedingResultEvent(event: PetBreedingResultEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + GetEventDispatcher().dispatchEvent(new RoomSessionPetBreedingResultEvent(session, parser.resultData, parser.otherResultData)); + } + + 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 = ''; + + 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; + + GetEventDispatcher().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 = ''; + + 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; + + GetEventDispatcher().dispatchEvent(new RoomSessionErrorMessageEvent(type, session)); + } + + private onFavoriteMembershipUpdateMessageEvent(event: FavoriteMembershipUpdateMessageEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const userData = session.userDataManager.getUserDataByIndex(parser.roomIndex); + + if(!userData) return; + + userData.groupId = parser.groupId; + userData.groupName = parser.groupName; + + GetEventDispatcher().dispatchEvent(new RoomSessionFavoriteGroupUpdateEvent(session, parser.roomIndex, parser.groupId, parser.status, parser.groupName)); + } +} diff --git a/packages/session/src/handler/WordQuizHandler.ts b/packages/session/src/handler/WordQuizHandler.ts new file mode 100644 index 0000000..c83f25b --- /dev/null +++ b/packages/session/src/handler/WordQuizHandler.ts @@ -0,0 +1,79 @@ +import { IConnection, IRoomHandlerListener } from '@nitrots/api'; +import { QuestionAnsweredEvent, QuestionEvent, QuestionFinishedEvent } from '@nitrots/communication'; +import { GetEventDispatcher, RoomSessionWordQuizEvent } from '@nitrots/events'; +import { BaseHandler } from './BaseHandler'; + +export class WordQuizHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new QuestionEvent(this.onQuestionEvent.bind(this))); + connection.addMessageEvent(new QuestionAnsweredEvent(this.onQuestionAnsweredEvent.bind(this))); + connection.addMessageEvent(new QuestionFinishedEvent(this.onQuestionFinishedEvent.bind(this))); + } + + private onQuestionEvent(event: QuestionEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const quizEvent = new RoomSessionWordQuizEvent(RoomSessionWordQuizEvent.QUESTION, session, parser.pollId); + + quizEvent.question = parser.question; + quizEvent.duration = parser.duration; + quizEvent.pollType = parser.pollType; + quizEvent.questionId = parser.questionId; + quizEvent.pollId = parser.pollId; + + GetEventDispatcher().dispatchEvent(quizEvent); + } + + private onQuestionAnsweredEvent(event: QuestionAnsweredEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const quizEvent = new RoomSessionWordQuizEvent(RoomSessionWordQuizEvent.ANSWERED, session, parser.userId); + + quizEvent.value = parser.value; + quizEvent.userId = parser.userId; + quizEvent.answerCounts = parser.answerCounts; + + GetEventDispatcher().dispatchEvent(quizEvent); + } + + private onQuestionFinishedEvent(event: QuestionFinishedEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const quizEvent = new RoomSessionWordQuizEvent(RoomSessionWordQuizEvent.FINISHED, session); + quizEvent.questionId = parser.questionId; + quizEvent.answerCounts = parser.answerCounts; + + GetEventDispatcher().dispatchEvent(quizEvent); + } +} diff --git a/packages/session/src/handler/index.ts b/packages/session/src/handler/index.ts new file mode 100644 index 0000000..67d7eb6 --- /dev/null +++ b/packages/session/src/handler/index.ts @@ -0,0 +1,12 @@ +export * from './BaseHandler'; +export * from './GenericErrorHandler'; +export * from './PetPackageHandler'; +export * from './PollHandler'; +export * from './RoomChatHandler'; +export * from './RoomDataHandler'; +export * from './RoomDimmerPresetsHandler'; +export * from './RoomPermissionsHandler'; +export * from './RoomPresentHandler'; +export * from './RoomSessionHandler'; +export * from './RoomUsersHandler'; +export * from './WordQuizHandler'; diff --git a/packages/session/src/index.ts b/packages/session/src/index.ts new file mode 100644 index 0000000..aeebbef --- /dev/null +++ b/packages/session/src/index.ts @@ -0,0 +1,15 @@ +export * from './GetRoomSessionManager'; +export * from './GetSessionDataManager'; +export * from './GroupInformationManager'; +export * from './HabboClubLevelEnum'; +export * from './IgnoredUsersManager'; +export * from './RoomPetData'; +export * from './RoomSession'; +export * from './RoomSessionManager'; +export * from './RoomUserData'; +export * from './SessionDataManager'; +export * from './UserDataManager'; +export * from './badge'; +export * from './furniture'; +export * from './handler'; +export * from './product'; diff --git a/packages/session/src/product/ProductData.ts b/packages/session/src/product/ProductData.ts new file mode 100644 index 0000000..b5984aa --- /dev/null +++ b/packages/session/src/product/ProductData.ts @@ -0,0 +1,30 @@ +import { IProductData } from '@nitrots/api'; + +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/packages/session/src/product/ProductDataLoader.ts b/packages/session/src/product/ProductDataLoader.ts new file mode 100644 index 0000000..e8e846f --- /dev/null +++ b/packages/session/src/product/ProductDataLoader.ts @@ -0,0 +1,35 @@ +import { IProductData } from '@nitrots/api'; +import { GetConfiguration } from '@nitrots/configuration'; +import { ProductData } from './ProductData'; + +export class ProductDataLoader +{ + private _products: Map; + + constructor(products: Map) + { + this._products = products; + } + + public async init(): Promise + { + const url = GetConfiguration().getValue('productdata.url'); + + if(!url || !url.length) throw new Error('invalid product data url'); + + const response = await fetch(url); + + if(response.status !== 200) throw new Error('Invalid product data file'); + + const responseData = await response.json(); + + this.parseProducts(responseData.productdata); + } + + 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/packages/session/src/product/index.ts b/packages/session/src/product/index.ts new file mode 100644 index 0000000..ad61a98 --- /dev/null +++ b/packages/session/src/product/index.ts @@ -0,0 +1,2 @@ +export * from './ProductData'; +export * from './ProductDataLoader'; diff --git a/packages/session/tsconfig.json b/packages/session/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/session/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/sound/.eslintrc.json b/packages/sound/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/sound/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/sound/.gitignore b/packages/sound/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/sound/.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/packages/sound/index.ts b/packages/sound/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/sound/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/sound/package.json b/packages/sound/package.json new file mode 100644 index 0000000..f8b22f9 --- /dev/null +++ b/packages/sound/package.json @@ -0,0 +1,21 @@ +{ + "name": "@nitrots/sound", + "description": "Nitro sound module", + "version": "1.0.0", + "type": "module", + "license": "GPL-3.0", + "scripts": { + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/communication": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "pixi.js": "^8.0.4" + }, + "devDependencies": { + "typescript": "~5.4.2" + } +} diff --git a/packages/sound/src/GetSoundManager.ts b/packages/sound/src/GetSoundManager.ts new file mode 100644 index 0000000..53d713b --- /dev/null +++ b/packages/sound/src/GetSoundManager.ts @@ -0,0 +1,5 @@ +import { SoundManager } from './SoundManager'; + +const soundManager = new SoundManager(); + +export const GetSoundManager = () => soundManager; diff --git a/packages/sound/src/SoundManager.ts b/packages/sound/src/SoundManager.ts new file mode 100644 index 0000000..ba69514 --- /dev/null +++ b/packages/sound/src/SoundManager.ts @@ -0,0 +1,194 @@ +import { IAdvancedMap, IMusicController, INitroEvent, ISoundManager } from '@nitrots/api'; +import { GetConfiguration } from '@nitrots/configuration'; +import { GetEventDispatcher, NitroSettingsEvent, NitroSoundEvent, RoomEngineEvent, RoomEngineObjectEvent, RoomEngineSamplePlaybackEvent } from '@nitrots/events'; +import { AdvancedMap, NitroLogger } from '@nitrots/utils'; +import { MusicController } from './music/MusicController'; + +export class SoundManager implements ISoundManager +{ + private _volumeSystem: number = 0.5; + private _volumeFurni: number = 0.5; + private _volumeTrax: number = 0.5; + + private _internalSamples: IAdvancedMap = new AdvancedMap(); + private _furniSamples: IAdvancedMap = new AdvancedMap(); + private _furnitureBeingPlayed: IAdvancedMap = new AdvancedMap(); + + private _musicController: IMusicController = new MusicController(); + + public async init(): Promise + { + this._musicController.init(); + + GetEventDispatcher().addEventListener(RoomEngineSamplePlaybackEvent.PLAY_SAMPLE, event => this.onEvent(event)); + GetEventDispatcher().addEventListener(RoomEngineObjectEvent.REMOVED, event => this.onEvent(event)); + GetEventDispatcher().addEventListener(RoomEngineEvent.DISPOSED, event => this.onEvent(event)); + GetEventDispatcher().addEventListener(NitroSettingsEvent.SETTINGS_UPDATED, event => this.onEvent(event)); + GetEventDispatcher().addEventListener(NitroSoundEvent.PLAY_SOUND, event => this.onEvent(event)); + } + + private onEvent(event: INitroEvent) + { + switch(event.type) + { + case RoomEngineSamplePlaybackEvent.PLAY_SAMPLE: { + const castedEvent = (event as RoomEngineSamplePlaybackEvent); + + this.playFurniSample(castedEvent.objectId, castedEvent.sampleId, castedEvent.pitch); + return; + } + case RoomEngineObjectEvent.REMOVED: { + const castedEvent = (event as RoomEngineObjectEvent); + + this.stopFurniSample(castedEvent.objectId); + return; + } + case RoomEngineEvent.DISPOSED: { + this._furnitureBeingPlayed.getKeys().forEach((objectId: number) => + { + this.stopFurniSample(objectId); + }); + return; + } + case NitroSettingsEvent.SETTINGS_UPDATED: { + const castedEvent = (event as NitroSettingsEvent); + + const volumeFurniUpdated = castedEvent.volumeFurni !== this._volumeFurni; + const volumeTraxUpdated = castedEvent.volumeTrax !== this._volumeTrax; + + this._volumeSystem = (castedEvent.volumeSystem / 100); + this._volumeFurni = (castedEvent.volumeFurni / 100); + this._volumeTrax = (castedEvent.volumeTrax / 100); + + if(volumeFurniUpdated) this.updateFurniSamplesVolume(this._volumeFurni); + + if(volumeTraxUpdated) this._musicController?.updateVolume(this._volumeTrax); + + return; + } + case NitroSoundEvent.PLAY_SOUND: { + const castedEvent = (event as NitroSoundEvent); + + this.playInternalSample(castedEvent.sampleCode); + return; + } + } + } + + private playSample(sample: HTMLAudioElement, volume: number, pitch: number = 1): void + { + sample.volume = volume; + sample.currentTime = 0; + + try + { + sample.play(); + } + catch (e) + { + NitroLogger.error(e); + } + } + + private playInternalSample(code: string): void + { + let sample = this._internalSamples.getValue(code); + + if(!sample) + { + const sampleUrl = GetConfiguration().getValue('sounds.url'); + + sample = new Audio(sampleUrl.replace('%sample%', code)); + this._internalSamples.add(code, sample); + } + + this.playSample(sample, this._volumeSystem); + } + + private playFurniSample(objectId: number, code: number, pitch: number): void + { + let sample = this._furniSamples.getValue(code); + + if(!sample) + { + const sampleUrl = GetConfiguration().getValue('external.samples.url'); + + sample = new Audio(sampleUrl.replace('%sample%', code.toString())); + this._furniSamples.add(code, sample); + } + + if(!this._furnitureBeingPlayed.hasKey(objectId)) this._furnitureBeingPlayed.add(objectId, code); + + sample.onended = event => this.stopFurniSample(objectId); + + sample.onpause = event => this.stopFurniSample(objectId); + + sample.onerror = event => this.stopFurniSample(objectId); + + this.playSample(sample, this._volumeFurni, pitch); + } + + private stopInternalSample(code: string): void + { + const sample = this._internalSamples.getValue(code); + + if(!sample) return; + + try + { + sample.pause(); + } + catch (e) + { + NitroLogger.error(e); + } + } + + private stopFurniSample(objectId: number): void + { + const furnitureBeingPlayed = this._furnitureBeingPlayed.getValue(objectId); + + if(!furnitureBeingPlayed) return; + + const sample = this._furniSamples.getValue(furnitureBeingPlayed); + + this._furnitureBeingPlayed.remove(objectId); + + if(!sample) return; + + try + { + sample.pause(); + } + catch (e) + { + NitroLogger.error(e); + } + } + + private updateInternalSamplesVolume(volume: number): void + { + this._internalSamples.getValues().forEach((sample: HTMLAudioElement) => + { + sample.volume = volume; + }); + } + + private updateFurniSamplesVolume(volume: number): void + { + this._furniSamples.getValues().forEach((sample: HTMLAudioElement) => + { + sample.volume = volume; + }); + } + + public get traxVolume(): number + { + return this._volumeTrax; + } + + public get musicController(): IMusicController + { + return this._musicController; + } +} diff --git a/packages/sound/src/common/SongDataEntry.ts b/packages/sound/src/common/SongDataEntry.ts new file mode 100644 index 0000000..0e74bd5 --- /dev/null +++ b/packages/sound/src/common/SongDataEntry.ts @@ -0,0 +1,24 @@ +import { ISongInfo } from '@nitrots/api'; + +export class SongDataEntry implements ISongInfo +{ + private _jukeboxDiskId:number = -1; + + constructor( + public readonly id: number, + public readonly length: number, + public readonly name: string, + public readonly creator: string, + public readonly songData: string = '' + ) {} + + public get diskId(): number + { + return this._jukeboxDiskId; + } + + public set diskId(k: number) + { + this._jukeboxDiskId = k; + } +} diff --git a/packages/sound/src/common/SongStartRequestData.ts b/packages/sound/src/common/SongStartRequestData.ts new file mode 100644 index 0000000..52cd171 --- /dev/null +++ b/packages/sound/src/common/SongStartRequestData.ts @@ -0,0 +1,51 @@ +export class SongStartRequestData +{ + private _songId: number; + private _startPos: number; + private _playLength: number; + private _playRequestTime: number; + private _fadeInSeconds: number; + private _fadeOutSeconds: number; + + constructor(songId: number, startPos: number, playLength: number, fadeInSeconds: number, fadeOutSeconds: number) + { + this._songId = songId; + this._startPos = startPos; + this._playLength = playLength; + this._fadeInSeconds = fadeInSeconds; + this._fadeOutSeconds = fadeOutSeconds; + this._playRequestTime = Date.now(); + } + + public get songId(): number + { + return this._songId; + } + + public get startPos(): number + { + if(this._startPos < 0) return 0; + + return this._startPos + ((Date.now() - this._playRequestTime) / 1000); + } + + public get playLength(): number + { + return this._playLength; + } + + public get playRequestTime(): number + { + return this._playRequestTime; + } + + public get fadeInSeconds(): number + { + return this._fadeInSeconds; + } + + public get fadeOutSeconds(): number + { + return this._fadeOutSeconds; + } +} diff --git a/packages/sound/src/common/index.ts b/packages/sound/src/common/index.ts new file mode 100644 index 0000000..c33b01f --- /dev/null +++ b/packages/sound/src/common/index.ts @@ -0,0 +1,2 @@ +export * from './SongDataEntry'; +export * from './SongStartRequestData'; diff --git a/packages/sound/src/index.ts b/packages/sound/src/index.ts new file mode 100644 index 0000000..1c517b2 --- /dev/null +++ b/packages/sound/src/index.ts @@ -0,0 +1,5 @@ +export * from './GetSoundManager'; +export * from './SoundManager'; +export * from './common'; +export * from './music'; +export * from './trax'; diff --git a/packages/sound/src/music/JukeboxPlaylistController.ts b/packages/sound/src/music/JukeboxPlaylistController.ts new file mode 100644 index 0000000..3351405 --- /dev/null +++ b/packages/sound/src/music/JukeboxPlaylistController.ts @@ -0,0 +1,190 @@ +import { IMessageEvent, IPlaylistController, ISongInfo } from '@nitrots/api'; +import { GetCommunication, GetJukeboxPlayListMessageComposer, JukeboxPlayListFullMessageEvent, JukeboxSongDisksMessageEvent, NowPlayingMessageEvent } from '@nitrots/communication'; +import { GetEventDispatcher, NowPlayingEvent, PlayListStatusEvent, SongInfoReceivedEvent } from '@nitrots/events'; +import { GetSoundManager } from '../GetSoundManager'; +import { SongDataEntry } from '../common'; +import { MusicPriorities } from './MusicPriorities'; + +export class JukeboxPlaylistController implements IPlaylistController +{ + private _isPlaying = false; + private _entries: ISongInfo[]; + private _currentSongId: number = -1; + private _missingSongInfo: number[] = []; + private _playPosition: number = -1; + private _disposed: boolean = false; + private _messageEvents: IMessageEvent[] = []; + + constructor() + { + this.onSongInfoReceivedEvent = this.onSongInfoReceivedEvent.bind(this); + } + + public init(): void + { + this._messageEvents = [ + new NowPlayingMessageEvent(this.onNowPlayingMessageEvent.bind(this)), + new JukeboxSongDisksMessageEvent(this.onJukeboxSongDisksMessageEvent.bind(this)), + new JukeboxPlayListFullMessageEvent(this.onJukeboxPlayListFullMessageEvent.bind(this)) + ]; + + this._messageEvents.forEach(event => GetCommunication().registerMessageEvent(event)); + + GetEventDispatcher().addEventListener(SongInfoReceivedEvent.SIR_TRAX_SONG_INFO_RECEIVED, this.onSongInfoReceivedEvent); + } + + public dispose(): void + { + if(this._disposed) return; + + this.stopPlaying(); + + GetEventDispatcher().removeEventListener(SongInfoReceivedEvent.SIR_TRAX_SONG_INFO_RECEIVED, this.onSongInfoReceivedEvent); + + this._messageEvents.forEach(event => GetCommunication().removeMessageEvent(event)); + + this._disposed = true; + } + + private onNowPlayingMessageEvent(event: NowPlayingMessageEvent): void + { + const parser = event.getParser(); + + this._isPlaying = (parser.currentSongId !== -1); + + if(parser.currentSongId >= 0) + { + GetSoundManager().musicController.playSong(parser.currentSongId, MusicPriorities.PRIORITY_ROOM_PLAYLIST, (parser.syncCount / 1000), 0, 1, 1); + this._currentSongId = parser.currentSongId; + } + else + { + this.stopPlaying(); + } + + if(parser.nextSongId >= 0) GetSoundManager().musicController.addSongInfoRequest(parser.nextSongId); + + this._playPosition = parser.currentPosition; + + GetEventDispatcher().dispatchEvent(new NowPlayingEvent(NowPlayingEvent.NPE_SONG_CHANGED, MusicPriorities.PRIORITY_ROOM_PLAYLIST, parser.currentSongId, parser.currentPosition)); + } + + private onJukeboxSongDisksMessageEvent(event: JukeboxSongDisksMessageEvent): void + { + const parser = event.getParser(); + + this._entries = []; + + for(let i = 0; i < parser.songDisks.length; i++) + { + const songId = parser.songDisks.getWithIndex(i); + const diskId = parser.songDisks.getKey(i); + + let songInfo = (GetSoundManager().musicController.getSongInfo(songId) as SongDataEntry); + + if(!songInfo) + { + songInfo = new SongDataEntry(songId, -1, null, null, null); + + if(this._missingSongInfo.indexOf(songId) < 0) + { + this._missingSongInfo.push(songId); + + GetSoundManager().musicController.requestSongInfoWithoutSamples(songId); + } + } + + songInfo.diskId = diskId; + + this._entries.push(songInfo); + } + + if(!this._missingSongInfo.length) GetEventDispatcher().dispatchEvent(new PlayListStatusEvent(PlayListStatusEvent.PLUE_PLAY_LIST_UPDATED)); + } + + private onJukeboxPlayListFullMessageEvent(event: JukeboxPlayListFullMessageEvent): void + { + GetEventDispatcher().dispatchEvent(new PlayListStatusEvent(PlayListStatusEvent.PLUE_PLAY_LIST_FULL)); + } + + private onSongInfoReceivedEvent(event: SongInfoReceivedEvent): void + { + for(let i = 0; i < this.length; i++) + { + const songData = this._entries[i]; + + if(songData.id === event.id) + { + const diskId = songData.diskId; + const updatedSongData = GetSoundManager().musicController.getSongInfo(event.id); + + if(updatedSongData) + { + updatedSongData.diskId = diskId; + this._entries[i] = updatedSongData; + } + + break; + } + } + + const missingIndex = this._missingSongInfo.indexOf(event.id); + + if(missingIndex >= 0) this._missingSongInfo.splice(missingIndex, 1); + + if(!this._missingSongInfo.length) GetEventDispatcher().dispatchEvent(new PlayListStatusEvent(PlayListStatusEvent.PLUE_PLAY_LIST_UPDATED)); + } + + public stopPlaying(): void + { + GetSoundManager().musicController.stop(this.priority); + + this._currentSongId = -1; + this._playPosition = -1; + this._isPlaying = false; + } + + public getEntry(index: number): ISongInfo + { + if((index < 0) || (index >= this._entries.length)) return null; + + return this._entries[index]; + } + + public requestPlayList(): void + { + GetCommunication().connection.send(new GetJukeboxPlayListMessageComposer()); + } + + public get priority(): number + { + return MusicPriorities.PRIORITY_ROOM_PLAYLIST; + } + + public get length(): number + { + if(!this._entries) return 0; + + return this._entries.length; + } + + public get playPosition(): number + { + return this._playPosition; + } + + public get currentSongId(): number + { + return this._currentSongId; + } + + public get isPlaying(): boolean + { + return this._isPlaying; + } + + public get entries(): ISongInfo[] + { + return this._entries; + } +} diff --git a/packages/sound/src/music/MusicController.ts b/packages/sound/src/music/MusicController.ts new file mode 100644 index 0000000..8eedb4b --- /dev/null +++ b/packages/sound/src/music/MusicController.ts @@ -0,0 +1,560 @@ +import { IAdvancedMap, IMusicController, IPlaylistController, ISongInfo } from '@nitrots/api'; +import { GetCommunication, GetNowPlayingMessageComposer, GetSongInfoMessageComposer, GetUserSongDisksMessageComposer, TraxSongInfoMessageEvent, UserSongDisksInventoryMessageEvent } from '@nitrots/communication'; +import { GetConfiguration } from '@nitrots/configuration'; +import { GetEventDispatcher, NotifyPlayedSongEvent, NowPlayingEvent, RoomObjectSoundMachineEvent, SongDiskInventoryReceivedEvent, SongInfoReceivedEvent, SoundManagerEvent } from '@nitrots/events'; +import { AdvancedMap } from '@nitrots/utils'; +import { GetSoundManager } from '../GetSoundManager'; +import { SongDataEntry, SongStartRequestData } from '../common'; +import { TraxData } from '../trax/TraxData'; +import { JukeboxPlaylistController } from './JukeboxPlaylistController'; +import { MusicPlayer } from './MusicPlayer'; +import { MusicPriorities } from './MusicPriorities'; + +export class MusicController implements IMusicController +{ + public static readonly SKIP_POSITION_SET: number = -1; + private static readonly MAXIMUM_NOTIFY_PRIORITY: number = MusicPriorities.PRIORITY_ROOM_PLAYLIST; + + private _timerInstance: number = 1; + private _songRequestList: number[] = []; + private _requestedSongs: Map = new Map(); + private _availableSongs: Map = new Map(); + private _songRequestsPerPriority: SongStartRequestData[] = []; + private _songRequestCountsPerPriority: number[] = []; + private _diskInventoryMissingData: number[] = []; + private _songDiskInventory: IAdvancedMap = new AdvancedMap(); + private _priorityPlaying: number = -1; + private _requestNumberPlaying: number = -1; + private _roomItemPlaylist: IPlaylistController; + private _musicPlayer: MusicPlayer; + + private _songIdPlaying: number = 1; + private _previousNotifiedSongId: number = -1; + private _previousNotificationTime: number = -1; + + constructor() + { + this.onJukeboxInit = this.onJukeboxInit.bind(this); + this.onJukeboxDispose = this.onJukeboxDispose.bind(this); + this.onSoundMachineInit = this.onSoundMachineInit.bind(this); + this.onSoundMachineDispose = this.onSoundMachineDispose.bind(this); + + this.onTraxSongComplete = this.onTraxSongComplete.bind(this); + } + + public init(): void + { + GetCommunication().registerMessageEvent(new TraxSongInfoMessageEvent(this.onTraxSongInfoMessageEvent.bind(this))); + GetCommunication().registerMessageEvent(new UserSongDisksInventoryMessageEvent(this.onSongDiskInventoryMessage.bind(this))); + + this._timerInstance = window.setInterval(this.onTick.bind(this), 1000); + this._musicPlayer = new MusicPlayer(GetConfiguration().getValue('external.samples.url')); + + GetEventDispatcher().addEventListener(RoomObjectSoundMachineEvent.JUKEBOX_INIT, this.onJukeboxInit); + GetEventDispatcher().addEventListener(RoomObjectSoundMachineEvent.JUKEBOX_DISPOSE, this.onJukeboxDispose); + GetEventDispatcher().addEventListener(RoomObjectSoundMachineEvent.SOUND_MACHINE_INIT, this.onSoundMachineInit); + GetEventDispatcher().addEventListener(RoomObjectSoundMachineEvent.SOUND_MACHINE_DISPOSE, this.onSoundMachineDispose); + GetEventDispatcher().addEventListener(SoundManagerEvent.TRAX_SONG_COMPLETE, this.onTraxSongComplete); + } + + public getRoomItemPlaylist(_arg_1?: number): IPlaylistController + { + return this._roomItemPlaylist; + } + + public get songDiskInventory(): IAdvancedMap + { + return this._songDiskInventory; + } + + public getSongDiskInventorySize(): number + { + return this._songDiskInventory.length; + } + + public getSongDiskInventoryDiskId(k: number): number + { + if(((k >= 0) && (k < this._songDiskInventory.length))) + { + return this._songDiskInventory.getKey(k); + } + return -1; + } + + public getSongDiskInventorySongId(k: number): number + { + if(((k >= 0) && (k < this._songDiskInventory.length))) + { + return this._songDiskInventory.getWithIndex(k); + } + return -1; + } + + public getSongInfo(songId: number): ISongInfo + { + const _local_2: SongDataEntry = this.getSongDataEntry(songId); + if(!_local_2) + { + this.requestSongInfoWithoutSamples(songId); + } + return _local_2; + } + + public getSongIdPlayingAtPriority(priority: number): number + { + if(priority !== this._priorityPlaying) + { + return -1; + } + return this._songIdPlaying; + } + + public stop(priority: number): void + { + const isCurrentPlayingPriority = (priority === this._priorityPlaying); + const isTopRequestPriority = (this.getTopRequestPriority() === priority); + if(isCurrentPlayingPriority) + { + this.resetSongStartRequest(priority); + this.stopSongAtPriority(priority); + } + else + { + this.resetSongStartRequest(priority); + if(isTopRequestPriority) + { + this.reRequestSongAtPriority(this._priorityPlaying); + } + } + } + + public addSongInfoRequest(k: number): void + { + this.requestSong(k, true); + } + + public requestSongInfoWithoutSamples(k: number): void + { + this.requestSong(k, false); + } + + public requestUserSongDisks(): void + { + GetCommunication().connection.send(new GetUserSongDisksMessageComposer()); + } + + public updateVolume(_arg_1: number): void + { + this._musicPlayer.setVolume(_arg_1); + } + + public dispose(): void + { + if(this._timerInstance) + { + clearInterval(this._timerInstance); + this._timerInstance = undefined; + } + + GetEventDispatcher().removeEventListener(RoomObjectSoundMachineEvent.JUKEBOX_INIT, this.onJukeboxInit); + GetEventDispatcher().removeEventListener(RoomObjectSoundMachineEvent.JUKEBOX_DISPOSE, this.onJukeboxDispose); + GetEventDispatcher().removeEventListener(RoomObjectSoundMachineEvent.SOUND_MACHINE_INIT, this.onSoundMachineInit); + GetEventDispatcher().removeEventListener(RoomObjectSoundMachineEvent.SOUND_MACHINE_DISPOSE, this.onSoundMachineDispose); + GetEventDispatcher().removeEventListener(SoundManagerEvent.TRAX_SONG_COMPLETE, this.onTraxSongComplete); + } + + public get samplesIdsInUse(): number[] + { + let _local_3: SongStartRequestData; + let _local_4: SongDataEntry; + let k = []; + for(let i = 0; i < this._songRequestsPerPriority.length; i++) + { + if(this._songRequestsPerPriority[i]) + { + _local_3 = this._songRequestsPerPriority[i]; + _local_4 = this._availableSongs.get(_local_3.songId); + if(_local_4) + { + const songData = _local_4.songData; + if(songData.length > 0) + { + const traxData = new TraxData(songData); + k = k.concat(traxData.getSampleIds()); + } + } + } + } + return k; + } + + public onSongLoaded(songId: number): void + { + const priority = this.getTopRequestPriority(); + if(priority >= 0) + { + const songIdAtTopPriority = this.getSongIdRequestedAtPriority(priority); + if(songId === songIdAtTopPriority) + { + this.playSongObject(priority, songId); + } + } + } + + public samplesUnloaded(_arg_1: number[]): void + { + throw new Error('Method not implemented.'); + } + + protected onTraxSongComplete(k: SoundManagerEvent): void + { + if(this.getSongIdPlayingAtPriority(this._priorityPlaying) === k.id) + { + if(((this.getTopRequestPriority() === this._priorityPlaying) && (this.getSongRequestCountAtPriority(this._priorityPlaying) == this._requestNumberPlaying))) + { + this.resetSongStartRequest(this._priorityPlaying); + } + const priorityPlaying = this._priorityPlaying; + this.playSongWithHighestPriority(); + if(priorityPlaying >= MusicPriorities.PRIORITY_SONG_PLAY) + { + GetEventDispatcher().dispatchEvent(new NowPlayingEvent(NowPlayingEvent.NPW_USER_STOP_SONG, priorityPlaying, k.id, -1)); + } + } + } + + private onTraxSongInfoMessageEvent(event: TraxSongInfoMessageEvent): void + { + const parser = event.getParser(); + + for(const song of parser.songs) + { + const songAvailable = !!this.getSongDataEntry(song.id); + const areSamplesRequested = !!this.areSamplesRequested(song.id); + + if(!songAvailable) + { + if(!areSamplesRequested) + { + //_local_9 = this._soundManager.loadTraxSong(_local_6.id, _local_6.data); + } + + const songInfoEntry: SongDataEntry = new SongDataEntry(song.id, song.length, song.name, song.creator, song.data); + this._availableSongs.set(song.id, songInfoEntry); + + const topRequestPriotityIndex: number = this.getTopRequestPriority(); + const songId: number = this.getSongIdRequestedAtPriority(topRequestPriotityIndex); + if(song.id === songId) + { + this.playSongObject(topRequestPriotityIndex, songId); + } + GetEventDispatcher().dispatchEvent(new SongInfoReceivedEvent(SongInfoReceivedEvent.SIR_TRAX_SONG_INFO_RECEIVED, song.id)); + while(this._diskInventoryMissingData.indexOf(song.id) != -1) + { + this._diskInventoryMissingData.splice(this._diskInventoryMissingData.indexOf(song.id), 1); + if(this._diskInventoryMissingData.length === 0) + { + GetEventDispatcher().dispatchEvent(new SongDiskInventoryReceivedEvent(SongDiskInventoryReceivedEvent.SDIR_SONG_DISK_INVENTORY_RECEIVENT_EVENT)); + } + } + + } + } + } + + private onSongDiskInventoryMessage(event: UserSongDisksInventoryMessageEvent): void + { + const parser = event.getParser(); + + this._songDiskInventory.reset(); + for(let i = 0; i < parser.songDiskCount; i++) + { + const diskId = parser.getDiskId(i); + const songId = parser.getSongId(i); + this._songDiskInventory.add(diskId, songId); + + if(!this._availableSongs.get(songId)) + { + this._diskInventoryMissingData.push(songId); + this.requestSongInfoWithoutSamples(songId); + } + } + if(this._diskInventoryMissingData.length === 0) + { + GetEventDispatcher().dispatchEvent(new SongDiskInventoryReceivedEvent(SongDiskInventoryReceivedEvent.SDIR_SONG_DISK_INVENTORY_RECEIVENT_EVENT)); + } + } + + private onTick(): void + { + if(this._songRequestList.length === 0) return; + + GetCommunication().connection.send(new GetSongInfoMessageComposer(...this._songRequestList)); + this._songRequestList = []; + } + + private requestSong(songId: number, arg2: boolean): void + { + if(this._requestedSongs.get(songId) === undefined) + { + this._requestedSongs.set(songId, arg2); + this._songRequestList.push(songId); + } + } + + private areSamplesRequested(k: number): boolean + { + if(!this._requestedSongs.get(k)) + { + return false; + } + return this._requestedSongs.get(k); + } + + private processSongEntryForPlaying(k: number, _arg_2: boolean = true): boolean + { + const songData: SongDataEntry = this.getSongDataEntry(k); + if(!songData) + { + this.addSongInfoRequest(k); + return false; + } + /* if(_local_3.soundObject == null) + { + _local_3.soundObject = this._soundManager.loadTraxSong(_local_3.id, _local_3.songData); + } + const _local_4:IHabboSound = _local_3.soundObject; + if(!_local_4.ready) + { + return false; + } */ + return true; + } + + public playSong(songId: number, priority: number, startPos: number = 0, playLength: number = 0, fadeInSeconds: number = 0.5, fadeOutSeconds: number = 0.5): boolean + { + if(!this.addSongStartRequest(priority, songId, startPos, playLength, fadeInSeconds, fadeOutSeconds)) + { + return false; + } + if(!this.processSongEntryForPlaying(songId)) + { + return false; + } + if(priority >= this._priorityPlaying) + { + this.playSongObject(priority, songId); + } + return true; + } + + private playSongObject(priority: number, songId: number): boolean + { + if((((songId === -1) || (priority < 0)) || (priority >= MusicPriorities.PRIORITY_COUNT))) + { + return false; + } + let _local_3 = false; + if(this.stopSongAtPriority(this._priorityPlaying)) + { + _local_3 = true; + } + const songData: SongDataEntry = this.getSongDataEntry(songId); + if(!songData) + { + return false; + } + if(_local_3) + { + return true; + } + this._musicPlayer.setVolume(GetSoundManager().traxVolume); + let startPos = MusicController.SKIP_POSITION_SET; + let playLength = 0; + let fadeInSeconds = 2; + let fadeOutSeconds = 1; + + const songRequestData: SongStartRequestData = this.getSongStartRequest(priority); + + if(songRequestData) + { + startPos = songRequestData.startPos; + playLength = songRequestData.playLength; + fadeInSeconds = songRequestData.fadeInSeconds; + fadeOutSeconds = songRequestData.fadeOutSeconds; + } + if(startPos >= (songData.length / 1000)) + { + return false; + } + if(startPos <= MusicController.SKIP_POSITION_SET) + { + startPos = 0; + } + + startPos = Math.trunc(startPos); + /* + _local_5.fadeInSeconds = _local_8; + _local_5.fadeOutSeconds = _local_9; + _local_5.position = _local_6; + _local_5.play(_local_7); + */ + + this._priorityPlaying = priority; + this._requestNumberPlaying = this.getSongRequestCountAtPriority(priority); + this._songIdPlaying = songId; + if(this._priorityPlaying <= MusicController.MAXIMUM_NOTIFY_PRIORITY) + { + this.notifySongPlaying(songData); + } + this._musicPlayer.preloadSamplesForSong(songData.songData).then(() => this._musicPlayer.play(songData.songData, songData.id, startPos, playLength)); + if(priority > MusicPriorities.PRIORITY_ROOM_PLAYLIST) + { + GetEventDispatcher().dispatchEvent(new NowPlayingEvent(NowPlayingEvent.NPE_USER_PLAY_SONG, priority, songData.id, -1)); + } + return true; + } + + private notifySongPlaying(k: SongDataEntry): void + { + const _local_2 = 8000; + const timeNow = Date.now(); + if(((k.length >= _local_2) && ((!(this._previousNotifiedSongId == k.id)) || (timeNow > (this._previousNotificationTime + _local_2))))) + { + GetEventDispatcher().dispatchEvent(new NotifyPlayedSongEvent(k.name, k.creator)); + this._previousNotifiedSongId = k.id; + this._previousNotificationTime = timeNow; + } + } + + private addSongStartRequest(priority: number, songId: number, startPos: number, playLength: number, fadeInSeconds: number, fadeOutSeconds: number): boolean + { + if(((priority < 0) || (priority >= MusicPriorities.PRIORITY_COUNT))) + { + return false; + } + const songStartRequest = new SongStartRequestData(songId, startPos, playLength, fadeInSeconds, fadeOutSeconds); + this._songRequestsPerPriority[priority] = songStartRequest; + this._songRequestCountsPerPriority[priority] = (this._songRequestCountsPerPriority[priority] + 1); + return true; + } + + private getSongDataEntry(k: number): SongDataEntry + { + let entry: SongDataEntry; + if(this._availableSongs) + { + entry = (this._availableSongs.get(k)); + } + return entry; + } + + private getSongStartRequest(k: number): SongStartRequestData + { + return this._songRequestsPerPriority[k]; + } + + private getTopRequestPriority(): number + { + return this._songRequestsPerPriority.length - 1; + } + + private getSongIdRequestedAtPriority(priorityIndex: number): number + { + if(priorityIndex < 0 || priorityIndex >= MusicPriorities.PRIORITY_COUNT) return -1; + + if(!this._songRequestsPerPriority[priorityIndex]) return -1; + + return this._songRequestsPerPriority[priorityIndex].songId; + } + + private getSongRequestCountAtPriority(k: number): number + { + if(((k < 0) || (k >= MusicPriorities.PRIORITY_COUNT))) + { + return -1; + } + return this._songRequestCountsPerPriority[k]; + } + + private playSongWithHighestPriority(): void + { + let _local_3: number; + this._priorityPlaying = -1; + this._songIdPlaying = -1; + this._requestNumberPlaying = -1; + const k = this.getTopRequestPriority(); + let _local_2 = k; + while(_local_2 >= 0) + { + _local_3 = this.getSongIdRequestedAtPriority(_local_2); + if(((_local_3 >= 0) && (this.playSongObject(_local_2, _local_3)))) + { + return; + } + _local_2--; + } + } + + private resetSongStartRequest(priority: number): void + { + if(((priority >= 0) && (priority < MusicPriorities.PRIORITY_COUNT))) + { + this._songRequestsPerPriority[priority] = undefined; + } + } + + private reRequestSongAtPriority(k: number): void + { + this._songRequestCountsPerPriority[k] = (this._songRequestCountsPerPriority[k] + 1); + } + + private stopSongAtPriority(priority: number): boolean + { + if(((priority === this._priorityPlaying) && (this._priorityPlaying >= 0))) + { + const songIdAtPriority = this.getSongIdPlayingAtPriority(priority); + if(songIdAtPriority >= 0) + { + const songData = this.getSongDataEntry(songIdAtPriority); + //this.stopSongDataEntry(_local_3); + this._musicPlayer.stop(); + return true; + } + } + return false; + } + + private onSoundMachineInit(k: Event): void + { + this.disposeRoomPlaylist(); + //this._roomItemPlaylist = (new SoundMachinePlayListController(this._soundManager, this, this._events) as IPlaylistController); + } + + private onSoundMachineDispose(k: Event): void + { + this.disposeRoomPlaylist(); + } + + private onJukeboxInit(k: Event): void + { + this.disposeRoomPlaylist(); + this._roomItemPlaylist = (new JukeboxPlaylistController() as IPlaylistController); + this._roomItemPlaylist.init(); + GetCommunication().connection.send(new GetNowPlayingMessageComposer()); + } + + private onJukeboxDispose(k: Event): void + { + this.disposeRoomPlaylist(); + } + + private disposeRoomPlaylist(): void + { + if(this._roomItemPlaylist) + { + this._roomItemPlaylist.dispose(); + this._roomItemPlaylist = undefined; + } + } +} diff --git a/packages/sound/src/music/MusicPlayer.ts b/packages/sound/src/music/MusicPlayer.ts new file mode 100644 index 0000000..6f005fd --- /dev/null +++ b/packages/sound/src/music/MusicPlayer.ts @@ -0,0 +1,240 @@ +import { GetEventDispatcher, SoundManagerEvent } from '@nitrots/events'; +import { NitroLogger } from '@nitrots/utils'; +import { Howl, Howler } from 'howler'; +import { TraxData } from '../trax/TraxData'; + +export class MusicPlayer +{ + private _currentSong: TraxData | undefined; + private _currentSongId: number; + private _startPos: number; + private _playLength: number; + private _isPlaying: boolean; + private _currentPos: number; + private _cache: Map; + private _sampleUrl: string; + + private _tickerInterval: number | undefined; + private _sequence: ISequenceEntry[][]; + + constructor(sampleUrl: string) + { + this._sampleUrl = sampleUrl; + this._isPlaying = false; + this._startPos = 0; + this._currentPos = 0; + this._playLength = 0; + this._sequence = []; + this._cache = new Map(); + } + + public async play(song: string, currentSongId: number, startPos: number = 0, playLength: number = -1): Promise + { + this.reset(); + + this._currentSong = new TraxData(song); + this._startPos = Math.trunc(startPos); + this._playLength = playLength; + this._currentPos = this._startPos; + this._currentSongId = currentSongId; + //this.emit('loading'); + await this.preload(); + this._isPlaying = true; + //this.emit('playing', this._currentPos, this._playLength - 1); + this.tick(); // to evade initial 1 sec delay + this._tickerInterval = window.setInterval(() => this.tick(), 1000); + } + + private reset(): void + { + this._isPlaying = false; + window.clearInterval(this._tickerInterval); + + Howler.stop(); + this._currentSongId = -1; + this._currentSong = undefined; + this._tickerInterval = undefined; + this._startPos = 0; + this._playLength = 0; + this._sequence = []; + this._currentPos = 0; + } + + public pause(): void + { + this._isPlaying = false; + //this.emit('paused', this._currentPos); + + Howler.stop(); + } + + public resume(): void + { + this._isPlaying = true; + //this.emit('playing', this._currentPos, this._playLength - 1 ); + } + + public stop(): void + { + const songId = this._currentSongId; + this.reset(); + GetEventDispatcher().dispatchEvent(new SoundManagerEvent(SoundManagerEvent.TRAX_SONG_COMPLETE, songId)); + //this.emit('stopped'); + } + + /** + * Sets global howler volume for all sounds + * @param volume value from 0.0 to 1.0 + */ + public setVolume(volume: number): void + { + Howler.volume(volume); + } + + /** + * Gets global howler volume for all sounds + * @returns value from 0.0 to 1.0 + */ + public getVolume(): number + { + return Howler.volume(); + } + + /** + * Gets sample from cache or loads it if not in cache + * @param id sample id + * @returns howl sound object + */ + public async getSample(id: number): Promise + { + let sample = this._cache.get(id); + + if(!sample) sample = await this.loadSong(id); + + return Promise.resolve(sample); + } + + private async preload(): Promise + { + this._sequence = []; + + if(!this._currentSong) return; + + for(const channel of this._currentSong.channels) + { + const sequenceEntryArray: ISequenceEntry[] = []; + for(const sample of channel.items) + { + const sampleSound = await this.getSample(sample.id); + + const sampleCount = Math.ceil((sample.length * 2) / Math.ceil(sampleSound.duration())); + + for(let i = 0; i < sampleCount; i++) + { + for(let j = 0; j < Math.ceil(sampleSound.duration()); j++) + { + sequenceEntryArray.push({ sampleId: sample.id, offset: j }); + } + } + } + + this._sequence.push(sequenceEntryArray); + } + + if(this._playLength <= 0) this._playLength = Math.max(...this._sequence.map((value: ISequenceEntry[]) => value.length)); + } + + public async preloadSamplesForSong(song: string): Promise + { + const traxData = new TraxData(song); + + await Promise.all(traxData.getSampleIds().map(id => this.getSample(id))); + } + + private async loadSong(songId: number): Promise + { + return new Promise((resolve, reject) => + { + const sample = new Howl({ + src: [this._sampleUrl.replace('%sample%', songId.toString())], + preload: true, + }); + + sample.once('load', () => + { + this._cache.set(songId, sample); + resolve(sample); + }); + + sample.once('loaderror', () => + { + NitroLogger.error('failed to load sample ' + songId); + reject('failed to load sample ' + songId); + }); + }); + } + + + private tick(): void + { + if(this._currentPos > this._playLength - 1) + { + this.stop(); + } + + if(this._isPlaying) + { + if(this._currentSong) + { + //this.emit('time', this._currentPos); + this.playPosition(this._currentPos); + } + + this._currentPos++; + } + } + + private playPosition(pos: number): void + { + if(!this._currentSong || !this._sequence) return; + + //@ts-ignore + if(!Howler._audioUnlocked) + { + //console.log('skipping due to locked audio'); + return; + } + + for(const sequencyEntry of this._sequence) + { + const entry = sequencyEntry[pos]; + + if(!entry) continue; + + // sample -1 is play none + // sample 0 is 1 second of empty noise + if(entry.sampleId === -1 || entry.sampleId === 0) continue; + + const sampleAudio = this._cache.get(entry.sampleId); + + if(!sampleAudio) continue; + + if(entry.offset === 0) + { + sampleAudio.play(); + } + else if(!sampleAudio.playing()) + { + sampleAudio.seek(entry.offset); + sampleAudio.play(); + } + } + } + +} + +interface ISequenceEntry +{ + sampleId: number; + offset: number; +} diff --git a/packages/sound/src/music/MusicPriorities.ts b/packages/sound/src/music/MusicPriorities.ts new file mode 100644 index 0000000..3fb0599 --- /dev/null +++ b/packages/sound/src/music/MusicPriorities.ts @@ -0,0 +1,8 @@ +export class MusicPriorities +{ + public static readonly PRIORITY_ROOM_PLAYLIST: number = 0; + public static readonly PRIORITY_USER_PLAYLIST: number = 1; + public static readonly PRIORITY_SONG_PLAY: number = 2; + public static readonly PRIORITY_PURCHASE_PREVIEW: number = 3; + public static readonly PRIORITY_COUNT: number = 4; +} diff --git a/packages/sound/src/music/index.ts b/packages/sound/src/music/index.ts new file mode 100644 index 0000000..d3553d4 --- /dev/null +++ b/packages/sound/src/music/index.ts @@ -0,0 +1,3 @@ +export * from './JukeboxPlaylistController'; +export * from './MusicController'; +export * from './MusicPriorities'; diff --git a/packages/sound/src/trax/TraxChannel.ts b/packages/sound/src/trax/TraxChannel.ts new file mode 100644 index 0000000..02d2ade --- /dev/null +++ b/packages/sound/src/trax/TraxChannel.ts @@ -0,0 +1,23 @@ +import { TraxChannelItem } from './TraxChannelItem'; + +export class TraxChannel +{ + private _id: number; + private _items: TraxChannelItem[]; + + constructor(id: number) + { + this._id = id; + this._items = []; + } + + public addChannelItem(item: TraxChannelItem): void + { + this._items.push(item); + } + + public get items(): TraxChannelItem[] + { + return this._items; + } +} diff --git a/packages/sound/src/trax/TraxChannelItem.ts b/packages/sound/src/trax/TraxChannelItem.ts new file mode 100644 index 0000000..7f08c26 --- /dev/null +++ b/packages/sound/src/trax/TraxChannelItem.ts @@ -0,0 +1,21 @@ +export class TraxChannelItem +{ + private _id: number; + private _length: number; + + constructor(id: number, length: number) + { + this._id = id; + this._length = length; + } + + public get id(): number + { + return this._id; + } + + public get length(): number + { + return this._length; + } +} diff --git a/packages/sound/src/trax/TraxData.ts b/packages/sound/src/trax/TraxData.ts new file mode 100644 index 0000000..57545d3 --- /dev/null +++ b/packages/sound/src/trax/TraxData.ts @@ -0,0 +1,97 @@ +import { TraxChannel } from './TraxChannel'; +import { TraxChannelItem } from './TraxChannelItem'; + +export class TraxData +{ + private _channels: TraxChannel[]; + private _metaData: Map; + + constructor(data: string) + { + this._channels = []; + this._metaData = new Map(); + + let channelLines: string[] = []; + + const lines: string[] = data.split(':'); + const lastLine: string = lines[lines.length - 1]; + + if(lastLine.indexOf('meta') > -1) + { + const metaData: string[] = lastLine.split(';'); + + for(const meta of metaData) + { + const metaAttributes: string[] = meta.split(','); + this._metaData.set(metaAttributes[0], metaAttributes[1]); + } + + channelLines = lines.slice(0, lines.length - 1); + } + else + { + channelLines = lines; + } + + for(let i = 0; i < channelLines.length / 2; i++) + { + if(channelLines[i * 2].length > 0) + { + const channelId: number = parseInt(channelLines[i * 2]); + const channelItemSets: string[] = channelLines[(i * 2) + 1].split(';'); + + const channel: TraxChannel = new TraxChannel(channelId); + + for(const channelItemSet of channelItemSets) + { + const channelItemData: string[] = channelItemSet.split(','); + + if(channelItemData.length !== 2) return; + + channel.addChannelItem(new TraxChannelItem(parseInt(channelItemData[0]), parseInt(channelItemData[1]))); + } + + this._channels.push(channel); + } + } + } + + public get channels(): TraxChannel[] + { + return this._channels; + } + + public getSampleIds(): number[] + { + const ids: number[] = []; + + for(const channel of this._channels) + { + for(const item of channel.items) + { + if(ids.indexOf(item.id) === -1) ids.push(item.id); + } + } + + return ids; + } + + public get hasMetaData(): boolean + { + return this._metaData.has('meta'); + } + + public get metaCutMode(): boolean + { + return this._metaData.has('c'); + } + + public get metaTempo(): number | null + { + const tempo = this._metaData.get('t'); + + if(!tempo) return null; + + return parseInt(tempo); + } +} diff --git a/packages/sound/src/trax/index.ts b/packages/sound/src/trax/index.ts new file mode 100644 index 0000000..d0b4128 --- /dev/null +++ b/packages/sound/src/trax/index.ts @@ -0,0 +1,3 @@ +export * from './TraxChannel'; +export * from './TraxChannelItem'; +export * from './TraxData'; diff --git a/packages/sound/tsconfig.json b/packages/sound/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/sound/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/packages/utils/.eslintrc.json b/packages/utils/.eslintrc.json new file mode 100644 index 0000000..ad92133 --- /dev/null +++ b/packages/utils/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": [ "@nitrots/eslint-config" ] +} diff --git a/packages/utils/.gitignore b/packages/utils/.gitignore new file mode 100644 index 0000000..1413af9 --- /dev/null +++ b/packages/utils/.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/packages/utils/index.ts b/packages/utils/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/packages/utils/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/packages/utils/package.json b/packages/utils/package.json new file mode 100644 index 0000000..7029cce --- /dev/null +++ b/packages/utils/package.json @@ -0,0 +1,22 @@ +{ + "name": "@nitrots/utils", + "description": "Nitro utils module", + "version": "1.0.0", + "type": "module", + "license": "GPL-3.0", + "scripts": { + "compile": "tsc --project ./tsconfig.json --noEmit false", + "eslint": "eslint ./src --fix" + }, + "main": "./index", + "dependencies": { + "@nitrots/api": "1.0.0", + "@nitrots/eslint-config": "1.0.0", + "pako": "^2.1.0", + "pixi.js": "^8.0.4" + }, + "devDependencies": { + "@types/pako": "^2.0.3", + "typescript": "~5.4.2" + } +} diff --git a/packages/utils/src/AdvancedMap.ts b/packages/utils/src/AdvancedMap.ts new file mode 100644 index 0000000..c8b9549 --- /dev/null +++ b/packages/utils/src/AdvancedMap.ts @@ -0,0 +1,159 @@ +import { IAdvancedMap } from '@nitrots/api'; + +export class AdvancedMap implements IAdvancedMap +{ + private _length: number; + private _dictionary: Map; + private _array: U[]; + private _keys: T[]; + + constructor(map: Map = null) + { + this._length = 0; + this._dictionary = new Map(); + this._array = []; + this._keys = []; + + if(map) for(const [key, value] of map.entries()) this.add(key, value); + } + + 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: IAdvancedMap): void + { + for(const k of (newValues as AdvancedMap)._keys) this.add(k, newValues.getValue(k)); + } + + public clone(): IAdvancedMap + { + const map = new AdvancedMap(); + + map.concatenate(this); + + return map; + } +} diff --git a/packages/utils/src/ArrayBufferToBase64.ts b/packages/utils/src/ArrayBufferToBase64.ts new file mode 100644 index 0000000..aa8eb74 --- /dev/null +++ b/packages/utils/src/ArrayBufferToBase64.ts @@ -0,0 +1,11 @@ +export const ArrayBufferToBase64 = (buffer: ArrayBuffer) => +{ + 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); +}; diff --git a/packages/utils/src/BinaryReader.ts b/packages/utils/src/BinaryReader.ts new file mode 100644 index 0000000..b0c68ac --- /dev/null +++ b/packages/utils/src/BinaryReader.ts @@ -0,0 +1,82 @@ +import { IBinaryReader } from '@nitrots/api'; + +export class BinaryReader implements IBinaryReader +{ + private _position: number; + private _dataView: DataView; + + constructor(buffer: ArrayBuffer) + { + this._position = 0; + this._dataView = new DataView(buffer); + } + + public readBytes(length: number): IBinaryReader + { + const buffer = new BinaryReader(this._dataView.buffer.slice(this._position, this._position + length)); + + this._position += length; + + return buffer; + } + + public readByte(): number + { + const byte = this._dataView.getInt8(this._position); + + this._position++; + + return byte; + } + + 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 readFloat(): number + { + const float = this._dataView.getFloat32(this._position); + + this._position += 4; + + return float; + } + + public readDouble(): number + { + const double = this._dataView.getFloat64(this._position); + + this._position += 8; + + return double; + } + + 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; + } +} diff --git a/packages/utils/src/BinaryWriter.ts b/packages/utils/src/BinaryWriter.ts new file mode 100644 index 0000000..dd20ef5 --- /dev/null +++ b/packages/utils/src/BinaryWriter.ts @@ -0,0 +1,109 @@ +import { IBinaryWriter } from '@nitrots/api'; + +export class BinaryWriter implements IBinaryWriter +{ + private _buffer: Uint8Array; + private _position: number; + + constructor() + { + this._buffer = new Uint8Array(); + this._position = 0; + } + + public writeByte(byte: number): IBinaryWriter + { + const array = new Uint8Array(1); + + array[0] = byte; + + this.appendArray(array); + + return this; + } + + public writeBytes(bytes: ArrayBuffer | number[]): IBinaryWriter + { + const array = new Uint8Array(bytes); + + this.appendArray(array); + + return this; + } + + public writeShort(short: number): IBinaryWriter + { + const array = new Uint8Array(2); + + array[0] = short >> 8; + array[1] = short & 0xFF; + + this.appendArray(array); + + return this; + } + + public writeInt(integer: number): IBinaryWriter + { + 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): IBinaryWriter + { + 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.position + array.length) > this._buffer.length) ? (this.position + array.length) : this._buffer.length); + + mergedArray.set(this._buffer); + mergedArray.set(array, this.position); + + this._buffer = mergedArray; + this.position += array.length; + } + + public getBuffer(): ArrayBuffer + { + return this._buffer.buffer; + } + + public get position(): number + { + return this._position; + } + + public set position(pos: number) + { + this._position = pos; + } + + public toString(encoding?: string): string + { + return new TextDecoder(encoding).decode(this._buffer); + } +} diff --git a/packages/utils/src/ColorConverter.ts b/packages/utils/src/ColorConverter.ts new file mode 100644 index 0000000..36e5b22 --- /dev/null +++ b/packages/utils/src/ColorConverter.ts @@ -0,0 +1,354 @@ +import { IVector3D } from '@nitrots/api'; +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 hex2rgba(hex: number, out: Array | Float32Array = []): Array | Float32Array + { + out[0] = ((hex >> 16) & 0xFF) / 255; + out[1] = ((hex >> 8) & 0xFF) / 255; + out[2] = (hex & 0xFF) / 255; + out[3] = (hex & 0xFF); + + return out; + } + + public static rgb2hex(rgb: number[] | Float32Array): number + { + return (((rgb[0] * 255) << 16) + ((rgb[1] * 255) << 8) + (rgb[2] * 255 | 0)); + } + + public static rgba2hex(rgb: number[] | Float32Array): number + { + return (((rgb[0] * 255) << 16) + ((rgb[1] * 255) << 8) + (rgb[2] * 255 | 0) + (rgb[3] | 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 rgbToHSL(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 hslToRGB(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 xyz2CieLab(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.xyz2CieLab(ColorConverter.rgb2xyz(k)); + } + + public static colorize(colorA: number, colorB: number): number + { + if(colorB === 0xFFFFFFFF) return colorA; + + let r = ((colorB >> 16) & 0xFF); + let g = ((colorB >> 8) & 0xFF); + let b = (colorB & 0xFF); + + r = ((((colorA >> 16) & 0xFF) * r) / 0xFF); + g = ((((colorA >> 8) & 0xFF) * g) / 0xFF); + b = (((colorA & 0xFF) * b) / 0xFF); + + return ((colorA && 0xFF000000) | (r << 16) | (g << 8) | b); + } +} diff --git a/packages/utils/src/FurniId.ts b/packages/utils/src/FurniId.ts new file mode 100644 index 0000000..92bad2b --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/GetPixi.ts b/packages/utils/src/GetPixi.ts new file mode 100644 index 0000000..48c3f22 --- /dev/null +++ b/packages/utils/src/GetPixi.ts @@ -0,0 +1,5 @@ +import { Application } from 'pixi.js'; + +const pixi = new Application(); + +export const GetPixi = () => pixi; diff --git a/packages/utils/src/GetRenderer.ts b/packages/utils/src/GetRenderer.ts new file mode 100644 index 0000000..2b32287 --- /dev/null +++ b/packages/utils/src/GetRenderer.ts @@ -0,0 +1,12 @@ +import { AutoDetectOptions, Renderer, autoDetectRenderer } from 'pixi.js'; + +let renderer: Renderer = null; + +export const PrepareRenderer = async (options: Partial): Promise => +{ + renderer = await autoDetectRenderer(options); + + return renderer; +} + +export const GetRenderer = () => renderer; diff --git a/packages/utils/src/GetStage.ts b/packages/utils/src/GetStage.ts new file mode 100644 index 0000000..164f1a4 --- /dev/null +++ b/packages/utils/src/GetStage.ts @@ -0,0 +1,5 @@ +import { Container } from 'pixi.js'; + +const stage = new Container(); + +export const GetStage = () => stage; diff --git a/packages/utils/src/GetTexturePool.ts b/packages/utils/src/GetTexturePool.ts new file mode 100644 index 0000000..46e84fe --- /dev/null +++ b/packages/utils/src/GetTexturePool.ts @@ -0,0 +1,5 @@ +import { TexturePool } from './TexturePool'; + +const texturePool = new TexturePool(); + +export const GetTexturePool = () => texturePool; diff --git a/packages/utils/src/GetTicker.ts b/packages/utils/src/GetTicker.ts new file mode 100644 index 0000000..b2c9c78 --- /dev/null +++ b/packages/utils/src/GetTicker.ts @@ -0,0 +1,3 @@ +import { Ticker } from 'pixi.js'; + +export const GetTicker = () => Ticker.shared; diff --git a/packages/utils/src/GetTickerFPS.ts b/packages/utils/src/GetTickerFPS.ts new file mode 100644 index 0000000..e35489e --- /dev/null +++ b/packages/utils/src/GetTickerFPS.ts @@ -0,0 +1,3 @@ +import { GetTicker } from './GetTicker'; + +export const GetTickerFPS = () => GetTicker().FPS; diff --git a/packages/utils/src/GetTickerTime.ts b/packages/utils/src/GetTickerTime.ts new file mode 100644 index 0000000..8615e84 --- /dev/null +++ b/packages/utils/src/GetTickerTime.ts @@ -0,0 +1,3 @@ +import { GetTicker } from './GetTicker'; + +export const GetTickerTime = () => GetTicker().lastTime; diff --git a/packages/utils/src/HabboWebTools.ts b/packages/utils/src/HabboWebTools.ts new file mode 100644 index 0000000..491ec79 --- /dev/null +++ b/packages/utils/src/HabboWebTools.ts @@ -0,0 +1,338 @@ +import { LegacyExternalInterface } from './LegacyExternalInterface'; +import { NitroLogger } from './NitroLogger'; + +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 openWebPage(pageUrl: string): void + { + window.open(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.'); + } + } +} diff --git a/packages/utils/src/Int32.ts b/packages/utils/src/Int32.ts new file mode 100644 index 0000000..1267f48 --- /dev/null +++ b/packages/utils/src/Int32.ts @@ -0,0 +1,13 @@ +const toUint32 = (x: number) => x >>> 0; + +export const ToInt32 = (x: number) => +{ + const uint32 = toUint32(x); + + if(uint32 >= Math.pow(2, 31)) + { + return uint32 - Math.pow(2, 32); + } + + return uint32; +}; diff --git a/packages/utils/src/LegacyExternalInterface.ts b/packages/utils/src/LegacyExternalInterface.ts new file mode 100644 index 0000000..9dcc458 --- /dev/null +++ b/packages/utils/src/LegacyExternalInterface.ts @@ -0,0 +1,118 @@ +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 +{ + private static readonly MESSAGE_KEY = 'Nitro_LegacyExternalInterface'; + private static _isListeningForPostMessages = false; + + + public static get available(): boolean + { + if(!this._isListeningForPostMessages) + { + this._isListeningForPostMessages = true; + window.addEventListener('message', (ev) => + { + if(typeof ev.data !== 'string') return; + + if(ev.data.startsWith(LegacyExternalInterface.MESSAGE_KEY)) + { + const { method, params } = JSON.parse( + ev.data.substr(LegacyExternalInterface.MESSAGE_KEY.length) + ); + + const fn = (window as any)[method]; + if(!fn) return; + + fn(...params); + return; + } + + }); + } + + return true; + } + + public static call( + method: K, + ...params: Parameters + ): ReturnType | undefined + { + if(window.top !== window) + { + window.top.postMessage(LegacyExternalInterface.MESSAGE_KEY + 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/packages/utils/src/LinkTracker.ts b/packages/utils/src/LinkTracker.ts new file mode 100644 index 0000000..57f6e98 --- /dev/null +++ b/packages/utils/src/LinkTracker.ts @@ -0,0 +1,40 @@ +import { ILinkEventTracker } from '@nitrots/api'; + +const linkTrackers: ILinkEventTracker[] = []; + +export const AddLinkEventTracker = (tracker: ILinkEventTracker): void => +{ + if(linkTrackers.indexOf(tracker) >= 0) return; + + linkTrackers.push(tracker); +}; + +export const RemoveLinkEventTracker = (tracker: ILinkEventTracker): void => +{ + const index = linkTrackers.indexOf(tracker); + + if(index === -1) return; + + linkTrackers.splice(index, 1); +}; + +export const CreateLinkEvent = (link: string): void => +{ + if(!link || (link === '')) return; + + for(const tracker of 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); + } + } +}; diff --git a/packages/utils/src/Matrix4x4.ts b/packages/utils/src/Matrix4x4.ts new file mode 100644 index 0000000..89d368d --- /dev/null +++ b/packages/utils/src/Matrix4x4.ts @@ -0,0 +1,134 @@ +import { IVector3D } from '@nitrots/api'; +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 getXRotationMatrix(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 getYRotationMatrix(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 getZRotationMatrix(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 vectorMultiplication(k: IVector3D): IVector3D + { + 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 multiply(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 scalarMultiply(k: number): void + { + let index = 0; + + while(index < this._data.length) + { + this._data[index] = (this._data[index] * k); + + index++; + } + } + + public rotateX(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.multiply(this); + } + + public rotateY(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.multiply(this); + } + + public rotateZ(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.multiply(this); + } + + public skew(): void + { + } + + public transpose(): 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 equals(k: Matrix4x4): boolean + { + return false; + } + + public get data(): number[] + { + return this._data; + } +} diff --git a/packages/utils/src/NitroBundle.ts b/packages/utils/src/NitroBundle.ts new file mode 100644 index 0000000..aae462c --- /dev/null +++ b/packages/utils/src/NitroBundle.ts @@ -0,0 +1,58 @@ +import { inflate } from 'pako'; +import { Assets, Texture } from 'pixi.js'; +import { ArrayBufferToBase64 } from './ArrayBufferToBase64'; +import { BinaryReader } from './BinaryReader'; + +export class NitroBundle +{ + private static TEXT_DECODER: TextDecoder = new TextDecoder('utf-8'); + + private _jsonFile: Object = null; + private _texture: Texture = null; + + public static async from(buffer: ArrayBuffer): Promise + { + const bundle = new NitroBundle(); + + await bundle.parse(buffer); + + return bundle; + } + + public async parse(arrayBuffer: ArrayBuffer): Promise + { + 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); + const inflatedBuffer = inflate(buffer.toArrayBuffer()); + + if(fileName.endsWith('.json')) + { + this._jsonFile = JSON.parse(NitroBundle.TEXT_DECODER.decode(inflatedBuffer)); + } + else + { + this._texture = await Assets.load(`data:image/png;base64,${ ArrayBufferToBase64(inflatedBuffer) }`); + } + + fileCount--; + } + } + + public get jsonFile(): Object + { + return this._jsonFile; + } + + public get texture(): Texture + { + return this._texture; + } +} diff --git a/packages/utils/src/NitroConfig.ts b/packages/utils/src/NitroConfig.ts new file mode 100644 index 0000000..aa905eb --- /dev/null +++ b/packages/utils/src/NitroConfig.ts @@ -0,0 +1,9 @@ +export { }; + +declare global +{ + interface Window + { + NitroConfig?: { [index: string]: any }; + } +} diff --git a/packages/utils/src/NitroLogger.ts b/packages/utils/src/NitroLogger.ts new file mode 100644 index 0000000..d286d2b --- /dev/null +++ b/packages/utils/src/NitroLogger.ts @@ -0,0 +1,48 @@ +export class NitroLogger +{ + public static LOG_DEBUG: boolean = false; + public static LOG_WARN: boolean = false; + public static LOG_ERROR: boolean = false; + public static LOG_EVENTS: boolean = false; + public static LOG_PACKETS: boolean = false; + + public static log(...messages: any[]): void + { + if(!this.LOG_DEBUG) return; + + console.log(this.logPrefix(), ...messages); + } + + public static warn(...messages: any[]): void + { + if(!this.LOG_WARN) return; + + console.warn(this.logPrefix(), ...messages); + } + + public static error(...messages: any[]): void + { + if(!this.LOG_ERROR) return; + + console.error(this.logPrefix(), ...messages); + } + + public static events(...messages: any[]): void + { + if(!this.LOG_EVENTS) return; + + console.log(this.logPrefix(), ...messages); + } + + public static packets(...messages: any[]): void + { + if(!this.LOG_PACKETS) return; + + console.log(this.logPrefix(), ...messages); + } + + private static logPrefix(): string + { + return '[Nitro]'; + } +} diff --git a/packages/utils/src/NitroVersion.ts b/packages/utils/src/NitroVersion.ts new file mode 100644 index 0000000..9cf4590 --- /dev/null +++ b/packages/utils/src/NitroVersion.ts @@ -0,0 +1,31 @@ + +export class NitroVersion +{ + public static RENDERER_VERSION: string = '2.0.0'; + public static UI_VERSION: string = ''; + + public static sayHello(): void + { + if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1) + { + const args = [ + `\n %c %c %c Nitro ${NitroVersion.UI_VERSION} - Renderer ${NitroVersion.RENDERER_VERSION} %c %c %c https://discord.nitrodev.co %c %c \n\n`, + 'background: #ffffff; padding:5px 0;', + 'background: #ffffff; padding:5px 0;', + 'color: #ffffff; background: #000000; padding:5px 0;', + 'background: #ffffff; padding:5px 0;', + 'background: #ffffff; padding:5px 0;', + 'background: #000000; padding:5px 0;', + 'background: #ffffff; padding:5px 0;', + 'background: #ffffff; padding:5px 0;' + ]; + + self.console.log(...args); + } + + else if(self.console) + { + self.console.log(`Nitro ${NitroVersion.UI_VERSION} - Renderer ${NitroVersion.RENDERER_VERSION} `); + } + } +} diff --git a/packages/utils/src/Node3D.ts b/packages/utils/src/Node3D.ts new file mode 100644 index 0000000..6018858 --- /dev/null +++ b/packages/utils/src/Node3D.ts @@ -0,0 +1,32 @@ +import { IVector3D } from '@nitrots/api'; +import { Matrix4x4 } from './Matrix4x4'; +import { Vector3d } from './Vector3d'; + +export class Node3D +{ + private _location: IVector3D = null; + private _transformedLocation: IVector3D = new Vector3d(); + private _needsTransformation: boolean = false; + + constructor(x: number, y: number, z: number) + { + this._location = new Vector3d(x, y, z); + + if((x !== 0) || (y !== 0) || (z !== 0)) this._needsTransformation = true; + } + + public get location(): IVector3D + { + return this._location; + } + + public get transformedLocation(): IVector3D + { + return this._transformedLocation; + } + + public applyTransform(matrix: Matrix4x4): void + { + if(this._needsTransformation) this._transformedLocation = matrix.vectorMultiplication(this._location); + } +} diff --git a/packages/utils/src/NumberBank.ts b/packages/utils/src/NumberBank.ts new file mode 100644 index 0000000..271ab1f --- /dev/null +++ b/packages/utils/src/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 reserveNumber(): number + { + if(this._freeNumbers.length > 0) + { + const k = this._freeNumbers.pop(); + + this._reservedNumbers.push(k); + + return k; + } + + return -1; + } + + public freeNumber(k: number): void + { + const i = this._reservedNumbers.indexOf(k); + + if(i >= 0) + { + this._reservedNumbers.splice(i, 1); + + this._freeNumbers.push(k); + } + } +} diff --git a/packages/utils/src/PointMath.ts b/packages/utils/src/PointMath.ts new file mode 100644 index 0000000..376204c --- /dev/null +++ b/packages/utils/src/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 sub(k: Point, _arg_2: Point): Point + { + return new Point((k.x - _arg_2.x), (k.y - _arg_2.y)); + } + + public static mul(k: Point, _arg_2: number): Point + { + return new Point((k.x * _arg_2), (k.y * _arg_2)); + } +} diff --git a/packages/utils/src/RoomId.ts b/packages/utils/src/RoomId.ts new file mode 100644 index 0000000..8df53a0 --- /dev/null +++ b/packages/utils/src/RoomId.ts @@ -0,0 +1,14 @@ +export class RoomId +{ + private static PREVIEW_ROOM_ID_BASE: number = 0x7FFF0000; + + public static makeRoomPreviewerId(roomId: number): number + { + return (roomId & 0xFFFF) + RoomId.PREVIEW_ROOM_ID_BASE; + } + + public static isRoomPreviewerId(roomId: number): boolean + { + return (roomId >= RoomId.PREVIEW_ROOM_ID_BASE); + } +} diff --git a/packages/utils/src/TexturePool.ts b/packages/utils/src/TexturePool.ts new file mode 100644 index 0000000..128679c --- /dev/null +++ b/packages/utils/src/TexturePool.ts @@ -0,0 +1,105 @@ +import { NitroLogger, TextureUtils } from '@nitrots/utils'; +import { Texture } from 'pixi.js'; + +export class TexturePool +{ + private static MAX_IDLE: number = 3600; + + private _textures: { [index: string]: { [index: string]: Texture[] } } = {}; + private _totalTextures: number = 0; + private _runCount: number = 0; + + public getTotalTextures(): number + { + let total = 0; + + for(const width in this._textures) + { + for(const height in this._textures[width]) + { + total += this._textures[width][height].length; + } + } + + this._totalTextures = total; + + return this._totalTextures; + } + + public getTexture(width: number, height: number): Texture + { + if(!this._textures[width]) this._textures[width] = {}; + + if(!this._textures[width][height]) this._textures[width][height] = []; + + if(this._textures[width][height].length) + { + const texture = this._textures[width][height].shift(); + + if(texture) + { + this._totalTextures--; + + return texture; + } + } + + return TextureUtils.createRenderTexture(width, height); + } + + public putTexture(texture: Texture) + { + if(!texture) return; + + if(!this._textures[texture.width]) this._textures[texture.width] = {}; + + if(!this._textures[texture.width][texture.height]) this._textures[texture.width][texture.height] = []; + + //@ts-ignore + delete texture.source.hitMap; + + this._textures[texture.width][texture.height].push(texture); + + this._totalTextures++; + } + + public run(): void + { + this._runCount++; + + if(!this._totalTextures) return; + + for(const width in this._textures) + { + for(const height in this._textures[width]) + { + const textures = this._textures[width][height]; + + for(let i = textures.length - 1; i >= 0; i--) + { + const texture = textures[i]; + const source = texture.source; + + if((source._touched > -1) && (this._runCount - source._touched) > TexturePool.MAX_IDLE) + { + //@ts-ignore + delete texture.source.hitMap; + + if(!source.destroyed) texture.destroy(true); + + this._textures[texture.width][texture.height].splice(i, 1); + + this._totalTextures--; + + NitroLogger.log(`[TexturePool] Texture disposed: ${texture.width}x${texture.height}`); + } + } + } + } + } + + public get textures(): { [index: string]: { [index: string]: Texture[] } } + { + return this._textures; + } +} diff --git a/packages/utils/src/TextureUtils.ts b/packages/utils/src/TextureUtils.ts new file mode 100644 index 0000000..c58f621 --- /dev/null +++ b/packages/utils/src/TextureUtils.ts @@ -0,0 +1,135 @@ +import { Container, ExtractImageOptions, ExtractOptions, ExtractSystem, GenerateTextureOptions, GetPixelsOutput, ICanvas, Matrix, RenderTexture, Renderer, Sprite, Texture } from 'pixi.js'; +import { GetRenderer } from './GetRenderer'; + +export class TextureUtils +{ + public static generateTexture(options: GenerateTextureOptions | Container): Texture + { + return this.getRenderer().textureGenerator.generateTexture(options); + } + + public static generateTextureFromImage(image: HTMLImageElement): Texture + { + return Texture.from(image); + } + + public static async generateImage(options: ExtractImageOptions | Container | Texture): Promise + { + return this.getExtractor().image(options); + } + + public static async generateImageUrl(options: ExtractImageOptions | Container | Texture): Promise + { + return this.getExtractor().base64(options); + } + + public static generateCanvas(options: ExtractOptions | Container | Texture): ICanvas + { + return this.getExtractor().canvas(options); + } + + public static clearRenderTexture(texture: Texture): Texture + { + return this.writeToTexture(new Sprite(Texture.EMPTY), texture); + } + + public static createRenderTexture(width: number, height: number): Texture + { + if((width < 0) || (height < 0)) return null; + + return RenderTexture.create({ width, height }); + } + + public static createAndFillRenderTexture(width: number, height: number, color: number = 16777215): Texture + { + if((width < 0) || (height < 0)) return null; + + return this.clearAndFillRenderTexture(this.createRenderTexture(width, height), color); + } + + public static createAndWriteRenderTexture(width: number, height: number, container: Container, transform: Matrix = null): Texture + { + if((width < 0) || (height < 0)) return null; + + return this.writeToTexture(container, this.createRenderTexture(width, height), true, transform); + } + + public static clearAndFillRenderTexture(texture: Texture, color: number = 16777215): Texture + { + if(!texture) return null; + + const sprite = new Sprite(Texture.WHITE); + + sprite.tint = color; + + sprite.width = texture.width; + sprite.height = texture.height; + + return this.writeToTexture(sprite, texture); + } + + public static writeToTexture(container: Container, target: Texture, clear: boolean = true, transform: Matrix = null): Texture + { + if(!container || !target) return null; + + this.getRenderer().render({ + container, + target, + clear, + transform + }); + + return target; + } + + public static flipTextureHorizontal(texture: Texture): Texture + { + if(!texture) return null; + + const matrix = new Matrix(); + + matrix.scale(-1, 1); + matrix.translate(texture.width, 0); + + return this.createAndWriteRenderTexture(texture.width, texture.height, new Sprite(texture), matrix); + } + + public static flipTextureVertical(texture: Texture): Texture + { + if(!texture) return null; + + const matrix = new Matrix(); + + matrix.scale(1, -1); + matrix.translate(0, texture.height); + + return this.createAndWriteRenderTexture(texture.width, texture.height, new Sprite(texture), matrix); + } + + public static flipTextureHorizontalAndVertical(texture: Texture): Texture + { + if(!texture) return null; + + const matrix = new Matrix(); + + matrix.scale(-1, -1); + matrix.translate(texture.width, texture.height); + + return this.createAndWriteRenderTexture(texture.width, texture.height, new Sprite(texture), matrix); + } + + public static getPixels(options: ExtractOptions | Container | Texture): GetPixelsOutput + { + return this.getExtractor().pixels(options); + } + + public static getRenderer(): Renderer + { + return GetRenderer(); + } + + public static getExtractor(): ExtractSystem + { + return this.getRenderer().extract; + } +} diff --git a/packages/utils/src/Vector3d.ts b/packages/utils/src/Vector3d.ts new file mode 100644 index 0000000..12c3d94 --- /dev/null +++ b/packages/utils/src/Vector3d.ts @@ -0,0 +1,215 @@ +import { IVector3D } from '@nitrots/api'; + +export class Vector3d implements IVector3D +{ + private _length: number = NaN; + + constructor( + private _x: number = 0, + private _y: number = 0, + private _z: number = 0) + {} + + 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; + + const product = new Vector3d(); + + product.x = ((vector1.y * vector2.z) - (vector1.z * vector2.y)); + product.y = ((vector1.z * vector2.x) - (vector1.x * vector2.z)); + product.z = ((vector1.x * vector2.y) - (vector1.y * vector2.x)); + + return product; + } + + 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 assign(vector: IVector3D): void + { + if(!vector) return; + + this._x = vector.x; + this._y = vector.y; + this._z = vector.z; + this._length = NaN; + } + + 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 + { + if(!amount) return; + + this._x /= amount; + this._y /= amount; + this._z /= amount; + this._length = NaN; + } + + public negate(): void + { + this._x = -(this._x); + this._y = -(this._y); + this._z = -(this._z); + } + + public dotProduct(vector: IVector3D): number + { + return ((this._x * vector.x) + (this._y * vector.y)) + (this._z * vector.z); + } + + public crossProduct(vector: IVector3D): IVector3D + { + const newVector = new Vector3d(); + + newVector.x = ((this._y * vector.z) - (this._z * vector.y)); + newVector.y = ((this._z * vector.x) - (this._x * vector.z)); + newVector.z = ((this._x * vector.y) - (this._y * vector.x)); + + return newVector; + } + + public normalize(): void + { + const k = (1 / this.length); + + this._x = (this._x * k); + this._y = (this._y * k); + this._z = (this._z * k); + } + + 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}]`; + } +} diff --git a/packages/utils/src/filters/PaletteMapFilter.ts b/packages/utils/src/filters/PaletteMapFilter.ts new file mode 100644 index 0000000..103a983 --- /dev/null +++ b/packages/utils/src/filters/PaletteMapFilter.ts @@ -0,0 +1,147 @@ +import { BufferImageSource, Filter, FilterSystem, GlProgram, RenderSurface, Texture } from 'pixi.js'; +import { TextureUtils } from '../TextureUtils'; + +export interface PaletteMapFilterOptions +{ + palette: number[]; + channel: number; +} + +export class PaletteMapFilter extends Filter +{ + public static readonly CHANNEL_RED = 0; + public static readonly CHANNEL_GREEN = 1; + public static readonly CHANNEL_BLUE = 2; + public static readonly CHANNEL_ALPHA = 3; + + public static readonly DEFAULT_OPTIONS: PaletteMapFilterOptions = { + palette: [], + channel: PaletteMapFilter.CHANNEL_RED, + }; + + public uniforms: { + uPalette: Float32Array, + uChannel: Float32Array + }; + + constructor(options: PaletteMapFilterOptions) + { + options = { ...PaletteMapFilter.DEFAULT_OPTIONS, ...options }; + + const glProgram = GlProgram.from({ + vertex: `in vec2 aPosition; + out vec2 vTextureCoord; + + uniform vec4 uInputSize; + uniform vec4 uOutputFrame; + uniform vec4 uOutputTexture; + + vec4 filterVertexPosition( void ) + { + vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy; + + position.x = position.x * (2.0 / uOutputTexture.x) - 1.0; + position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z; + + return vec4(position, 0.0, 1.0); + } + + vec2 filterTextureCoord( void ) + { + return aPosition * (uOutputFrame.zw * uInputSize.zw); + } + + void main(void) + { + gl_Position = filterVertexPosition(); + vTextureCoord = filterTextureCoord(); + }`, + fragment: ` + in vec2 vTextureCoord; + out vec4 finalColor; + + uniform sampler2D uTexture; + uniform sampler2D uLutTexture; + uniform int channel; + + void main(void) { + vec4 currentColor = texture(uTexture, vTextureCoord); + vec4 adjusted = currentColor; + + if(currentColor.a > 0.0) + { + if(channel == 0) + { + adjusted = texture2D(uLutTexture, vec2((currentColor.r * 255.0 + 0.5) / 256.0, 0.5)); + } else if(channel == 1) { + adjusted = texture2D(uLutTexture, vec2((currentColor.g * 255.0 + 0.5) / 256.0, 0.5)); + } else if(channel == 2) { + adjusted = texture2D(uLutTexture, vec2((currentColor.b * 255.0 + 0.5) / 256.0, 0.5)); + } else if(channel == 3) { + adjusted = texture2D(uLutTexture, vec2((currentColor.a * 255.0 + 0.5) / 256.0, 0.5)); + } + } + + finalColor = vec4(adjusted.r, adjusted.g, adjusted.b, currentColor.a); + } + `, + name: 'palette-map-filter', + }); + + const lookUpTable = PaletteMapFilter.getLookUpTable(options.palette); + + const lutTexture = new Texture({ + source: new BufferImageSource({ + resource: Uint8Array.from(lookUpTable), + width: lookUpTable.length / 4, + height: 1 + }) + }); + + (async () => + { + console.log(await TextureUtils.generateImageUrl(lutTexture)); + })(); + + super({ + gpuProgram: null, + glProgram, + resources: { + paletteMapUniforms: { + uChannel: { value: options.channel, type: 'int' } + }, + uLutTexture: lutTexture.source + }, + }); + + this.uniforms = this.resources.paletteMapUniforms.uniforms; + + Object.assign(this, options); + } + + public apply( + filterManager: FilterSystem, + input: Texture, + output: RenderSurface, + clearMode: boolean, + ): void + { + + filterManager.applyFilter(this, input, output, clearMode); + } + + private static getLookUpTable(data: number[]): number[] + { + const lookUpTable = []; + + for(let i = 0; i < data.length; i++) + { + lookUpTable[(i * 4) + PaletteMapFilter.CHANNEL_RED] = ((data[i] >> 16) & 0xFF); + lookUpTable[(i * 4) + PaletteMapFilter.CHANNEL_GREEN] = ((data[i] >> 8) & 0xFF); + lookUpTable[(i * 4) + PaletteMapFilter.CHANNEL_BLUE] = (data[i] & 0xFF); + lookUpTable[(i * 4) + PaletteMapFilter.CHANNEL_ALPHA] = ((data[i] >> 24) & 0xFF); + } + + return lookUpTable; + } +} diff --git a/packages/utils/src/filters/PlaneMaskFilter.ts b/packages/utils/src/filters/PlaneMaskFilter.ts new file mode 100644 index 0000000..da85e3d --- /dev/null +++ b/packages/utils/src/filters/PlaneMaskFilter.ts @@ -0,0 +1,90 @@ +import { Filter, FilterSystem, GlProgram, RenderSurface, Texture } from 'pixi.js'; + +export interface PlaneMaskFilterOptions +{ +} + +export class PlaneMaskFilter extends Filter +{ + public static readonly DEFAULT_OPTIONS: PlaneMaskFilterOptions = { + }; + + public uniforms: { + }; + + constructor(options: PlaneMaskFilterOptions) + { + options = { ...PlaneMaskFilter.DEFAULT_OPTIONS, ...options }; + + const glProgram = GlProgram.from({ + vertex: `in vec2 aPosition; + out vec2 vTextureCoord; + + uniform vec4 uInputSize; + uniform vec4 uOutputFrame; + uniform vec4 uOutputTexture; + + vec4 filterVertexPosition( void ) + { + vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy; + + position.x = position.x * (2.0 / uOutputTexture.x) - 1.0; + position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z; + + return vec4(position, 0.0, 1.0); + } + + vec2 filterTextureCoord( void ) + { + return aPosition * (uOutputFrame.zw * uInputSize.zw); + } + + void main(void) + { + gl_Position = filterVertexPosition(); + vTextureCoord = filterTextureCoord(); + }`, + fragment: ` + in vec2 vTextureCoord; + out vec4 finalColor; + + uniform sampler2D uTexture; + + void main(void) { + vec4 c = texture(uTexture, vTextureCoord); + + if(c.r == 0.0 && c.g == 0.0 && c.b == 0.0) { + finalColor = vec4(0.0, 0.0, 0.0, 0.0); + } else { + finalColor = c; + } + } + `, + name: 'plane-mask-filter', + }); + + super({ + gpuProgram: null, + glProgram, + resources: { + planeMaskUniforms: { + }, + }, + }); + + this.uniforms = this.resources.planeMaskUniforms.uniforms; + + Object.assign(this, options); + } + + public apply( + filterManager: FilterSystem, + input: Texture, + output: RenderSurface, + clearMode: boolean, + ): void + { + + filterManager.applyFilter(this, input, output, clearMode); + } +} diff --git a/packages/utils/src/filters/WiredFilter.ts b/packages/utils/src/filters/WiredFilter.ts new file mode 100644 index 0000000..303ae86 --- /dev/null +++ b/packages/utils/src/filters/WiredFilter.ts @@ -0,0 +1,143 @@ +import { Color, ColorSource, Filter, FilterSystem, GlProgram, RenderSurface, Texture } from 'pixi.js'; + +export interface WiredFilterOptions +{ + lineColor: ColorSource; + color: ColorSource; +} + +export class WiredFilter extends Filter +{ + public static readonly DEFAULT_OPTIONS: WiredFilterOptions = { + lineColor: 0x000000, + color: 0x000000, + }; + + public uniforms: { + uLineColor: Float32Array, + uColor: Float32Array + }; + + private _lineColor!: Color; + private _color!: Color; + + constructor(options: WiredFilterOptions) + { + options = { ...WiredFilter.DEFAULT_OPTIONS, ...options }; + + const glProgram = GlProgram.from({ + vertex: `in vec2 aPosition; + out vec2 vTextureCoord; + + uniform vec4 uInputSize; + uniform vec4 uOutputFrame; + uniform vec4 uOutputTexture; + + vec4 filterVertexPosition( void ) + { + vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy; + + position.x = position.x * (2.0 / uOutputTexture.x) - 1.0; + position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z; + + return vec4(position, 0.0, 1.0); + } + + vec2 filterTextureCoord( void ) + { + return aPosition * (uOutputFrame.zw * uInputSize.zw); + } + + void main(void) + { + gl_Position = filterVertexPosition(); + vTextureCoord = filterTextureCoord(); + }`, + fragment: ` + in vec2 vTextureCoord; + out vec4 finalColor; + + uniform sampler2D uTexture; + uniform vec3 uLineColor; + uniform vec3 uColor; + + void main(void) { + vec4 currentColor = texture(uTexture, vTextureCoord); + vec3 colorLine = uLineColor * currentColor.a; + vec3 colorOverlay = uColor * currentColor.a; + + if(currentColor.r == 0.0 && currentColor.g == 0.0 && currentColor.b == 0.0 && currentColor.a > 0.0) { + finalColor = vec4(colorLine.r, colorLine.g, colorLine.b, currentColor.a); + } else if(currentColor.a > 0.0) { + finalColor = vec4(colorOverlay.r, colorOverlay.g, colorOverlay.b, currentColor.a); + } + } + `, + name: 'wired-filter', + }); + + super({ + gpuProgram: null, + glProgram, + resources: { + planeMaskUniforms: { + uLineColor: { value: new Float32Array(3), type: 'vec3' }, + uColor: { value: new Float32Array(3), type: 'vec3' } + }, + }, + }); + + this.uniforms = this.resources.planeMaskUniforms.uniforms; + + this._lineColor = new Color(); + this.lineColor = options.lineColor ?? 0x000000; + + this._color = new Color(); + this.color = options.color ?? 0x000000; + + Object.assign(this, options); + } + + public apply( + filterManager: FilterSystem, + input: Texture, + output: RenderSurface, + clearMode: boolean, + ): void + { + + filterManager.applyFilter(this, input, output, clearMode); + } + + public get lineColor(): ColorSource + { + return this._lineColor.value as ColorSource; + } + + public set lineColor(value: ColorSource) + { + this._lineColor.setValue(value); + + const [r, g, b] = this._lineColor.toArray(); + + this.uniforms.uLineColor[0] = r; + this.uniforms.uLineColor[1] = g; + this.uniforms.uLineColor[2] = b; + } + + public get color(): ColorSource + { + return this._color.value as ColorSource; + } + + public set color(value: ColorSource) + { + this._color.setValue(value); + + const [r, g, b] = this._color.toArray(); + + this.uniforms.uColor[0] = r; + this.uniforms.uColor[1] = g; + this.uniforms.uColor[2] = b; + } +} diff --git a/packages/utils/src/filters/index.ts b/packages/utils/src/filters/index.ts new file mode 100644 index 0000000..910b9e9 --- /dev/null +++ b/packages/utils/src/filters/index.ts @@ -0,0 +1,3 @@ +export * from './PaletteMapFilter'; +export * from './PlaneMaskFilter'; +export * from './WiredFilter'; diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts new file mode 100644 index 0000000..a25613d --- /dev/null +++ b/packages/utils/src/index.ts @@ -0,0 +1,31 @@ +export * from './AdvancedMap'; +export * from './ArrayBufferToBase64'; +export * from './BinaryReader'; +export * from './BinaryWriter'; +export * from './ColorConverter'; +export * from './FurniId'; +export * from './GetPixi'; +export * from './GetRenderer'; +export * from './GetStage'; +export * from './GetTexturePool'; +export * from './GetTicker'; +export * from './GetTickerFPS'; +export * from './GetTickerTime'; +export * from './HabboWebTools'; +export * from './Int32'; +export * from './LegacyExternalInterface'; +export * from './LinkTracker'; +export * from './Matrix4x4'; +export * from './NitroBundle'; +export * from './NitroConfig'; +export * from './NitroLogger'; +export * from './NitroVersion'; +export * from './Node3D'; +export * from './NumberBank'; +export * from './PointMath'; +export * from './RoomId'; +export * from './TexturePool'; +export * from './TextureUtils'; +export * from './Vector3d'; +export * from './filters'; +export * from './motion'; diff --git a/packages/utils/src/motion/Callback.ts b/packages/utils/src/motion/Callback.ts new file mode 100644 index 0000000..259f13c --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/Combo.ts b/packages/utils/src/motion/Combo.ts new file mode 100644 index 0000000..a5450c6 --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/Dispose.ts b/packages/utils/src/motion/Dispose.ts new file mode 100644 index 0000000..252b8e3 --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/DropBounce.ts b/packages/utils/src/motion/DropBounce.ts new file mode 100644 index 0000000..7b52fce --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/Ease.ts b/packages/utils/src/motion/Ease.ts new file mode 100644 index 0000000..1034cdf --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/EaseOut.ts b/packages/utils/src/motion/EaseOut.ts new file mode 100644 index 0000000..d59fb0f --- /dev/null +++ b/packages/utils/src/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._rate))); + } +} diff --git a/packages/utils/src/motion/EaseRate.ts b/packages/utils/src/motion/EaseRate.ts new file mode 100644 index 0000000..d5308cc --- /dev/null +++ b/packages/utils/src/motion/EaseRate.ts @@ -0,0 +1,14 @@ +import { Ease } from './Ease'; +import { Interval } from './Interval'; + +export class EaseRate extends Ease +{ + protected _rate: number; + + constructor(k: Interval, _arg_2: number) + { + super(k); + + this._rate = _arg_2; + } +} diff --git a/packages/utils/src/motion/Interval.ts b/packages/utils/src/motion/Interval.ts new file mode 100644 index 0000000..01a963b --- /dev/null +++ b/packages/utils/src/motion/Interval.ts @@ -0,0 +1,47 @@ +import { GetTickerTime } from '../GetTickerTime'; +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 = GetTickerTime(); + } + + 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/packages/utils/src/motion/JumpBy.ts b/packages/utils/src/motion/JumpBy.ts new file mode 100644 index 0000000..1b956c9 --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/Motion.ts b/packages/utils/src/motion/Motion.ts new file mode 100644 index 0000000..acf6f58 --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/Motions.ts b/packages/utils/src/motion/Motions.ts new file mode 100644 index 0000000..92c7242 --- /dev/null +++ b/packages/utils/src/motion/Motions.ts @@ -0,0 +1,194 @@ +import { GetTickerFPS } from '../GetTickerFPS'; +import { GetTickerTime } from '../GetTickerTime'; +import { Motion } from './Motion'; + +export class Motions +{ + private static _QUEUED_MOTIONS: Motion[] = []; + private static _RUNNING_MOTIONS: Motion[] = []; + private static _REMOVED_MOTIONS: Motion[] = []; + private static _TIMER: ReturnType = null; + private static _IS_UPDATING: boolean = false; + + public static get TIMER_TIME(): number + { + return (1000 / GetTickerFPS()); + } + + public static runMotion(k: Motion): Motion + { + if(((Motions._RUNNING_MOTIONS.indexOf(k) === -1) && (Motions._QUEUED_MOTIONS.indexOf(k) === -1))) + { + if(Motions._IS_UPDATING) + { + Motions._QUEUED_MOTIONS.push(k); + } + else + { + Motions._RUNNING_MOTIONS.push(k); + + k.start(); + } + + Motions.startTimer(); + } + + return k; + } + + public static removeMotion(k: Motion): void + { + let _local_2: number = Motions._RUNNING_MOTIONS.indexOf(k); + + if(_local_2 > -1) + { + if(Motions._IS_UPDATING) + { + _local_2 = Motions._REMOVED_MOTIONS.indexOf(k); + + if(_local_2 == -1) Motions._REMOVED_MOTIONS.push(k); + } + else + { + Motions._RUNNING_MOTIONS.splice(_local_2, 1); + + if(k.running) k.stop(); + + if(!Motions._RUNNING_MOTIONS.length) Motions.stopTimer(); + } + } + else + { + _local_2 = Motions._QUEUED_MOTIONS.indexOf(k); + + if(_local_2 > -1) Motions._QUEUED_MOTIONS.splice(_local_2, 1); + } + } + + public static getMotionByTag(k: string): Motion + { + for(const _local_2 of Motions._RUNNING_MOTIONS) + { + if(_local_2.tag == k) return _local_2; + } + + for(const _local_2 of Motions._QUEUED_MOTIONS) + { + if(_local_2.tag == k) return _local_2; + } + + return null; + } + + public static getMotionByTarget(k: HTMLElement): Motion + { + for(const _local_2 of Motions._RUNNING_MOTIONS) + { + if(_local_2.target == k) return _local_2; + } + + for(const _local_2 of Motions._QUEUED_MOTIONS) + { + if(_local_2.target == k) return _local_2; + } + + return null; + } + + public static getMotionByTagAndTarget(k: string, _arg_2: HTMLElement): Motion + { + for(const _local_3 of Motions._RUNNING_MOTIONS) + { + if(((_local_3.tag == k) && (_local_3.target == _arg_2))) return _local_3; + } + + for(const _local_3 of Motions._QUEUED_MOTIONS) + { + if(((_local_3.tag == k) && (_local_3.target == _arg_2))) return _local_3; + } + + return null; + } + + public static get isRunning(): boolean + { + return !!Motions._TIMER; + } + + public static get isUpdating(): boolean + { + return Motions._IS_UPDATING; + } + + private static onTick(): void + { + Motions._IS_UPDATING = true; + + const _local_2: number = GetTickerTime(); + + let _local_3: Motion = null; + + // eslint-disable-next-line no-cond-assign + while(_local_3 = Motions._QUEUED_MOTIONS.pop()) Motions._RUNNING_MOTIONS.push(_local_3); + + // eslint-disable-next-line no-cond-assign + while(_local_3 = Motions._REMOVED_MOTIONS.pop()) + { + Motions._RUNNING_MOTIONS.splice(Motions._RUNNING_MOTIONS.indexOf(_local_3), 1); + + if(_local_3.running) _local_3.stop(); + } + + for(_local_3 of Motions._RUNNING_MOTIONS) + { + if(_local_3.running) + { + _local_3.tick(_local_2); + + if(_local_3.complete) + { + Motions.removeMotion(_local_3); + } + } + else + { + Motions.removeMotion(_local_3); + } + } + + if(!Motions._RUNNING_MOTIONS.length) Motions.stopTimer(); + + Motions._IS_UPDATING = false; + } + + private static startTimer(): void + { + if(!Motions._TIMER) + { + Motions._TIMER = setInterval(Motions.onTick, Motions.TIMER_TIME); + } + } + + private static stopTimer(): void + { + if(Motions._TIMER) + { + clearInterval(Motions._TIMER); + + Motions._TIMER = null; + } + } + + + public getNumRunningMotions(k: HTMLElement): number + { + let _local_2 = 0; + + for(const _local_3 of Motions._RUNNING_MOTIONS) + { + if(_local_3.target === k) _local_2++; + } + + return _local_2; + } +} diff --git a/packages/utils/src/motion/MoveBy.ts b/packages/utils/src/motion/MoveBy.ts new file mode 100644 index 0000000..1639901 --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/MoveTo.ts b/packages/utils/src/motion/MoveTo.ts new file mode 100644 index 0000000..3d7fe2a --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/Queue.ts b/packages/utils/src/motion/Queue.ts new file mode 100644 index 0000000..990d9da --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/ResizeTo.ts b/packages/utils/src/motion/ResizeTo.ts new file mode 100644 index 0000000..d5e706b --- /dev/null +++ b/packages/utils/src/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/packages/utils/src/motion/Wait.ts b/packages/utils/src/motion/Wait.ts new file mode 100644 index 0000000..f64a01b --- /dev/null +++ b/packages/utils/src/motion/Wait.ts @@ -0,0 +1,37 @@ +import { GetTickerTime } from '../GetTickerTime'; +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 = GetTickerTime(); + } + + public tick(k: number): void + { + super.tick(k); + + this._complete = ((k - this._startTimeMs) >= this._waitTimeMs); + + if(this._complete) this.stop(); + } +} diff --git a/packages/utils/src/motion/index.ts b/packages/utils/src/motion/index.ts new file mode 100644 index 0000000..e9d75df --- /dev/null +++ b/packages/utils/src/motion/index.ts @@ -0,0 +1,16 @@ +export * from './Callback'; +export * from './Combo'; +export * from './Dispose'; +export * from './DropBounce'; +export * from './Ease'; +export * from './EaseOut'; +export * from './EaseRate'; +export * from './Interval'; +export * from './JumpBy'; +export * from './Motion'; +export * from './Motions'; +export * from './MoveBy'; +export * from './MoveTo'; +export * from './Queue'; +export * from './ResizeTo'; +export * from './Wait'; diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json new file mode 100644 index 0000000..5e8757d --- /dev/null +++ b/packages/utils/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" + }, + "include": [ + "src" ] +} diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png deleted file mode 100644 index 634eb063ec992a9de0818597bd6ea3c25820c563..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9604 zcmZ{KWmHt(7xpAG^w14Mmvr|qARvOIw3NgEfI2q|` zK7S8J8X%t9#@YbDt4zuZ7bxi-dDp<)7yt+t0swGv0KggP5pDwj2$lu_Hk|qDh(QwqS;Z?Mnw+ z_jCRCqV^wYZCwV$EXuk3=ta%vdCdigOb{SFk?Qk1MH>$?R-@?C{e{$SOwf4H_#W!X+B+&^*wW&Lw@o!|5laa6>Z*MIi34M~V5Zc+vGt*Pfx_QG*7H=dJ?k>CkT(&@2IGcQA>cM+U zR~zdj-T4K{%CrF;q3q!SfdHBITarR$c_VIyLfMa>rhjl-ZIXTACd$ug*}s5)N>%U@ zXA2y)OS@2Mq#il_%YzFeBTheG-3cEd7~zy!nwhfGZQI`I8OE6v*=!#Q10d|AbA%S{9Lii!N?9~7;mSp%7 z#`lmUuqap>a1ls|`gqK)hYtZ5>4)tlrUxkVx(EUxwTP3lF6J!Mxt_|_;{Cp+zuC~g^^ev1C*u4URt{b9gSd4@ z;dx4>s0^q2xdgIX{%T1@ku)*|NlSr0ZBaL06y-}HpY?UKxdF1#Ckkb=0bG+Y=$hUsZ(vP?i&4JKrvU)mmufTURQO8Gbdm_co+<@~Ze7qKRIn zE6H{%-tQ)}J4hEOW9o&%+#zo7z7go{6Bx7VM-J%-;c5Pb$0Z`X>0Z+1@gwz%R-HCN;A8ja6qY)|sWF0na4&Y~_BH-DLQoYr~jTb47hut^wE$EY=_8d2jPU z*14qPup zMb)52cY#+-8@aETxklrIylUCZn~)xquK(y|zR7BS=XCwcGA>eU;!gtd zwX8`ix8@deJ$nxK+L>XSEj}rDJ|opkG?T+48$oq8fWfyY+{Lq@|);Tea&0)B;A5zK{ zB)g_5gp0s&80^FMtOKf#G@RMN9>@i2HeYBg?{(olFRCTT1JuX&6CilRVdZUIQ|XJRxYT6=+g?kVBUMUt#Qmi z^dXAFBXAbg8jAob=QijpS*<>KDWxZ>8{P@YlKRyZF`vM^QwNMmG&lMuY#oI6k0T9>-k)i_ugbr!Ow*LmH`9XWg0WLlDLteu94_Nyo4r$RNPFTVl%)e&uv-UEV*B5Bh$oNFMs@OE(qn8gW`jKxJSDB`rU`(@1TO$2v#BWQ4w}q-OyQ;B`Yp#un@M)DN6~Lx=}_ z&Y#D+z!rZ)e$k5Vpia2aOPyar5I@vOVg)|EJ{q=*lQfZ(p=@hYoL?|8K2>CrtKex^ z{`sTrtv_VVwzL-`>c_!_Zr+39uwR@c2Z(Be7=4s^yAa#R`}5jQ>kvc&SN@Nmh2=}S z`Ndn>!`(Zm{={8iS>eyZ^Y+Jtdmtw9KOdO;tJY014`SM3R0oqS9$DMJ|133e8Ck=< zP3?V|Wp+Q-{4-kldUQdTAEBYIWL=~?YVRyvQ_Ip~gLp4A5jkOdEjdB@C+_QNmvANS zHhmn~a_Yxhu_>vxI3d4@T zhrYc>M~Y{jJb&<6fK%o@asMSf?)(_eBmD*ez#L8sLU!1>NJn*l;GxAK$r)6TyT_{q z5{EB@wHNwqFW+jmxe@H5xJG*bV&A);sAuurY<67SJ&e9!kEaWx?S0gC-&-?>Tw0hO zX^ESEJX9nVPTg;5I$%xrk8=4Ld_COqv4R)|wE;dAicf#?=ADsB5%ADdi0Ck}TMru@ zRA1CcSdmB5?)k>ukM)mGn{KIwdB;i(M|`;O#7gBCQM6f6gz}iai0dP9K5T8lJ+x^_ zi0Z@7EAU68Iz)ZVS3Mbh$g@iQDW%>j@lykv>C!r7e$3!|f$&xtk4u~R5Jl2=7>3>; z*2)N299R52{g^loasr5PIvoX;v)Pbu=h2c$Z|Qvk0{SGNi=UvKDfIP~M!5E@tf>CA zt&^GcQ%!3#=sej)KHHTbxRJg54bkTgQr}=kA%{E*`Z@x!i%NBZvL(OOqH|6B`DR1N zx#TF3w}DAI$;(pfhx&iIWzvb4i!UT^LOCWF?v-ZUacpyXE#~~Qul7svkoj4_Vazu7 zfoJzyoUdOE3tGSH=dc#cC@ke;LQEMxi(n9!cYSiip!^p>wK?vF&Nlsz4Z+D{-bkAI ze`+l_pJ~F((-QqKC>*uuuoI0x1{@DAl;uw(?cIq}!pE|Hlvrk`9`2l?6DCD2gz8BV zen~t}YJ%QRKUizYmQY+yw}B4HS4n?OzNWosvm&vwF1|?9a5DBN^xGG@!v;hK(m`bJ z{uU`-0>kdQ&pZ7t7HI%z24!whEU&0+x=RXLf_iAz&4L;Iv&6GHw2Yfh8qz0hdp>}>Lw zn0g;bhLmzD$$bFOiZP%mcl6E&bVJll(9$81oFUQmeN%UUmRmbKtESu+4<@K0nO2~6 zHEY~?^|XWsn|1JGRcEOu0q5$C-1?Q}Hy;BIdf`aqI%SeqAVDlp^o@3ZWctn9i-94O zq&aw&VKZ|67m=!+aqiOcW39hGlT8N%k;hvbzQ4rXn>_a6UT!anCN8}Fn_{rOCXUNb+JZ}%fgFH0N_qvJy|Z*p zQzFzLZNVd|)tH!<%+>c2Hy;>G<3eY^47sMCo;Sqrd}UKUV=ay%f6k1#OW2LVe5HC# z{M|iRTebh}D!EqOAlym@bG_?|Dw6)lH&-2~>uC}DKEh{mjD0Lk>rF9($(ZRR)lA9U z%enH`)M7_K_@|ZUxsj3+(RWy z3P1s0F@eciKk(*kYq{Fv@UG8^rMol9rN3s3elAc4ZC4K{%YQh-v_rjNE4`W_hLl2E z!H*kbzY||5`+cwlLC8WtC0$z+?3Z;Ls2x4n10L1kx1C??P5Gw7qn|`T+Lcd$-W}z? zX_R|tg{=T|)foJHX8STMMB*8f3ZF2_*_k6~y%iMwRCdce9^6hha?k z?tM3n(#mX7jHHTvkKE8?4wUtpn*D}g}%=Cwh5#>~UT(u4X0S1DUR8swNlrtsq_aS_W3e|GosHq4?qSoQQ zfIFggoyWO5hLi1FG#3cTvh-s`V|wp%=ID~`d;y!s8m`JeAQ5YbKbM?Dh-ZZ1?zH1uITT}(RH?ujPyi~D!#wStVK2gvb+IgmJ zttFcX1G-ugZUwVaje!81#8zDrTDc>6YD87989Q|#xeafvD>O|P{B$@T&bQ+h{-+A+?G$Ju9SH6 zBL*Z(zzG`+Ujo#sWF8X@$`%?Fn~KuQV%=w3KGK2oK#z%*Kv0rA7_`Dli~kts@iFFij>??F4e zLS~`a6>khKux z!cA3IJ_xItT@mQUB!_%<*3iCELGxq`W(+8tz%*01uFYaT-ylMSkqrp?8^Pq=cRoju zoSGt!Cfn76MNxYBnwl-_-ev`NsVx(i-fhcI`cGGrTlu5|7%m5ZeldeC%9nm|H8_k&>oa*0C>Vg9?@CdyW27qKeDdpCo|3Uk z;9}g|reC43S$PLjcx&&AKGUzYWxg=|WElv>em#J!rOO(iRB4u%yJ55xQ{#WC zJlVwc_n*ROF+V+h5-OO((oXG~C!>bBf?_`!F#f#^`Zskrs#(#K=~rcN+xI!TR#S^Q&7;)ioQ%@HcV&j3PFw0 zI(u`TYxW!=HbnZLfB}i*S(I%3$|Fa;Z3NL76F=8!^R#{pXG}&qcJKM$h_dQ9RUfel za#u_InTRS0w%pGw1%EO13F}P^iDWSG+d@C=#OY``g@!%u)T*J`tc^#R&;`O74U+)v z2;?A@m+STjnksr=IH>!40(&pgJjp0%iQ?!Xb|*{2)5hF%rpgSdrkny69?DS%2E1ea z{*&JWCs!@)#~D1jsGp4G-xIY&ShIwbHB^*a-;j2hOk@n&v(EJ+X($G$Y?AOp-sUL3 zzb?FVX5bSW`72JXDGDJ31c&tg6L$G*E)&ma`psPp!X80ATp@(Y04}D`V4XPDJo6t0 zdx~!gurw&b35P-$JDTTzXJuj`)w}q(T>T&g2)ic)&dCD^99=G1<6eHpHvj9~p3(bT z`F+ab3xt|x1pQ`RJnH#mK+-GzRv_OOD-;dI@&((xlG)j$a`dyv_GVb9ChII2k2=K@ zsW|a026@PwvjikOBmXu*bCnxKP4p!)JM*)L{nD1}X~}urAxG8RfNxd6u2CDromA@* zDn37e%jek<3X+Nd7DW4vfVS+dyNBJaytt0>=xY|Cojsl<~L%)QefPZyT1$M z5X*U^hE{jYYxl@|is?Jqq|K%GRBxMPj`D5)rJHUTTbescy~5*(EYybO>n84Xb&hIu zAm|XBgqrwQw?coH5Sd53r!5bBu4?&w4Ue)VJM0;c?Ga)xT`+2#p#Wec92Iik0z2Z)Pd_MytcCZFDD0=p~m#87+ zKTZIn3NV1z{x=U@Sl@XtC|9AmGAu5a$UdE8r)_s`q3%7ouDS6I;yKitTvR}T*=U{l zcBo7bil-MuDMCDo7&~Z>Kpl)d>^3s&W}sR!#d7E?zoDbUIAi*}`-!w=W?ucS9#(YK z_3>wt_FWqBhO;Ha$GiZC>_|%P_BED)0|vit$?Bnqg+gIgv2Z2S2S8dPw%*1aJZ<|8 z9!;f>CYZWHhWSb`x?=^mrfK(Jp<2I211L9PjK_}O&uCcNsBc|6aFDs-1#j*cu`($k z$D`@!k(J6;&lE)hnU784gX|aBnDg$(zqw-eVD_)Kp%BboKwzr9-VP8|KyEoowSsrv zev(R4SXNjv@;YAp{)NV_W5bS;t7ds`C%#BKMwNI&JkuPfv#bY!&m;O~D!^Y^dQQQS zY+ro-q<%Acm0qZ469r4_>g(mP0I}C4FF)H??0pMjvBKHOQ?*0WJ8MZC3U-%qSh0yx zyExF74)buS!M%tR@_}H*NbKf=2i!^>wjh4mpjt}#_)pwawpLrNQdIH?3YdgVzd&piuhkajemM?n4gL*#?uz-Z&S=4MpoW`NPWl8G0T|3rkTS5|n zd&zX_tHT4sb*6VEAgT#Eyr$TEKzmlD>-<}`voghL zw*z+?pU$#7k5smSj(yBPyK_P`e{mQEJ#2 z34pIzE_x+LbB=UjgArY1!5y&`Z3+(dp-S7HIq0$WF5*q%rIlZIG`LwZb|0N_TXw?D z7!pFBND|I-lOJIH9!=hzcBZi$wrsXcw|k}b%A(DSOwg6$#C~^arScU+g5uWmq>;*U zu?Y_!-U-T$0^+UmDr+34t$WXEKS1>Z?IX?H!3JfQ!?vd%M1TNCh$fmAM$R%w9JZQ0 z5^yLjjAlZRCr~uvP#eCyo8MuUE&Q?efbo~vYnQsaqwTrRD{uF`NQ|orij^EZ{n;y8 zKhxJkvkhvsKW)DKrq3s{cUt{t%2NpYT=|?G^|B5|x>vN{5Jx2LqG80}MCuLaV+Px& zRty_(tjykS6Omz-5A}s&;|?Xy?_zs)Ub4atLhoF~F9$f|d@{%w&;#LyMNz3kFF>=I zAM+pZ3GOfBqP6hYWs6x=iKj1_t?p0yW}|l!@aulp#uT1lmzAsTB?Uu=MM44)$|8JH zp$)em)o(~s)j~g$#$~i#2=D9@|6KqNpaJ02dXU^#q|hPf&lfV2B*+Sa>PO;`vQ;!g z`0sqLKSYeN3-re4U3#KT>5tIvZptDdGD`+6Yixq zrj;3_k?zq`5*r8^PT=fq%j`_6=Pj8$%2c-7YH^u5<6)VuU~tQU(iU4Ds_)5&eS))$ zP}l^*I?ws4Jlg#xa~LgWB-%-75;=)530DONb98j4*OwOyC#oOyym97IC6bv5zb(aF z5&Ccy@LFbT1KPIZ>udf& zn>G4<)v+R?pDSwyC~~eT3QiA=nA7*$L(Qw%{!rg5*8e;O6<2zPBTz54*~`scnfv`)ne1Hjo?B1j@} zQiDwe2p;2FDV5D0bl>eR(H)^fR{EJrSI%eB9Q>$i(T>t0~F6Eh)Mu_{6hAFeXXP_(;-Dpy|97%-<@g3v(8+{+Ed2P z16CvGM$lseN2=atxTlN z*VfYE7ZykFUJvG~?c)0T+ps6Ewvi1Oph!vw5lEcSvLva2#b)f&h>BQ;s zU3nR1O&~x|QRgm4@ga@3krgWaHq!=^J&V&dS5h_hS&jSx9!k~n^?b5wLe-L2HKv|Q zg7GH>Hs9wqA<%_+LGn~#TAP-o1T5Xmz4)))J65d5_a~tE`ZfgTQ;g=t(&Q&~{^}xG zd!gAZ{aIBWuMk83lu4`bx5x;fViiJ*)sFe zHST(hjCANhMUp7C6YR1;Df2`Q}FR1*CKJ}iYy}ouMhw*5GdzDE<)bG!~o??uF z%t)_C?;Ros(X%%iL#`0J7|OnBf3F0F1tsbbO!-K?q)b*(OWXtQI*Bujsfsr497uO% z7qy`NY`(LL+zK@4(?x@8EFpHQ+y}vKPuU<)!c$CxM<+8NIU>!9lN?Y=&pFXhOqYo5 zJ%n>H$g>y6_J^uan;YI`onBYS=11WayyC(*^rk6K9w_^Ix{*|bvJgyg^5C$R$^5Y*HjJrzN@IZH!`o#)y3_Z86n{!{$(9;6DE zNEJ>l@yw@By>E)YBk2rqtB;g~6d&1}*fsTVD%dAIpIV{$F#ay+b2TWF?1Tp&k>Th*~;h=r1eH6w`^>B+^a0-K%9dqXn)dqkc$J zPM=sbF}hiUhnCQm5DJ zk3A1|sJTi89o~)+fjpUb2y*KEz3cb*y7E7>-XDo=NVj6ed_6tK zB-35^82z`CR`d-r=qRDAl0KuQwd@BUHjfYfKmOzZRqb8(=Ls`3D`PwcM&ngyTvojW zlMpf~d8R=HfbZ3eb79xWK}3c21j8v$GFpPr)SX$GN|^b8n8?lUE=hql7Q`H~6}|vo0G>bS%@yN(^~cIrRbM zq9nh@gmrn-TPNkxQK901tjDWRHwKJo7N_=fnTZFkAW z&C>CB{ilaD|ua+j?WUbU{t$V)DSx@pC=5jI%zu-O2xj@3z0AFzae9RWog6CmtdOdhCCfur-LkN#Tq`7auxje_s>nX8-K@b zmid5?P}=n1E2$|}LQ$t;%;3S6zs^<}rM0+rTzcBwTpGelTWeE!65`STY%^RJcQZ3m zhPM{C6fn#of*rE=NZt=>xwwy#OH8xoVSHK@-HX zDScm;^7kT6_0yQHr&L*gg(yNg)=|fJ(4N1e;S`J9p<#@v5JU;d(kyT@Ju+KX2_n9! z;A`VBL(iubQghA96=l#HD+Y0f(ksEGQ~QQ^CBl;6e6G4xH*`Oz4#)BxB+tGp3oBz8 z(D0>uWRbU1i6~}xq~^O6n2!~7VI&7tv;|_iO5QZS@ezGrut(a^O6`8XDg)$9eajF} za5EwpxlKY&TePh!X%5Avo?7IXD86{%0QdaqolakWzgo$|e^{ z@h&Q;X;jIz!_yR$&~hn9uWXE?8t~*-ZOSCDt#I5ZLwriGztL#nm z|6ol2pI7dYMKN_`hKRFwI3)Txd-dt1k7E6)?m#OB#W5OB(`6$6k{VVrq~fxT6G|Us zF(BY=F>b0p@G1k5DT-y3D4~b(9Y*xVWsBpKVn+e@Q-{A1kIhaGWi8jSsb4-s{p73K*~a1)ac7VtnGm%A z3nYSiEBb=2Pg%i)jcVIiIyS$ibGcOFH!?r zB)j>QQ#}%V83-GsvWfH#A+rcKP7pSz*Y!LllW+d@ei@ejFKuXnysbWNRZH7P^efsd z0adOH$3jEF#{1UgwhJE9?|$pab?IP6bg$%39;}KcudZfPYY=OQPbBVWU8j3bct}Dg zj!R>!I1i85cxvSm{a3>7_S!r2W328YA83jveWmP#9RRu+HX=znyX-s+H zga1ds_r9B#N7(;gfbD|sJxRbi+|nk<+$98w4Y=>&b!2C^?$PcsA!~LWEoc*v5I0J&A aBw&+;F6aQQkV{elxN-fKZavyL=Klcpaw0GQ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png deleted file mode 100644 index 33cf6c6ab19d882ccc9e2f05ea256021a12f72ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29298 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 diff --git a/public/browserconfig.xml b/public/browserconfig.xml deleted file mode 100644 index b3930d0..0000000 --- a/public/browserconfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - #da532c - - - diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png deleted file mode 100644 index 788a7f12b42a2b1d9b7766676ff5e8e69cc19b89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1017 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>rUEcBGBP$a zG&VOk3=Y&bGc(fHH%^SzTrx}A*u==v($LpKzrIxM`8m<~eM(jN>Y)L;lk3&buUGhY zUGndB$@SBf=XR)?ngR_m@^Uu3y-xlAX_fycl>VJi{Cq%p_jD}_GZPC7i@3P>MRWRo zJl^pC_3r-{3;%CZ`G3UY^MlRVS!o6a29}nV`T6C1m0cyavyN|XPG@_+vL zmYbWaudly-`}QwizWn>~@&D?$|A)HXfA|m{9&T=Ko}Hb&bLYFxWp>$m^> zyZa#{^&WfRv$SbI1&m4F?k;ZPyMDd}a@b2eeO=j~G4pe%n{lN1{RIlW^mK6yk+__k zkdTrjCMqgCT|itkH7zkUIpMhgD^sDTW@h060d;X^^A3GAWo`BK3_=eRAF!V6*4ENo zy<(MTclRg522+m}*%?`xuU{}tZD9GL@`abDx5wA#?3V*fRnNqxgQ9 zT|C^poZnwRUw#Ewe!RW;|Aqq#5>|9gxUk_v$B7j$X56soaHw%g3M%r-imGC}a^cLH zH*@an`O|dBX9C0K74tFz3q3O_;xFERr``ez<nb!jVMV;EJ?LWE=mPb z3`Pb;e` zn=64LMdW8!fJtL=TH1ybWTTusoB(JmRNf7d`&b)&72>O_cxpR|7dmG|7~+h*V~!j%9E2${uk9$mU5mg z4~xVI?LQ<}3oi*PQNTQ?lkn(!NVnW7xX*If`>I)HS4VPKq9cYnI@Fwbax<1|Hm^Q! z#9U%THnz_Zw~Xa>p%MiNtjOij!eOyi!s9KXNvWE#9J{H=!PTIXb&zX2-`Y&fYW^vD zf28MTHU;t}Vlu0J$YRc1|4B9>SyQ4pNRzGj2IGxE8oZl*{C7|Kf&O|ojuxOiG|OK; zO*|l}f=#odMpF%$c{RR64TxLjMQRNQ!lz?-9Y=>>%MG?pscpEY_xaq(#VcsKo6_mC z&$@>0#&;ZBaCkcR5S=zmRLD6}X3S5F>xIc1TQ|-x)ecOl2V`sqK}5^mHd;s5B^zF` zJ`c5(B)vWbBSM`@p4IkFFr@DngpNGtfOmZK?jK22u^KuBx+P=iL#o+4P-(l!=?D)A z5bxPVTsRJ9@}T#GJTsVO_Dy$+c(uyRvjGa~c%8o%VQpIZwpG5n$qujh*X^O+O76~y z>(|NMjpJE9ta#?rup;jQIN4L>;&-{M+3crwq}o!vNlxiawlFzFu=qR&dqL(LmF%SY zV5R5lQ%g41o^Vr@^NF-R;{3gdJ)Gtz0~p$)#P5U)PS5DDm-r2#^4;H zHr(-&nHqvn*gL*5Eh!u7o>pC*+1H!fI+VU^Xh)(>osN20ZE$uHa7gFiyb?BuSJC_R7QX;`RM$;p{&j;Ln){A&rR9$P!9Z-`bibn^qsIoq6`| zgSdF;64`l8`?0;e2V8}w2TwH|NEGAZU-Gx!$;`p6CKyLXe*ED?>{d9Q+qN=qP|J3< zhxnfUGuYqXiL{*ttUOR*Lfdms`v#+xW(X>pz+a_gUeJTkS!gFAT_>Pfr@d3(t%#RQd3q|#@ukeH?Ht$ zeH%w6lY0h=&uU_ncaVfofXJ5$4zEA~9$L);n z2Sr`JTrCobf)dL}InrKLX6vD8zmE;wGn6KTbV$Jsk7x$ti%CW=-_z4mzfmQO)JU0B zldX>B24QuBzUfNq=kZj$Y8+-#>{z{-bMWX1D?R%(=>;VT=E#bWIW5`LpYC$E|GD#B zf2g2+ba#f%Ibz%*1TLt(dps$ zuWgE3q#xUWPV}RPhtMOiVM!5E0G4P=OEdH-vy;|7Xbkq0E!NulI2w&bqy62OEB`}? ziw~zoUi$w8V+7{BlyE-H$B#}4Nkt|k#YfUEL?G#x5+aba1bP?%7b_RmR1^|@jg5!B zMtE+E6aYmjn};c@qtwYI2&g)ez_jWOhoU$>$PvNBU>~nfw@-eA=~_!N2g@3V=xccE QGN}Y`BYF~A@YE~+0>ge95&!@I diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 34ba1b3d4ace82c0c28e6093993d5d3fe9a47d23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 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 ka>#WtcNG!P^Edoo) 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 diff --git a/public/robots.txt b/public/robots.txt deleted file mode 100644 index e9e57dc..0000000 --- a/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/public/safari-pinned-tab.svg b/public/safari-pinned-tab.svg deleted file mode 100644 index dc7ced3..0000000 --- a/public/safari-pinned-tab.svg +++ /dev/null @@ -1,154 +0,0 @@ - - - - -Created by potrace 1.14, written by Peter Selinger 2001-2017 - - - - - diff --git a/public/site.webmanifest b/public/site.webmanifest deleted file mode 100644 index 6264b89..0000000 --- a/public/site.webmanifest +++ /dev/null @@ -1,20 +0,0 @@ -{ - "start_url": "/", - "name": "Nitro", - "short_name": "Nitro", - "icons": [ - { - "src": "android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" -} diff --git a/src/App.scss b/src/App.scss deleted file mode 100644 index 2000ade..0000000 --- a/src/App.scss +++ /dev/null @@ -1,102 +0,0 @@ -$toolbar-me-zindex: 90; -$chatinput-zindex: 80; -$toolbar-zindex: 70; -$rightside-zindex: 69; -$notification-center-zindex: 68; -$toolbar-memenu-zindex: 60; -$roomtools-zindex: 50; -$context-menu-zindex: 40; -$infostand-zindex: 30; -$quiz-zindex: 21; -$chat-zindex: 20; -$highscore-zindex: 19; - -$grid-bg-color: #cdd3d9; -$grid-border-color: $muted; -$grid-active-bg-color: #ececec; -$grid-active-border-color: $white; - -$toolbar-height: 55px; - -$achievement-width: 375px; -$achievement-height: 405px; - -$avatar-editor-width: 620px; -$avatar-editor-height: 374px; - -$catalog-width: 630px; -$catalog-height: 400px; - -$inventory-width: 528px; -$inventory-height: 320px; - -$navigator-width: 420px; -$navigator-height: 440px; - -$chat-input-style-selector-widget-width: 210px; -$chat-input-style-selector-widget-height: 200px; - -$user-profile-width: 470px; -$user-profile-height: 460px; - -$nitro-widget-custom-stack-height-width: 275px; -$nitro-widget-custom-stack-height-height: 220px; - -$nitro-widget-exchange-credit-width: 375px; -$nitro-widget-exchange-credit-height: 150px; - -$nitro-widget-crafting-width: 500px; -$nitro-widget-crafting-height: 300px; - -$chat-history-width: 300px; -$chat-history-height: 300px; - -$friends-list-width: 250px; -$friends-list-height: 300px; - -$help-width: 450px; -$help-height: 290px; - -$nitropedia-width: 400px; -$nitropedia-height: 400px; - -$messenger-width: 500px; -$messenger-height: 370px; - -$marketplace-post-offer-width: 430px; -$marketplace-post-offer-height: 250px; - -$camera-editor-width: 600px; -$camera-editor-height: 500px; - -$camera-checkout-width: 350px; - -$room-info-width: 325px; - -$nitro-group-creator-width: 383px; -$nitro-mod-tools-width: 175px; - -$nitro-group-manager-width: 390px; -$nitro-group-manager-height: 355px; - -$nitro-chooser-width: 200px; -$nitro-chooser-height: 200px; - -$nitro-doorbell-width: 300px; -$nitro-doorbell-height: 200px; - -$nitro-guide-tool-width: 250px; - -$nitro-floor-editor-width: 760px; -$nitro-floor-editor-height: 500px; - -$nitro-calendar-width: 850px; -$nitro-calendar-height: 400px; - -.nitro-app { - width: 100%; - height: 100%; -} - -@import './common'; -@import './components'; diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index 1c8e72c..0000000 --- a/src/App.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { GetAssetManager, GetAvatarRenderManager, GetCommunication, GetConfiguration, GetLocalizationManager, GetRoomCameraWidgetManager, GetRoomEngine, GetRoomSessionManager, GetSessionDataManager, GetSoundManager, GetStage, GetTexturePool, GetTicker, HabboWebTools, LegacyExternalInterface, LoadGameUrlEvent, NitroLogger, NitroVersion, PrepareRenderer } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { GetUIVersion } from './api'; -import { Base } from './common'; -import { LoadingView } from './components/loading/LoadingView'; -import { MainView } from './components/main/MainView'; -import { useMessageEvent } from './hooks'; - -NitroVersion.UI_VERSION = GetUIVersion(); - -export const App: FC<{}> = props => -{ - const [ isReady, setIsReady ] = useState(false); - - useMessageEvent(LoadGameUrlEvent, event => - { - const parser = event.getParser(); - - if(!parser) return; - - LegacyExternalInterface.callGame('showGame', parser.url); - }); - - useEffect(() => - { - const prepare = async (width: number, height: number) => - { - try - { - if(!window.NitroConfig) throw new Error('NitroConfig is not defined!'); - - const renderer = await PrepareRenderer({ - width, - height, - autoDensity: true, - backgroundAlpha: 0, - preference: 'webgl', - resolution: window.devicePixelRatio - }); - - await GetConfiguration().init(); - - GetTicker().maxFPS = GetConfiguration().getValue('system.fps.max', 24); - NitroLogger.LOG_DEBUG = GetConfiguration().getValue('system.log.debug', true); - NitroLogger.LOG_WARN = GetConfiguration().getValue('system.log.warn', false); - NitroLogger.LOG_ERROR = GetConfiguration().getValue('system.log.error', false); - NitroLogger.LOG_EVENTS = GetConfiguration().getValue('system.log.events', false); - NitroLogger.LOG_PACKETS = GetConfiguration().getValue('system.log.packets', false); - - const assetUrls = GetConfiguration().getValue('preload.assets.urls').map(url => GetConfiguration().interpolate(url)) ?? []; - - await Promise.all( - [ - GetAssetManager().downloadAssets(assetUrls), - GetLocalizationManager().init(), - GetAvatarRenderManager().init(), - GetSoundManager().init(), - GetSessionDataManager().init(), - GetRoomSessionManager().init(), - GetRoomCameraWidgetManager().init() - ] - ); - - await GetRoomEngine().init(); - await GetCommunication().init(); - - // new GameMessageHandler(); - - if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'authentication', 'authok', []); - - HabboWebTools.sendHeartBeat(); - - setInterval(() => HabboWebTools.sendHeartBeat(), 10000); - - GetTicker().add(ticker => GetRoomEngine().update(ticker)); - GetTicker().add(ticker => renderer.render(GetStage())); - GetTicker().add(ticker => GetTexturePool().run()); - - setIsReady(true); - - // handle socket close - //canvas.addEventListener('webglcontextlost', () => instance.events.dispatchEvent(new NitroEvent(Nitro.WEBGL_CONTEXT_LOST))); - } - - catch(err) - { - NitroLogger.error(err); - } - } - - prepare(window.innerWidth, window.innerHeight); - }, []); - - return ( - - { !isReady && - } - { isReady && } - - - ); -} diff --git a/src/DevTools.ts b/src/DevTools.ts new file mode 100644 index 0000000..ad972b8 --- /dev/null +++ b/src/DevTools.ts @@ -0,0 +1,25 @@ +import { GetRoomEngine, RoomEngine } from '@nitrots/room'; +import { GetRenderer, GetTexturePool } from '@nitrots/utils'; +import { Texture, TextureGCSystem, TextureSource } from 'pixi.js'; +export { }; + +declare global +{ + interface Window + { + NitroDevTools?: + { + roomEngine(): RoomEngine; + textureCache(): TextureSource[]; + texturePool(): { [index: string]: { [index: string]: Texture[] } }; + textureGC(): TextureGCSystem; + }; + } +} + +window.NitroDevTools = { + roomEngine: () => GetRoomEngine(), + textureCache: () => GetRenderer().texture.managedTextures, + texturePool: () => GetTexturePool().textures, + textureGC: () => GetRenderer().textureGC +}; diff --git a/src/api/GetRendererVersion.ts b/src/api/GetRendererVersion.ts deleted file mode 100644 index bb9e461..0000000 --- a/src/api/GetRendererVersion.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { NitroVersion } from '@nitrots/nitro-renderer'; - -export const GetRendererVersion = () => NitroVersion.RENDERER_VERSION; diff --git a/src/api/GetUIVersion.ts b/src/api/GetUIVersion.ts deleted file mode 100644 index bdbe922..0000000 --- a/src/api/GetUIVersion.ts +++ /dev/null @@ -1 +0,0 @@ -export const GetUIVersion = () => '2.2.0'; diff --git a/src/api/achievements/AchievementCategory.ts b/src/api/achievements/AchievementCategory.ts deleted file mode 100644 index 906d8da..0000000 --- a/src/api/achievements/AchievementCategory.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { AchievementData } from '@nitrots/nitro-renderer'; -import { AchievementUtilities } from './AchievementUtilities'; -import { IAchievementCategory } from './IAchievementCategory'; - -export class AchievementCategory implements IAchievementCategory -{ - private _code: string; - private _achievements: AchievementData[]; - - constructor(code: string) - { - this._code = code; - this._achievements = []; - } - - public getProgress(): number - { - return AchievementUtilities.getAchievementCategoryProgress(this); - } - - public getMaxProgress(): number - { - return AchievementUtilities.getAchievementCategoryMaxProgress(this); - } - - public get code(): string - { - return this._code; - } - - public get achievements(): AchievementData[] - { - return this._achievements; - } - - public set achievements(achievements: AchievementData[]) - { - this._achievements = achievements; - } -} diff --git a/src/api/achievements/AchievementUtilities.ts b/src/api/achievements/AchievementUtilities.ts deleted file mode 100644 index 55180e6..0000000 --- a/src/api/achievements/AchievementUtilities.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { AchievementData, GetLocalizationManager } from '@nitrots/nitro-renderer'; -import { GetConfigurationValue } from '../nitro'; -import { IAchievementCategory } from './IAchievementCategory'; - -export class AchievementUtilities -{ - public static getAchievementBadgeCode(achievement: AchievementData): string - { - if(!achievement) return null; - - let badgeId = achievement.badgeId; - - if(!achievement.finalLevel) badgeId = GetLocalizationManager().getPreviousLevelBadgeId(badgeId); - - return badgeId; - } - - public static getAchievementCategoryImageUrl(category: IAchievementCategory, progress: number = null, icon: boolean = false): string - { - const imageUrl = GetConfigurationValue('achievements.images.url'); - - let imageName = icon ? 'achicon_' : 'achcategory_'; - - imageName += category.code; - - if(progress !== null) imageName += `_${ ((progress > 0) ? 'active' : 'inactive') }`; - - return imageUrl.replace('%image%', imageName); - } - - public static getAchievementCategoryMaxProgress(category: IAchievementCategory): number - { - if(!category) return 0; - - let progress = 0; - - for(const achievement of category.achievements) - { - progress += achievement.levelCount; - } - - return progress; - } - - public static getAchievementCategoryProgress(category: IAchievementCategory): number - { - if(!category) return 0; - - let progress = 0; - - for(const achievement of category.achievements) progress += (achievement.finalLevel ? achievement.level : (achievement.level - 1)); - - return progress; - } - - public static getAchievementCategoryTotalUnseen(category: IAchievementCategory): number - { - if(!category) return 0; - - let unseen = 0; - - for(const achievement of category.achievements) ((achievement.unseen > 0) && unseen++); - - return unseen; - } - - public static getAchievementHasStarted(achievement: AchievementData): boolean - { - if(!achievement) return false; - - if(achievement.finalLevel || ((achievement.level - 1) > 0)) return true; - - return false; - } - - public static getAchievementIsIgnored(achievement: AchievementData): boolean - { - if(!achievement) return false; - - const ignored = GetConfigurationValue('achievements.unseen.ignored'); - const value = achievement.badgeId.replace(/[0-9]/g, ''); - const index = ignored.indexOf(value); - - if(index >= 0) return true; - - return false; - } - - public static getAchievementLevel(achievement: AchievementData): number - { - if(!achievement) return 0; - - if(achievement.finalLevel) return achievement.level; - - return (achievement.level - 1); - } -} diff --git a/src/api/achievements/IAchievementCategory.ts b/src/api/achievements/IAchievementCategory.ts deleted file mode 100644 index a049d46..0000000 --- a/src/api/achievements/IAchievementCategory.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { AchievementData } from '@nitrots/nitro-renderer'; - -export interface IAchievementCategory -{ - code: string; - achievements: AchievementData[]; -} diff --git a/src/api/achievements/index.ts b/src/api/achievements/index.ts deleted file mode 100644 index a3d44b7..0000000 --- a/src/api/achievements/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './AchievementCategory'; -export * from './AchievementUtilities'; -export * from './IAchievementCategory'; diff --git a/src/api/avatar/AvatarEditorAction.ts b/src/api/avatar/AvatarEditorAction.ts deleted file mode 100644 index 064d6df..0000000 --- a/src/api/avatar/AvatarEditorAction.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class AvatarEditorAction -{ - public static ACTION_SAVE: string = 'AEA_ACTION_SAVE'; - public static ACTION_CLEAR: string = 'AEA_ACTION_CLEAR'; - public static ACTION_RESET: string = 'AEA_ACTION_RESET'; - public static ACTION_RANDOMIZE: string = 'AEA_ACTION_RANDOMIZE'; -} diff --git a/src/api/avatar/AvatarEditorGridColorItem.ts b/src/api/avatar/AvatarEditorGridColorItem.ts deleted file mode 100644 index dee3dae..0000000 --- a/src/api/avatar/AvatarEditorGridColorItem.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { ColorConverter, IPartColor } from '@nitrots/nitro-renderer'; - -export class AvatarEditorGridColorItem -{ - private _partColor: IPartColor; - private _isDisabled: boolean; - private _isHC: boolean; - private _isSelected: boolean; - private _notifier: () => void; - - constructor(partColor: IPartColor, isDisabled: boolean = false) - { - this._partColor = partColor; - this._isDisabled = isDisabled; - this._isHC = (this._partColor.clubLevel > 0); - this._isSelected = false; - } - - public dispose(): void - { - this._partColor = null; - } - - public get partColor(): IPartColor - { - return this._partColor; - } - - public get color(): string - { - return ColorConverter.int2rgb(this._partColor.rgb); - } - - public get isDisabled(): boolean - { - return this._isDisabled; - } - - public get isHC(): boolean - { - return this._isHC; - } - - public get isSelected(): boolean - { - return this._isSelected; - } - - public set isSelected(flag: boolean) - { - this._isSelected = flag; - - if(this.notify) this.notify(); - } - - public get notify(): () => void - { - return this._notifier; - } - - public set notify(notifier: () => void) - { - this._notifier = notifier; - } -} diff --git a/src/api/avatar/AvatarEditorGridPartItem.ts b/src/api/avatar/AvatarEditorGridPartItem.ts deleted file mode 100644 index 45e9472..0000000 --- a/src/api/avatar/AvatarEditorGridPartItem.ts +++ /dev/null @@ -1,336 +0,0 @@ -import { AvatarFigurePartType, GetAvatarRenderManager, IAvatarImageListener, IAvatarRenderManager, IFigurePart, IFigurePartSet, IGraphicAsset, IPartColor, NitroAlphaFilter, NitroContainer, NitroSprite, TextureUtils } from '@nitrots/nitro-renderer'; -import { FigureData } from './FigureData'; - -export class AvatarEditorGridPartItem implements IAvatarImageListener -{ - private static ALPHA_FILTER: NitroAlphaFilter = new NitroAlphaFilter({ alpha: 0.2 }); - private static THUMB_DIRECTIONS: number[] = [ 2, 6, 0, 4, 3, 1 ]; - private static DRAW_ORDER: string[] = [ - AvatarFigurePartType.LEFT_HAND_ITEM, - AvatarFigurePartType.LEFT_HAND, - AvatarFigurePartType.LEFT_SLEEVE, - AvatarFigurePartType.LEFT_COAT_SLEEVE, - AvatarFigurePartType.BODY, - AvatarFigurePartType.SHOES, - AvatarFigurePartType.LEGS, - AvatarFigurePartType.CHEST, - AvatarFigurePartType.CHEST_ACCESSORY, - AvatarFigurePartType.COAT_CHEST, - AvatarFigurePartType.CHEST_PRINT, - AvatarFigurePartType.WAIST_ACCESSORY, - AvatarFigurePartType.RIGHT_HAND, - AvatarFigurePartType.RIGHT_SLEEVE, - AvatarFigurePartType.RIGHT_COAT_SLEEVE, - AvatarFigurePartType.HEAD, - AvatarFigurePartType.FACE, - AvatarFigurePartType.EYES, - AvatarFigurePartType.HAIR, - AvatarFigurePartType.HAIR_BIG, - AvatarFigurePartType.FACE_ACCESSORY, - AvatarFigurePartType.EYE_ACCESSORY, - AvatarFigurePartType.HEAD_ACCESSORY, - AvatarFigurePartType.HEAD_ACCESSORY_EXTRA, - AvatarFigurePartType.RIGHT_HAND_ITEM, - ]; - - private _renderManager: IAvatarRenderManager; - private _partSet: IFigurePartSet; - private _partColors: IPartColor[]; - private _useColors: boolean; - private _isDisabled: boolean; - private _thumbContainer: NitroContainer; - private _imageUrl: string; - private _maxColorIndex: number; - private _isValidFigure: boolean; - private _isHC: boolean; - private _isSellable: boolean; - private _isClear: boolean; - private _isSelected: boolean; - private _disposed: boolean; - private _isInitalized: boolean; - private _notifier: () => void; - - constructor(partSet: IFigurePartSet, partColors: IPartColor[], useColors: boolean = true, isDisabled: boolean = false) - { - this._renderManager = GetAvatarRenderManager(); - this._partSet = partSet; - this._partColors = partColors; - this._useColors = useColors; - this._isDisabled = isDisabled; - this._thumbContainer = null; - this._imageUrl = null; - this._maxColorIndex = 0; - this._isValidFigure = false; - this._isHC = false; - this._isSellable = false; - this._isClear = false; - this._isSelected = false; - this._disposed = false; - this._isInitalized = false; - - if(partSet) - { - const colors = partSet.parts; - - for(const color of colors) this._maxColorIndex = Math.max(this._maxColorIndex, color.colorLayerIndex); - } - } - - public init(): void - { - if(this._isInitalized) return; - - this._isInitalized = true; - - this.update(); - } - - public dispose(): void - { - if(this._disposed) return; - - this._renderManager = null; - this._partSet = null; - this._partColors = null; - this._imageUrl = null; - this._disposed = true; - this._isInitalized = false; - - if(this._thumbContainer) - { - this._thumbContainer.destroy(); - - this._thumbContainer = null; - } - } - - public update(): void - { - this.updateThumbVisualization(); - } - - private analyzeFigure(): boolean - { - if(!this._renderManager || !this._partSet || !this._partSet.parts || !this._partSet.parts.length) return false; - - const figureContainer = this._renderManager.createFigureContainer(((this.partSet.type + '-') + this.partSet.id)); - - if(!this._renderManager.isFigureContainerReady(figureContainer)) - { - this._renderManager.downloadAvatarFigure(figureContainer, this); - - return false; - } - - this._isValidFigure = true; - - return true; - } - - private renderThumb(): NitroContainer - { - if(!this._renderManager || !this._partSet) return null; - - if(!this._isValidFigure) - { - if(!this.analyzeFigure()) return null; - } - - const parts = this._partSet.parts.concat().sort(this.sortByDrawOrder); - const container = new NitroContainer(); - - for(const part of parts) - { - if(!part) continue; - - let asset: IGraphicAsset = null; - let direction = 0; - let hasAsset = false; - - while(!hasAsset && (direction < AvatarEditorGridPartItem.THUMB_DIRECTIONS.length)) - { - const assetName = ((((((((((FigureData.SCALE + '_') + FigureData.STD) + '_') + part.type) + '_') + part.id) + '_') + AvatarEditorGridPartItem.THUMB_DIRECTIONS[direction]) + '_') + FigureData.DEFAULT_FRAME); - - asset = this._renderManager.getAssetByName(assetName); - - if(asset && asset.texture) - { - hasAsset = true; - } - else - { - direction++; - } - } - - if(!hasAsset) continue; - - const x = asset.offsetX; - const y = asset.offsetY; - let partColor: IPartColor = null; - - if(this._useColors && (part.colorLayerIndex > 0)) - { - const color = this._partColors[(part.colorLayerIndex - 1)]; - - if(color) partColor = color; - } - - const sprite = new NitroSprite(asset.texture); - - sprite.position.set(x, y); - - if(partColor) sprite.tint = partColor.rgb; - - container.addChild(sprite); - } - - return container; - } - - private async updateThumbVisualization(): Promise - { - if(!this._isInitalized) return; - - let container = this._thumbContainer; - - if(!container) container = this.renderThumb(); - - if(!container) return; - - if(this._partSet) - { - this._isHC = (this._partSet.clubLevel > 0); - this._isSellable = this._partSet.isSellable; - } - else - { - this._isHC = false; - this._isSellable = false; - } - - if(this._isDisabled) this.setAlpha(container, 0.2); - - this._imageUrl = await TextureUtils.generateImageUrl(container); - - if(this.notify) this.notify(); - } - - private setAlpha(container: NitroContainer, alpha: number): NitroContainer - { - container.filters = [ AvatarEditorGridPartItem.ALPHA_FILTER ]; - - return container; - } - - private sortByDrawOrder(a: IFigurePart, b: IFigurePart): number - { - const indexA = AvatarEditorGridPartItem.DRAW_ORDER.indexOf(a.type); - const indexB = AvatarEditorGridPartItem.DRAW_ORDER.indexOf(b.type); - - if(indexA < indexB) return -1; - - if(indexA > indexB) return 1; - - if(a.index < b.index) return -1; - - if(a.index > b.index) return 1; - - return 0; - } - - public resetFigure(figure: string): void - { - if(!this.analyzeFigure()) return; - - this.update(); - } - - public get disposed(): boolean - { - return this._disposed; - } - - public get id(): number - { - if(!this._partSet) return -1; - - return this._partSet.id; - } - - public get partSet(): IFigurePartSet - { - return this._partSet; - } - - public set partColors(partColors: IPartColor[]) - { - this._partColors = partColors; - - this.update(); - } - - public get isDisabled(): boolean - { - return this._isDisabled; - } - - public set thumbContainer(container: NitroContainer) - { - this._thumbContainer = container; - - this.update(); - } - - public get imageUrl(): string - { - return this._imageUrl; - } - - public get maxColorIndex(): number - { - return this._maxColorIndex; - } - - public get isHC(): boolean - { - return this._isHC; - } - - public get isSellable(): boolean - { - return this._isSellable; - } - - public get isClear(): boolean - { - return this._isClear; - } - - public set isClear(flag: boolean) - { - this._isClear = flag; - } - - public get isSelected(): boolean - { - return this._isSelected; - } - - public set isSelected(flag: boolean) - { - this._isSelected = flag; - - if(this.notify) this.notify(); - } - - public get notify(): () => void - { - return this._notifier; - } - - public set notify(notifier: () => void) - { - this._notifier = notifier; - } -} diff --git a/src/api/avatar/AvatarEditorThumbnailsHelper.ts b/src/api/avatar/AvatarEditorThumbnailsHelper.ts deleted file mode 100644 index 6be9b9b..0000000 --- a/src/api/avatar/AvatarEditorThumbnailsHelper.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { AvatarFigurePartType, AvatarScaleType, AvatarSetType, GetAssetManager, GetAvatarRenderManager, IFigurePart, IGraphicAsset, IPartColor, NitroAlphaFilter, NitroContainer, NitroSprite, TextureUtils } from '@nitrots/nitro-renderer'; -import { FigureData } from './FigureData'; -import { IAvatarEditorCategoryPartItem } from './IAvatarEditorCategoryPartItem'; - -export class AvatarEditorThumbnailsHelper -{ - private static THUMBNAIL_CACHE: Map = new Map(); - private static THUMB_DIRECTIONS: number[] = [ 2, 6, 0, 4, 3, 1 ]; - private static ALPHA_FILTER: NitroAlphaFilter = new NitroAlphaFilter({ alpha: 0.2 }); - private static DRAW_ORDER: string[] = [ - AvatarFigurePartType.LEFT_HAND_ITEM, - AvatarFigurePartType.LEFT_HAND, - AvatarFigurePartType.LEFT_SLEEVE, - AvatarFigurePartType.LEFT_COAT_SLEEVE, - AvatarFigurePartType.BODY, - AvatarFigurePartType.SHOES, - AvatarFigurePartType.LEGS, - AvatarFigurePartType.CHEST, - AvatarFigurePartType.CHEST_ACCESSORY, - AvatarFigurePartType.COAT_CHEST, - AvatarFigurePartType.CHEST_PRINT, - AvatarFigurePartType.WAIST_ACCESSORY, - AvatarFigurePartType.RIGHT_HAND, - AvatarFigurePartType.RIGHT_SLEEVE, - AvatarFigurePartType.RIGHT_COAT_SLEEVE, - AvatarFigurePartType.HEAD, - AvatarFigurePartType.FACE, - AvatarFigurePartType.EYES, - AvatarFigurePartType.HAIR, - AvatarFigurePartType.HAIR_BIG, - AvatarFigurePartType.FACE_ACCESSORY, - AvatarFigurePartType.EYE_ACCESSORY, - AvatarFigurePartType.HEAD_ACCESSORY, - AvatarFigurePartType.HEAD_ACCESSORY_EXTRA, - AvatarFigurePartType.RIGHT_HAND_ITEM, - ]; - - private static getThumbnailKey(setType: string, part: IAvatarEditorCategoryPartItem): string - { - return `${ setType }-${ part.partSet.id }`; - } - - public static clearCache(): void - { - this.THUMBNAIL_CACHE.clear(); - } - - public static async build(setType: string, part: IAvatarEditorCategoryPartItem, useColors: boolean, partColors: IPartColor[], isDisabled: boolean = false): Promise - { - if(!setType || !setType.length || !part || !part.partSet || !part.partSet.parts || !part.partSet.parts.length) return null; - - const thumbnailKey = this.getThumbnailKey(setType, part); - const cached = this.THUMBNAIL_CACHE.get(thumbnailKey); - - if(cached) return cached; - - const buildContainer = (part: IAvatarEditorCategoryPartItem, useColors: boolean, partColors: IPartColor[], isDisabled: boolean = false) => - { - const container = new NitroContainer(); - const parts = part.partSet.parts.concat().sort(this.sortByDrawOrder); - - for(const part of parts) - { - if(!part) continue; - - let asset: IGraphicAsset = null; - let direction = 0; - let hasAsset = false; - - while(!hasAsset && (direction < AvatarEditorThumbnailsHelper.THUMB_DIRECTIONS.length)) - { - const assetName = `${ FigureData.SCALE }_${ FigureData.STD }_${ part.type }_${ part.id }_${ AvatarEditorThumbnailsHelper.THUMB_DIRECTIONS[direction] }_${ FigureData.DEFAULT_FRAME }`; - - asset = GetAssetManager().getAsset(assetName); - - if(asset && asset.texture) - { - hasAsset = true; - } - else - { - direction++; - } - } - - if(!hasAsset) continue; - - const x = asset.offsetX; - const y = asset.offsetY; - - const sprite = new NitroSprite(asset.texture); - - sprite.position.set(x, y); - - if(useColors && (part.colorLayerIndex > 0) && partColors && partColors.length) - { - const color = partColors[(part.colorLayerIndex - 1)]; - - if(color) sprite.tint = color.rgb; - } - - if(isDisabled) container.filters = [ AvatarEditorThumbnailsHelper.ALPHA_FILTER ]; - - container.addChild(sprite); - } - - return container; - } - - return new Promise(async (resolve, reject) => - { - const resetFigure = async (figure: string) => - { - const container = buildContainer(part, useColors, partColors, isDisabled); - const imageUrl = await TextureUtils.generateImageUrl(container); - - AvatarEditorThumbnailsHelper.THUMBNAIL_CACHE.set(thumbnailKey, imageUrl); - - resolve(imageUrl); - } - - const figureContainer = GetAvatarRenderManager().createFigureContainer(`${ setType }-${ part.partSet.id }`); - - if(!GetAvatarRenderManager().isFigureContainerReady(figureContainer)) - { - GetAvatarRenderManager().downloadAvatarFigure(figureContainer, { - resetFigure, - dispose: null, - disposed: false - }); - } - else - { - resetFigure(null); - } - }); - } - - public static async buildForFace(figureString: string, isDisabled: boolean = false): Promise - { - if(!figureString || !figureString.length) return null; - - const thumbnailKey = figureString; - const cached = this.THUMBNAIL_CACHE.get(thumbnailKey); - - if(cached) return cached; - - return new Promise(async (resolve, reject) => - { - const resetFigure = async (figure: string) => - { - const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, null, { resetFigure, dispose: null, disposed: false }); - const texture = avatarImage.processAsTexture(AvatarSetType.HEAD, false); - const sprite = new NitroSprite(texture); - - if(isDisabled) sprite.filters = [ AvatarEditorThumbnailsHelper.ALPHA_FILTER ]; - - const imageUrl = await TextureUtils.generateImageUrl({ - target: sprite - }); - - sprite.destroy(); - avatarImage.dispose(); - - if(!avatarImage.isPlaceholder()) AvatarEditorThumbnailsHelper.THUMBNAIL_CACHE.set(thumbnailKey, imageUrl); - - resolve(imageUrl); - } - - resetFigure(figureString); - }); - } - - private static sortByDrawOrder(a: IFigurePart, b: IFigurePart): number - { - const indexA = AvatarEditorThumbnailsHelper.DRAW_ORDER.indexOf(a.type); - const indexB = AvatarEditorThumbnailsHelper.DRAW_ORDER.indexOf(b.type); - - if(indexA < indexB) return -1; - - if(indexA > indexB) return 1; - - if(a.index < b.index) return -1; - - if(a.index > b.index) return 1; - - return 0; - } -} diff --git a/src/api/avatar/AvatarEditorUtilities.ts b/src/api/avatar/AvatarEditorUtilities.ts deleted file mode 100644 index c7e2468..0000000 --- a/src/api/avatar/AvatarEditorUtilities.ts +++ /dev/null @@ -1,277 +0,0 @@ -import { GetAvatarRenderManager, IPartColor } from '@nitrots/nitro-renderer'; -import { GetClubMemberLevel, GetConfigurationValue } from '../nitro'; -import { AvatarEditorGridColorItem } from './AvatarEditorGridColorItem'; -import { AvatarEditorGridPartItem } from './AvatarEditorGridPartItem'; -import { CategoryBaseModel } from './CategoryBaseModel'; -import { CategoryData } from './CategoryData'; -import { FigureData } from './FigureData'; - -export class AvatarEditorUtilities -{ - private static MAX_PALETTES: number = 2; - - public static CURRENT_FIGURE: FigureData = null; - public static FIGURE_SET_IDS: number[] = []; - public static BOUND_FURNITURE_NAMES: string[] = []; - - public static getGender(gender: string): string - { - switch(gender) - { - case FigureData.MALE: - case 'm': - case 'M': - gender = FigureData.MALE; - break; - case FigureData.FEMALE: - case 'f': - case 'F': - gender = FigureData.FEMALE; - break; - default: - gender = FigureData.MALE; - } - - return gender; - } - - public static hasFigureSetId(setId: number): boolean - { - return (this.FIGURE_SET_IDS.indexOf(setId) >= 0); - } - - public static createCategory(model: CategoryBaseModel, name: string): CategoryData - { - if(!model || !name || !this.CURRENT_FIGURE) return null; - - const partItems: AvatarEditorGridPartItem[] = []; - const colorItems: AvatarEditorGridColorItem[][] = []; - - let i = 0; - - while(i < this.MAX_PALETTES) - { - colorItems.push([]); - - i++; - } - - const setType = GetAvatarRenderManager().structureData.getSetType(name); - - if(!setType) return null; - - const palette = GetAvatarRenderManager().structureData.getPalette(setType.paletteID); - - if(!palette) return null; - - let colorIds = this.CURRENT_FIGURE.getColorIds(name); - - if(!colorIds) colorIds = []; - - const partColors: IPartColor[] = new Array(colorIds.length); - const clubItemsDimmed = this.clubItemsDimmed; - const clubMemberLevel = GetClubMemberLevel(); - - for(const partColor of palette.colors.getValues()) - { - if(partColor.isSelectable && (clubItemsDimmed || (clubMemberLevel >= partColor.clubLevel))) - { - let i = 0; - - while(i < this.MAX_PALETTES) - { - const isDisabled = (clubMemberLevel < partColor.clubLevel); - const colorItem = new AvatarEditorGridColorItem(partColor, isDisabled); - - colorItems[i].push(colorItem); - - i++; - } - - if(name !== FigureData.FACE) - { - let i = 0; - - while(i < colorIds.length) - { - if(partColor.id === colorIds[i]) partColors[i] = partColor; - - i++; - } - } - } - } - - let mandatorySetIds: string[] = []; - - if(clubItemsDimmed) - { - mandatorySetIds = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(this.CURRENT_FIGURE.gender, 2); - } - else - { - mandatorySetIds = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(this.CURRENT_FIGURE.gender, clubMemberLevel); - } - - const isntMandatorySet = (mandatorySetIds.indexOf(name) === -1); - - if(isntMandatorySet) - { - const partItem = new AvatarEditorGridPartItem(null, null, false); - - partItem.isClear = true; - - partItems.push(partItem); - } - - const usesColors = (name !== FigureData.FACE); - const partSets = setType.partSets; - const totalPartSets = partSets.length; - - i = (totalPartSets - 1); - - while(i >= 0) - { - const partSet = partSets.getWithIndex(i); - - let isValidGender = false; - - if(partSet.gender === FigureData.UNISEX) - { - isValidGender = true; - } - - else if(partSet.gender === this.CURRENT_FIGURE.gender) - { - isValidGender = true; - } - - if(partSet.isSelectable && isValidGender && (clubItemsDimmed || (clubMemberLevel >= partSet.clubLevel))) - { - const isDisabled = (clubMemberLevel < partSet.clubLevel); - - let isValid = true; - - if(partSet.isSellable) isValid = this.hasFigureSetId(partSet.id); - - if(isValid) partItems.push(new AvatarEditorGridPartItem(partSet, partColors, usesColors, isDisabled)); - } - - i--; - } - - partItems.sort(this.clubItemsFirst ? this.clubSorter : this.noobSorter); - - // if(this._forceSellableClothingVisibility || GetNitroInstance().getConfiguration("avatareditor.support.sellablefurni", false)) - // { - // _local_31 = (this._manager.windowManager.assets.getAssetByName("camera_zoom_in") as BitmapDataAsset); - // _local_32 = (_local_31.content as BitmapData).clone(); - // _local_33 = (AvatarEditorView._Str_6802.clone() as IWindowContainer); - // _local_33.name = AvatarEditorGridView.GET_MORE; - // _local_7 = new AvatarEditorGridPartItem(_local_33, k, null, null, false); - // _local_7._Str_3093 = _local_32; - // _local_3.push(_local_7); - // } - - i = 0; - - while(i < this.MAX_PALETTES) - { - colorItems[i].sort(this.colorSorter); - - i++; - } - - return new CategoryData(name, partItems, colorItems); - } - - public static clubSorter(a: AvatarEditorGridPartItem, b: AvatarEditorGridPartItem): number - { - const clubLevelA = (!a.partSet ? 9999999999 : a.partSet.clubLevel); - const clubLevelB = (!b.partSet ? 9999999999 : b.partSet.clubLevel); - const isSellableA = (!a.partSet ? false : a.partSet.isSellable); - const isSellableB = (!b.partSet ? false : b.partSet.isSellable); - - if(isSellableA && !isSellableB) return 1; - - if(isSellableB && !isSellableA) return -1; - - if(clubLevelA > clubLevelB) return -1; - - if(clubLevelA < clubLevelB) return 1; - - if(a.partSet.id > b.partSet.id) return -1; - - if(a.partSet.id < b.partSet.id) return 1; - - return 0; - } - - public static colorSorter(a: AvatarEditorGridColorItem, b: AvatarEditorGridColorItem): number - { - const clubLevelA = (!a.partColor ? -1 : a.partColor.clubLevel); - const clubLevelB = (!b.partColor ? -1 : b.partColor.clubLevel); - - if(clubLevelA < clubLevelB) return -1; - - if(clubLevelA > clubLevelB) return 1; - - if(a.partColor.index < b.partColor.index) return -1; - - if(a.partColor.index > b.partColor.index) return 1; - - return 0; - } - - public static noobSorter(a: AvatarEditorGridPartItem, b: AvatarEditorGridPartItem): number - { - const clubLevelA = (!a.partSet ? -1 : a.partSet.clubLevel); - const clubLevelB = (!b.partSet ? -1 : b.partSet.clubLevel); - const isSellableA = (!a.partSet ? false : a.partSet.isSellable); - const isSellableB = (!b.partSet ? false : b.partSet.isSellable); - - if(isSellableA && !isSellableB) return 1; - - if(isSellableB && !isSellableA) return -1; - - if(clubLevelA < clubLevelB) return -1; - - if(clubLevelA > clubLevelB) return 1; - - if(a.partSet.id < b.partSet.id) return -1; - - if(a.partSet.id > b.partSet.id) return 1; - - return 0; - } - - public static avatarSetFirstSelectableColor(name: string): number - { - const setType = GetAvatarRenderManager().structureData.getSetType(name); - - if(!setType) return -1; - - const palette = GetAvatarRenderManager().structureData.getPalette(setType.paletteID); - - if(!palette) return -1; - - for(const color of palette.colors.getValues()) - { - if(!color.isSelectable || (GetClubMemberLevel() < color.clubLevel)) continue; - - return color.id; - } - - return -1; - } - - public static get clubItemsFirst(): boolean - { - return GetConfigurationValue('avatareditor.show.clubitems.first', true); - } - - public static get clubItemsDimmed(): boolean - { - return GetConfigurationValue('avatareditor.show.clubitems.dimmed', true); - } -} diff --git a/src/api/avatar/BodyModel.ts b/src/api/avatar/BodyModel.ts deleted file mode 100644 index d2cf7e4..0000000 --- a/src/api/avatar/BodyModel.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { AvatarEditorFigureCategory, AvatarScaleType, AvatarSetType, GetAvatarRenderManager } from '@nitrots/nitro-renderer'; -import { AvatarEditorUtilities } from './AvatarEditorUtilities'; -import { CategoryBaseModel } from './CategoryBaseModel'; -import { FigureData } from './FigureData'; - -export class BodyModel extends CategoryBaseModel -{ - private _imageCallBackHandled: boolean = false; - - public init(): void - { - super.init(); - - this.addCategory(FigureData.FACE); - - this._isInitalized = true; - } - - public selectColor(category: string, colorIndex: number, paletteId: number): void - { - super.selectColor(category, colorIndex, paletteId); - - this.updateSelectionsFromFigure(FigureData.FACE); - } - - protected updateSelectionsFromFigure(name: string): void - { - if(!this._categories || !AvatarEditorUtilities.CURRENT_FIGURE) return; - - const category = this._categories.get(name); - - if(!category) return; - - const setId = AvatarEditorUtilities.CURRENT_FIGURE.getPartSetId(name); - - let colorIds = AvatarEditorUtilities.CURRENT_FIGURE.getColorIds(name); - - if(!colorIds) colorIds = []; - - category.selectPartId(setId); - category.selectColorIds(colorIds); - - for(const part of category.parts) - { - const resetFigure = (figure: string) => - { - const figureString = AvatarEditorUtilities.CURRENT_FIGURE.getFigureStringWithFace(part.id); - const avatarImage = GetAvatarRenderManager().createAvatarImage(figureString, AvatarScaleType.LARGE, null, { resetFigure, dispose: null, disposed: false }); - - const sprite = avatarImage.processAsContainer(AvatarSetType.HEAD); - - if(sprite) - { - sprite.y = 10; - - part.thumbContainer = sprite; - - setTimeout(() => avatarImage.dispose(), 0); - } - } - - resetFigure(null); - } - } - - public get canSetGender(): boolean - { - return true; - } - - public get name(): string - { - return AvatarEditorFigureCategory.GENERIC; - } -} diff --git a/src/api/avatar/CategoryBaseModel.ts b/src/api/avatar/CategoryBaseModel.ts deleted file mode 100644 index 34dd933..0000000 --- a/src/api/avatar/CategoryBaseModel.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { AvatarEditorUtilities } from './AvatarEditorUtilities'; -import { CategoryData } from './CategoryData'; -import { IAvatarEditorCategoryModel } from './IAvatarEditorCategoryModel'; - -export class CategoryBaseModel implements IAvatarEditorCategoryModel -{ - protected _categories: Map; - protected _isInitalized: boolean; - protected _maxPaletteCount: number; - private _disposed: boolean; - - constructor() - { - this._isInitalized = false; - this._maxPaletteCount = 0; - } - - public dispose(): void - { - this._categories = null; - this._disposed = true; - } - - public get disposed(): boolean - { - return this._disposed; - } - - public init(): void - { - if(!this._categories) this._categories = new Map(); - } - - public reset(): void - { - this._isInitalized = false; - - if(this._categories) - { - for(const category of this._categories.values()) (category && category.dispose()); - } - - this._categories = new Map(); - } - - protected addCategory(name: string): void - { - let existing = this._categories.get(name); - - if(existing) return; - - existing = AvatarEditorUtilities.createCategory(this, name); - - if(!existing) return; - - this._categories.set(name, existing); - - this.updateSelectionsFromFigure(name); - } - - protected updateSelectionsFromFigure(figure: string): void - { - const category = this._categories.get(figure); - - if(!category) return; - - const setId = AvatarEditorUtilities.CURRENT_FIGURE.getPartSetId(figure); - - let colorIds = AvatarEditorUtilities.CURRENT_FIGURE.getColorIds(figure); - - if(!colorIds) colorIds = []; - - category.selectPartId(setId); - category.selectColorIds(colorIds); - } - - public hasClubSelectionsOverLevel(level: number): boolean - { - if(!this._categories) return false; - - for(const category of this._categories.values()) - { - if(!category) continue; - - if(category.hasClubSelectionsOverLevel(level)) return true; - } - - return false; - } - - public hasInvalidSelectedItems(ownedItems: number[]): boolean - { - if(!this._categories) return false; - - for(const category of this._categories.values()) - { - if(category.hasInvalidSelectedItems(ownedItems)) return true; - } - - return false; - } - - public stripClubItemsOverLevel(level: number): boolean - { - if(!this._categories) return false; - - let didStrip = false; - - for(const [ name, category ] of this._categories.entries()) - { - let isValid = false; - - if(category.stripClubItemsOverLevel(level)) isValid = true; - - if(category.stripClubColorsOverLevel(level)) isValid = true; - - if(isValid) - { - const partItem = category.getCurrentPart(); - - if(partItem && AvatarEditorUtilities.CURRENT_FIGURE) - { - AvatarEditorUtilities.CURRENT_FIGURE.savePartData(name, partItem.id, category.getSelectedColorIds(), true); - } - - didStrip = true; - } - } - - return didStrip; - } - - public stripInvalidSellableItems(): boolean - { - if(!this._categories) return false; - - let didStrip = false; - - for(const [ name, category ] of this._categories.entries()) - { - const isValid = false; - - // if(category._Str_8360(this._Str_2278.manager.inventory)) _local_6 = true; - - if(isValid) - { - const partItem = category.getCurrentPart(); - - if(partItem && AvatarEditorUtilities.CURRENT_FIGURE) - { - AvatarEditorUtilities.CURRENT_FIGURE.savePartData(name, partItem.id, category.getSelectedColorIds(), true); - } - - didStrip = true; - } - } - - return didStrip; - } - - public selectPart(category: string, partIndex: number): void - { - const categoryData = this._categories.get(category); - - if(!categoryData) return; - - const selectedPartIndex = categoryData.selectedPartIndex; - - categoryData.selectPartIndex(partIndex); - - const partItem = categoryData.getCurrentPart(); - - if(!partItem) return; - - if(partItem.isDisabled) - { - categoryData.selectPartIndex(selectedPartIndex); - - // open hc window - - return; - } - - this._maxPaletteCount = partItem.maxColorIndex; - - AvatarEditorUtilities.CURRENT_FIGURE.savePartData(category, partItem.id, categoryData.getSelectedColorIds(), true); - } - - public selectColor(category: string, colorIndex: number, paletteId: number): void - { - const categoryData = this._categories.get(category); - - if(!categoryData) return; - - const paletteIndex = categoryData.getCurrentColorIndex(paletteId); - - categoryData.selectColorIndex(colorIndex, paletteId); - - const colorItem = categoryData.getSelectedColor(paletteId); - - if(colorItem.isDisabled) - { - categoryData.selectColorIndex(paletteIndex, paletteId); - - // open hc window - - return; - } - - AvatarEditorUtilities.CURRENT_FIGURE.savePartSetColourId(category, categoryData.getSelectedColorIds(), true); - } - - public getCategoryData(category: string): CategoryData - { - if(!this._isInitalized) this.init(); - - if(!this._categories) return null; - - return this._categories.get(category); - } - - public get categories(): Map - { - return this._categories; - } - - public get canSetGender(): boolean - { - return false; - } - - public get maxPaletteCount(): number - { - return (this._maxPaletteCount || 1); - } - - public set maxPaletteCount(count: number) - { - this._maxPaletteCount = count; - } - - public get name(): string - { - return null; - } -} diff --git a/src/api/avatar/CategoryData.ts b/src/api/avatar/CategoryData.ts deleted file mode 100644 index db82f01..0000000 --- a/src/api/avatar/CategoryData.ts +++ /dev/null @@ -1,487 +0,0 @@ -import { IPartColor } from '@nitrots/nitro-renderer'; -import { AvatarEditorGridColorItem } from './AvatarEditorGridColorItem'; -import { AvatarEditorGridPartItem } from './AvatarEditorGridPartItem'; - -export class CategoryData -{ - private _name: string; - private _parts: AvatarEditorGridPartItem[]; - private _palettes: AvatarEditorGridColorItem[][]; - private _selectedPartIndex: number = -1; - private _paletteIndexes: number[]; - - constructor(name: string, partItems: AvatarEditorGridPartItem[], colorItems: AvatarEditorGridColorItem[][]) - { - this._name = name; - this._parts = partItems; - this._palettes = colorItems; - this._selectedPartIndex = -1; - } - - private static defaultColorId(palettes: AvatarEditorGridColorItem[], clubLevel: number): number - { - if(!palettes || !palettes.length) return -1; - - let i = 0; - - while(i < palettes.length) - { - const colorItem = palettes[i]; - - if(colorItem.partColor && (colorItem.partColor.clubLevel <= clubLevel)) - { - return colorItem.partColor.id; - } - - i++; - } - - return -1; - } - - public init(): void - { - for(const part of this._parts) - { - if(!part) continue; - - part.init(); - } - } - - public dispose(): void - { - if(this._parts) - { - for(const part of this._parts) part.dispose(); - - this._parts = null; - } - - if(this._palettes) - { - for(const palette of this._palettes) for(const colorItem of palette) colorItem.dispose(); - - this._palettes = null; - } - - this._selectedPartIndex = -1; - this._paletteIndexes = null; - } - - public selectPartId(partId: number): void - { - if(!this._parts) return; - - let i = 0; - - while(i < this._parts.length) - { - const partItem = this._parts[i]; - - if(partItem.id === partId) - { - this.selectPartIndex(i); - - return; - } - - i++; - } - } - - public selectColorIds(colorIds: number[]): void - { - if(!colorIds || !this._palettes) return; - - this._paletteIndexes = new Array(colorIds.length); - - let i = 0; - - while(i < this._palettes.length) - { - const palette = this.getPalette(i); - - if(palette) - { - let colorId = 0; - - if(colorIds.length > i) - { - colorId = colorIds[i]; - } - else - { - const colorItem = palette[0]; - - if(colorItem && colorItem.partColor) colorId = colorItem.partColor.id; - } - - let j = 0; - - while(j < palette.length) - { - const colorItem = palette[j]; - - if(colorItem.partColor.id === colorId) - { - this._paletteIndexes[i] = j; - - colorItem.isSelected = true; - } - else - { - colorItem.isSelected = false; - } - - j++; - } - } - - i++; - } - - this.updatePartColors(); - } - - public selectPartIndex(partIndex: number): AvatarEditorGridPartItem - { - if(!this._parts) return null; - - if((this._selectedPartIndex >= 0) && (this._parts.length > this._selectedPartIndex)) - { - const partItem = this._parts[this._selectedPartIndex]; - - if(partItem) partItem.isSelected = false; - } - - if(this._parts.length > partIndex) - { - const partItem = this._parts[partIndex]; - - if(partItem) - { - partItem.isSelected = true; - - this._selectedPartIndex = partIndex; - - return partItem; - } - } - - return null; - } - - public selectColorIndex(colorIndex: number, paletteId: number): AvatarEditorGridColorItem - { - const palette = this.getPalette(paletteId); - - if(!palette) return null; - - if(palette.length <= colorIndex) return null; - - this.deselectColorIndex(this._paletteIndexes[paletteId], paletteId); - - this._paletteIndexes[paletteId] = colorIndex; - - const colorItem = palette[colorIndex]; - - if(!colorItem) return null; - - colorItem.isSelected = true; - - this.updatePartColors(); - - return colorItem; - } - - public getCurrentColorIndex(k: number): number - { - return this._paletteIndexes[k]; - } - - private deselectColorIndex(colorIndex: number, paletteIndex: number): void - { - const palette = this.getPalette(paletteIndex); - - if(!palette) return; - - if(palette.length <= colorIndex) return; - - const colorItem = palette[colorIndex]; - - if(!colorItem) return; - - colorItem.isSelected = false; - } - - public getSelectedColorIds(): number[] - { - if(!this._paletteIndexes || !this._paletteIndexes.length) return null; - - if(!this._palettes || !this._palettes.length) return null; - - const palette = this._palettes[0]; - - if(!palette || (!palette.length)) return null; - - const colorItem = palette[0]; - - if(!colorItem || !colorItem.partColor) return null; - - const colorId = colorItem.partColor.id; - const colorIds: number[] = []; - - let i = 0; - - while(i < this._paletteIndexes.length) - { - const paletteSet = this._palettes[i]; - - if(!((!(paletteSet)) || (paletteSet.length <= i))) - { - if(paletteSet.length > this._paletteIndexes[i]) - { - const color = paletteSet[this._paletteIndexes[i]]; - - if(color && color.partColor) - { - colorIds.push(color.partColor.id); - } - else - { - colorIds.push(colorId); - } - } - else - { - colorIds.push(colorId); - } - } - - i++; - } - - const partItem = this.getCurrentPart(); - - if(!partItem) return null; - - return colorIds.slice(0, Math.max(partItem.maxColorIndex, 1)); - } - - private getSelectedColors(): IPartColor[] - { - const partColors: IPartColor[] = []; - - let i = 0; - - while(i < this._paletteIndexes.length) - { - const colorItem = this.getSelectedColor(i); - - if(colorItem) - { - partColors.push(colorItem.partColor); - } - else - { - partColors.push(null); - } - - i++; - } - - return partColors; - } - - public getSelectedColor(paletteId: number): AvatarEditorGridColorItem - { - const palette = this.getPalette(paletteId); - - if(!palette || (palette.length <= this._paletteIndexes[paletteId])) return null; - - return palette[this._paletteIndexes[paletteId]]; - } - - public getSelectedColorId(paletteId: number): number - { - const colorItem = this.getSelectedColor(paletteId); - - if(colorItem && (colorItem.partColor)) return colorItem.partColor.id; - - return 0; - } - - public getPalette(paletteId: number): AvatarEditorGridColorItem[] - { - if(!this._paletteIndexes || !this._palettes || (this._palettes.length <= paletteId)) - { - return null; - } - - return this._palettes[paletteId]; - } - - public getCurrentPart(): AvatarEditorGridPartItem - { - return this._parts[this._selectedPartIndex] as AvatarEditorGridPartItem; - } - - private updatePartColors(): void - { - const partColors = this.getSelectedColors(); - - for(const partItem of this._parts) - { - if(partItem) partItem.partColors = partColors; - } - } - - public hasClubSelectionsOverLevel(level: number): boolean - { - let hasInvalidSelections = false; - - const partColors = this.getSelectedColors(); - - if(partColors) - { - let i = 0; - - while(i < partColors.length) - { - const partColor = partColors[i]; - - if(partColor && (partColor.clubLevel > level)) hasInvalidSelections = true; - - i++; - } - } - - const partItem = this.getCurrentPart(); - - if(partItem && partItem.partSet) - { - const partSet = partItem.partSet; - - if(partSet && (partSet.clubLevel > level)) hasInvalidSelections = true; - } - - return hasInvalidSelections; - } - - public hasInvalidSelectedItems(ownedItems: number[]): boolean - { - const part = this.getCurrentPart(); - - if(!part) return false; - - const partSet = part.partSet; - - if(!partSet || !partSet.isSellable) return; - - return (ownedItems.indexOf(partSet.id) > -1); - } - - public stripClubItemsOverLevel(level: number): boolean - { - const partItem = this.getCurrentPart(); - - if(partItem && partItem.partSet) - { - const partSet = partItem.partSet; - - if(partSet.clubLevel > level) - { - const newPartItem = this.selectPartIndex(0); - - if(newPartItem && !newPartItem.partSet) this.selectPartIndex(1); - - return true; - } - } - - return false; - } - - public stripClubColorsOverLevel(level: number): boolean - { - const colorIds: number[] = []; - const partColors = this.getSelectedColors(); - const colorItems = this.getPalette(0); - - let didStrip = false; - - const colorId = CategoryData.defaultColorId(colorItems, level); - - if(colorId === -1) return false; - - let i = 0; - - while(i < partColors.length) - { - const partColor = partColors[i]; - - if(!partColor) - { - colorIds.push(colorId); - - didStrip = true; - } - else - { - if(partColor.clubLevel > level) - { - colorIds.push(colorId); - - didStrip = true; - } - else - { - colorIds.push(partColor.id); - } - } - - i++; - } - - if(didStrip) this.selectColorIds(colorIds); - - return didStrip; - } - - // public stripInvalidSellableItems(k:IHabboInventory): boolean - // { - // var _local_3:IFigurePartSet; - // var _local_4:AvatarEditorGridPartItem; - // var _local_2:AvatarEditorGridPartItem = this._Str_6315(); - // if (((_local_2) && (_local_2.partSet))) - // { - // _local_3 = _local_2.partSet; - // if (((_local_3.isSellable) && (!(k._Str_14439(_local_3.id))))) - // { - // _local_4 = this._Str_8066(0); - // if (((!(_local_4 == null)) && (_local_4.partSet == null))) - // { - // this._Str_8066(1); - // } - // return true; - // } - // } - // return false; - // } - - public get name(): string - { - return this._name; - } - - public get parts(): AvatarEditorGridPartItem[] - { - return this._parts; - } - - public get selectedPartIndex(): number - { - return this._selectedPartIndex; - } -} diff --git a/src/api/avatar/FigureData.ts b/src/api/avatar/FigureData.ts deleted file mode 100644 index 78014d1..0000000 --- a/src/api/avatar/FigureData.ts +++ /dev/null @@ -1,287 +0,0 @@ -import { AvatarEditorUtilities } from './AvatarEditorUtilities'; - -export class FigureData -{ - private static DEFAULT_DIRECTION: number = 4; - - public static MALE: string = 'M'; - public static FEMALE: string = 'F'; - public static UNISEX: string = 'U'; - public static SCALE: string = 'h'; - public static STD: string = 'std'; - public static DEFAULT_FRAME: string = '0'; - public static FACE: string = 'hd'; - public static HAIR: string = 'hr'; - public static HAT: string = 'ha'; - public static HEAD_ACCESSORIES: string = 'he'; - public static EYE_ACCESSORIES: string = 'ea'; - public static FACE_ACCESSORIES: string = 'fa'; - public static JACKET: string = 'cc'; - public static SHIRT: string = 'ch'; - public static CHEST_ACCESSORIES: string = 'ca'; - public static CHEST_PRINTS: string = 'cp'; - public static TROUSERS: string = 'lg'; - public static SHOES: string = 'sh'; - public static TROUSER_ACCESSORIES: string = 'wa'; - public static SET_TYPES = [ FigureData.FACE, FigureData.HAIR, FigureData.HAT, FigureData.HEAD_ACCESSORIES, FigureData.EYE_ACCESSORIES, FigureData.FACE_ACCESSORIES, FigureData.JACKET, FigureData.SHIRT, FigureData.CHEST_ACCESSORIES, FigureData.CHEST_PRINTS, FigureData.TROUSERS, FigureData.SHOES, FigureData.TROUSERS ]; - - private _data: Map; - private _colors: Map; - private _gender: string = 'M'; - private _direction: number = FigureData.DEFAULT_DIRECTION; - private _avatarEffectType: number = -1; - private _notifier: () => void = null; - - public loadAvatarData(figureString: string, gender: string): void - { - this._data = new Map(); - this._colors = new Map(); - this._gender = gender; - - this.parseFigureString(figureString); - this.updateView(); - } - - 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(setType: string): number - { - const existing = this._data.get(setType); - - if(existing !== undefined) return existing; - - return -1; - } - - public getColorIds(setType: string): number[] - { - const existing = this._colors.get(setType); - - if(existing !== undefined) return existing; - - return [ AvatarEditorUtilities.avatarSetFirstSelectableColor(setType) ]; - } - - 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(setType: string, partId: number, colorIds: number[], update: boolean = false): void - { - this.savePartSetId(setType, partId, update); - this.savePartSetColourId(setType, colorIds, update); - } - - private savePartSetId(setType: string, partId: number, update: boolean = true): void - { - switch(setType) - { - case FigureData.FACE: - case FigureData.HAIR: - case FigureData.HAT: - case FigureData.HEAD_ACCESSORIES: - case FigureData.EYE_ACCESSORIES: - case FigureData.FACE_ACCESSORIES: - case FigureData.SHIRT: - case FigureData.JACKET: - case FigureData.CHEST_ACCESSORIES: - case FigureData.CHEST_PRINTS: - case FigureData.TROUSERS: - case FigureData.SHOES: - case FigureData.TROUSER_ACCESSORIES: - if(partId >= 0) - { - this._data.set(setType, partId); - } - else - { - this._data.delete(setType); - } - break; - } - - if(update) this.updateView(); - } - - public savePartSetColourId(setType: string, colorIds: number[], update: boolean = true): void - { - switch(setType) - { - case FigureData.FACE: - case FigureData.HAIR: - case FigureData.HAT: - case FigureData.HEAD_ACCESSORIES: - case FigureData.EYE_ACCESSORIES: - case FigureData.FACE_ACCESSORIES: - case FigureData.SHIRT: - case FigureData.JACKET: - case FigureData.CHEST_ACCESSORIES: - case FigureData.CHEST_PRINTS: - case FigureData.TROUSERS: - case FigureData.SHOES: - case FigureData.TROUSER_ACCESSORIES: - this._colors.set(setType, colorIds); - break; - } - - if(update) 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) 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 - { - if(this.notify) this.notify(); - } - - public get gender(): string - { - return this._gender; - } - - public get direction(): number - { - return this._direction; - } - - public set direction(direction: number) - { - this._direction = direction; - - this.updateView(); - } - - public set avatarEffectType(k: number) - { - this._avatarEffectType = k; - } - - public get avatarEffectType(): number - { - return this._avatarEffectType; - } - - public get notify(): () => void - { - return this._notifier; - } - - public set notify(notifier: () => void) - { - this._notifier = notifier; - } -} diff --git a/src/api/avatar/FigureGenerator.ts b/src/api/avatar/FigureGenerator.ts deleted file mode 100644 index 6fc0093..0000000 --- a/src/api/avatar/FigureGenerator.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { AvatarFigureContainer, GetAvatarRenderManager, IFigurePartSet, IPalette, IPartColor, SetType } from '@nitrots/nitro-renderer'; -import { Randomizer } from '../utils'; -import { FigureData } from './FigureData'; - -function getTotalColors(partSet: IFigurePartSet): number -{ - const parts = partSet.parts; - - let totalColors = 0; - - for(const part of parts) totalColors = Math.max(totalColors, part.colorLayerIndex); - - return totalColors; -} - -function getRandomSetTypes(requiredSets: string[], options: string[]): string[] -{ - options = options.filter(option => (requiredSets.indexOf(option) === -1)); - - return [ ...requiredSets, ...Randomizer.getRandomElements(options, (Randomizer.getRandomNumber(options.length) + 1)) ]; -} - -function getRandomPartSet(setType: SetType, gender: string, clubLevel: number = 0, figureSetIds: number[] = []): IFigurePartSet -{ - if(!setType) return null; - - const options = setType.partSets.getValues().filter(option => - { - if(!option.isSelectable || ((option.gender !== 'U') && (option.gender !== gender)) || (option.clubLevel > clubLevel) || (option.isSellable && (figureSetIds.indexOf(option.id) === -1))) return null; - - return option; - }); - - if(!options || !options.length) return null; - - return Randomizer.getRandomElement(options); -} - -function getRandomColors(palette: IPalette, partSet: IFigurePartSet, clubLevel: number = 0): IPartColor[] -{ - if(!palette) return []; - - const options = palette.colors.getValues().filter(option => - { - if(!option.isSelectable || (option.clubLevel > clubLevel)) return null; - - return option; - }); - - if(!options || !options.length) return null; - - return Randomizer.getRandomElements(options, getTotalColors(partSet)); -} - -export function generateRandomFigure(figureData: FigureData, gender: string, clubLevel: number = 0, figureSetIds: number[] = [], ignoredSets: string[] = []): string -{ - const structure = GetAvatarRenderManager().structure; - const figureContainer = new AvatarFigureContainer(''); - const requiredSets = getRandomSetTypes(structure.getMandatorySetTypeIds(gender, clubLevel), FigureData.SET_TYPES); - - for(const setType of ignoredSets) - { - const partSetId = figureData.getPartSetId(setType); - const colors = figureData.getColorIds(setType); - - figureContainer.updatePart(setType, partSetId, colors); - } - - for(const type of requiredSets) - { - if(figureContainer.hasPartType(type)) continue; - - const setType = (structure.figureData.getSetType(type) as SetType); - const selectedSet = getRandomPartSet(setType, gender, clubLevel, figureSetIds); - - if(!selectedSet) continue; - - let selectedColors: number[] = []; - - if(selectedSet.isColorable) - { - selectedColors = getRandomColors(structure.figureData.getPalette(setType.paletteID), selectedSet, clubLevel).map(color => color.id); - } - - figureContainer.updatePart(setType.type, selectedSet.id, selectedColors); - } - - return figureContainer.getFigureString(); -} diff --git a/src/api/avatar/HeadModel.ts b/src/api/avatar/HeadModel.ts deleted file mode 100644 index 5dc30cd..0000000 --- a/src/api/avatar/HeadModel.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { AvatarEditorFigureCategory } from '@nitrots/nitro-renderer'; -import { CategoryBaseModel } from './CategoryBaseModel'; -import { FigureData } from './FigureData'; - -export class HeadModel extends CategoryBaseModel -{ - public init(): void - { - super.init(); - - this.addCategory(FigureData.HAIR); - this.addCategory(FigureData.HAT); - this.addCategory(FigureData.HEAD_ACCESSORIES); - this.addCategory(FigureData.EYE_ACCESSORIES); - this.addCategory(FigureData.FACE_ACCESSORIES); - - this._isInitalized = true; - } - - public get name(): string - { - return AvatarEditorFigureCategory.HEAD; - } -} diff --git a/src/api/avatar/IAvatarEditorCategory.ts b/src/api/avatar/IAvatarEditorCategory.ts deleted file mode 100644 index a7cfd51..0000000 --- a/src/api/avatar/IAvatarEditorCategory.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { IPartColor } from '@nitrots/nitro-renderer'; -import { IAvatarEditorCategoryPartItem } from './IAvatarEditorCategoryPartItem'; - -export interface IAvatarEditorCategory -{ - setType: string; - partItems: IAvatarEditorCategoryPartItem[]; - colorItems: IPartColor[][]; -} diff --git a/src/api/avatar/IAvatarEditorCategoryModel.ts b/src/api/avatar/IAvatarEditorCategoryModel.ts deleted file mode 100644 index dc9affa..0000000 --- a/src/api/avatar/IAvatarEditorCategoryModel.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { CategoryData } from './CategoryData'; - -export interface IAvatarEditorCategoryModel -{ - init(): void; - dispose(): void; - reset(): void; - getCategoryData(category: string): CategoryData; - selectPart(category: string, partIndex: number): void; - selectColor(category: string, colorIndex: number, paletteId: number): void; - hasClubSelectionsOverLevel(level: number): boolean; - hasInvalidSelectedItems(ownedItems: number[]): boolean; - stripClubItemsOverLevel(level: number): boolean; - stripInvalidSellableItems(): boolean; - categories: Map; - canSetGender: boolean; - maxPaletteCount: number; - name: string; -} diff --git a/src/api/avatar/IAvatarEditorCategoryPartItem.ts b/src/api/avatar/IAvatarEditorCategoryPartItem.ts deleted file mode 100644 index d1cbc0d..0000000 --- a/src/api/avatar/IAvatarEditorCategoryPartItem.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { IFigurePartSet } from '@nitrots/nitro-renderer'; - -export interface IAvatarEditorCategoryPartItem -{ - id?: number; - partSet?: IFigurePartSet; - usesColor?: boolean; - maxPaletteCount?: number; - isClear?: boolean; -} diff --git a/src/api/avatar/LegModel.ts b/src/api/avatar/LegModel.ts deleted file mode 100644 index 5633930..0000000 --- a/src/api/avatar/LegModel.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AvatarEditorFigureCategory } from '@nitrots/nitro-renderer'; -import { CategoryBaseModel } from './CategoryBaseModel'; -import { FigureData } from './FigureData'; - -export class LegModel extends CategoryBaseModel -{ - public init(): void - { - super.init(); - - this.addCategory(FigureData.TROUSERS); - this.addCategory(FigureData.SHOES); - this.addCategory(FigureData.TROUSER_ACCESSORIES); - - this._isInitalized = true; - } - - public get name(): string - { - return AvatarEditorFigureCategory.LEGS; - } -} diff --git a/src/api/avatar/TorsoModel.ts b/src/api/avatar/TorsoModel.ts deleted file mode 100644 index 43e48cf..0000000 --- a/src/api/avatar/TorsoModel.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { AvatarEditorFigureCategory } from '@nitrots/nitro-renderer'; -import { CategoryBaseModel } from './CategoryBaseModel'; -import { FigureData } from './FigureData'; - -export class TorsoModel extends CategoryBaseModel -{ - public init(): void - { - super.init(); - - this.addCategory(FigureData.SHIRT); - this.addCategory(FigureData.CHEST_PRINTS); - this.addCategory(FigureData.JACKET); - this.addCategory(FigureData.CHEST_ACCESSORIES); - - this._isInitalized = true; - } - - public get name(): string - { - return AvatarEditorFigureCategory.TORSO; - } -} diff --git a/src/api/avatar/index.ts b/src/api/avatar/index.ts deleted file mode 100644 index acf945b..0000000 --- a/src/api/avatar/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -export * from './AvatarEditorAction'; -export * from './AvatarEditorGridColorItem'; -export * from './AvatarEditorGridPartItem'; -export * from './AvatarEditorThumbnailsHelper'; -export * from './AvatarEditorUtilities'; -export * from './BodyModel'; -export * from './CategoryBaseModel'; -export * from './CategoryData'; -export * from './FigureData'; -export * from './FigureGenerator'; -export * from './HeadModel'; -export * from './IAvatarEditorCategory'; -export * from './IAvatarEditorCategoryModel'; -export * from './IAvatarEditorCategoryPartItem'; -export * from './LegModel'; -export * from './TorsoModel'; diff --git a/src/api/camera/CameraEditorTabs.ts b/src/api/camera/CameraEditorTabs.ts deleted file mode 100644 index 6e894e7..0000000 --- a/src/api/camera/CameraEditorTabs.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class CameraEditorTabs -{ - public static readonly COLORMATRIX: string = 'colormatrix'; - public static readonly COMPOSITE: string = 'composite'; -} diff --git a/src/api/camera/CameraPicture.ts b/src/api/camera/CameraPicture.ts deleted file mode 100644 index fe8c221..0000000 --- a/src/api/camera/CameraPicture.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { NitroTexture } from '@nitrots/nitro-renderer'; - -export class CameraPicture -{ - constructor( - public texture: NitroTexture, - public imageUrl: string) - {} -} diff --git a/src/api/camera/CameraPictureThumbnail.ts b/src/api/camera/CameraPictureThumbnail.ts deleted file mode 100644 index cd12660..0000000 --- a/src/api/camera/CameraPictureThumbnail.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class CameraPictureThumbnail -{ - constructor( - public effectName: string, - public thumbnailUrl: string) - {} -} diff --git a/src/api/camera/index.ts b/src/api/camera/index.ts deleted file mode 100644 index 93c6ccb..0000000 --- a/src/api/camera/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './CameraEditorTabs'; -export * from './CameraPicture'; -export * from './CameraPictureThumbnail'; diff --git a/src/api/campaign/CalendarItem.ts b/src/api/campaign/CalendarItem.ts deleted file mode 100644 index d3634b3..0000000 --- a/src/api/campaign/CalendarItem.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ICalendarItem } from './ICalendarItem'; - -export class CalendarItem implements ICalendarItem -{ - private _productName: string; - private _customImage: string; - private _furnitureClassName: string; - - constructor(productName: string, customImage: string, furnitureClassName: string) - { - this._productName = productName; - this._customImage = customImage; - this._furnitureClassName = furnitureClassName; - } - - public get productName(): string - { - return this._productName; - } - - public get customImage(): string - { - return this._customImage; - } - - public get furnitureClassName(): string - { - return this._furnitureClassName; - } -} diff --git a/src/api/campaign/CalendarItemState.ts b/src/api/campaign/CalendarItemState.ts deleted file mode 100644 index 1b91ca3..0000000 --- a/src/api/campaign/CalendarItemState.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class CalendarItemState -{ - public static readonly STATE_UNLOCKED = 1; - public static readonly STATE_LOCKED_AVAILABLE = 2; - public static readonly STATE_LOCKED_EXPIRED = 3; - public static readonly STATE_LOCKED_FUTURE = 4; -} diff --git a/src/api/campaign/ICalendarItem.ts b/src/api/campaign/ICalendarItem.ts deleted file mode 100644 index 87dfbd6..0000000 --- a/src/api/campaign/ICalendarItem.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface ICalendarItem -{ - readonly productName: string; - readonly customImage: string; - readonly furnitureClassName: string; -} diff --git a/src/api/campaign/index.ts b/src/api/campaign/index.ts deleted file mode 100644 index a86e40c..0000000 --- a/src/api/campaign/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './CalendarItem'; -export * from './CalendarItemState'; -export * from './ICalendarItem'; diff --git a/src/api/catalog/BuilderFurniPlaceableStatus.ts b/src/api/catalog/BuilderFurniPlaceableStatus.ts deleted file mode 100644 index 40eb6f6..0000000 --- a/src/api/catalog/BuilderFurniPlaceableStatus.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class BuilderFurniPlaceableStatus -{ - public static OKAY: number = 0; - public static MISSING_OFFER: number = 1; - public static FURNI_LIMIT_REACHED: number = 2; - public static NOT_IN_ROOM: number = 3; - public static NOT_ROOM_OWNER: number = 4; - public static GUILD_ROOM: number = 5; - public static VISITORS_IN_ROOM: number = 6; -} diff --git a/src/api/catalog/CatalogNode.ts b/src/api/catalog/CatalogNode.ts deleted file mode 100644 index 893aa32..0000000 --- a/src/api/catalog/CatalogNode.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { NodeData } from '@nitrots/nitro-renderer'; -import { ICatalogNode } from './ICatalogNode'; - -export class CatalogNode implements ICatalogNode -{ - private _depth: number = 0; - private _localization: string = ''; - private _pageId: number = -1; - private _pageName: string = ''; - private _iconId: number = 0; - private _children: ICatalogNode[]; - private _offerIds: number[]; - private _parent: ICatalogNode; - private _isVisible: boolean; - private _isActive: boolean; - private _isOpen: boolean; - - constructor(node: NodeData, depth: number, parent: ICatalogNode) - { - this._depth = depth; - this._parent = parent; - this._localization = node.localization; - this._pageId = node.pageId; - this._pageName = node.pageName; - this._iconId = node.icon; - this._children = []; - this._offerIds = node.offerIds; - this._isVisible = node.visible; - this._isActive = false; - this._isOpen = false; - } - - public activate(): void - { - this._isActive = true; - } - - public deactivate(): void - { - this._isActive = false; - } - - public open(): void - { - this._isOpen = true; - } - - public close(): void - { - this._isOpen = false; - } - - public addChild(child: ICatalogNode):void - { - if(!child) return; - - this._children.push(child); - } - - public get depth(): number - { - return this._depth; - } - - public get isBranch(): boolean - { - return (this._children.length > 0); - } - - public get isLeaf(): boolean - { - return (this._children.length === 0); - } - - public get localization(): string - { - return this._localization; - } - - public get pageId(): number - { - return this._pageId; - } - - public get pageName(): string - { - return this._pageName; - } - - public get iconId(): number - { - return this._iconId; - } - - public get children(): ICatalogNode[] - { - return this._children; - } - - public get offerIds(): number[] - { - return this._offerIds; - } - - public get parent(): ICatalogNode - { - return this._parent; - } - - public get isVisible(): boolean - { - return this._isVisible; - } - - public get isActive(): boolean - { - return this._isActive; - } - - public get isOpen(): boolean - { - return this._isOpen; - } -} diff --git a/src/api/catalog/CatalogPage.ts b/src/api/catalog/CatalogPage.ts deleted file mode 100644 index 1e80609..0000000 --- a/src/api/catalog/CatalogPage.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { ICatalogPage } from './ICatalogPage'; -import { IPageLocalization } from './IPageLocalization'; -import { IPurchasableOffer } from './IPurchasableOffer'; - -export class CatalogPage implements ICatalogPage -{ - public static MODE_NORMAL: number = 0; - - private _pageId: number; - private _layoutCode: string; - private _localization: IPageLocalization; - private _offers: IPurchasableOffer[]; - private _acceptSeasonCurrencyAsCredits: boolean; - private _mode: number; - - constructor(pageId: number, layoutCode: string, localization: IPageLocalization, offers: IPurchasableOffer[], acceptSeasonCurrencyAsCredits: boolean, mode: number = -1) - { - this._pageId = pageId; - this._layoutCode = layoutCode; - this._localization = localization; - this._offers = offers; - this._acceptSeasonCurrencyAsCredits = acceptSeasonCurrencyAsCredits; - - for(const offer of offers) (offer.page = this); - - if(mode === -1) this._mode = CatalogPage.MODE_NORMAL; - else this._mode = mode; - } - - public get pageId(): number - { - return this._pageId; - } - - public get layoutCode(): string - { - return this._layoutCode; - } - - public get localization(): IPageLocalization - { - return this._localization; - } - - public get offers(): IPurchasableOffer[] - { - return this._offers; - } - - public get acceptSeasonCurrencyAsCredits(): boolean - { - return this._acceptSeasonCurrencyAsCredits; - } - - public get mode(): number - { - return this._mode; - } -} diff --git a/src/api/catalog/CatalogPageName.ts b/src/api/catalog/CatalogPageName.ts deleted file mode 100644 index 8e4c7b6..0000000 --- a/src/api/catalog/CatalogPageName.ts +++ /dev/null @@ -1,26 +0,0 @@ -export class CatalogPageName -{ - public static DUCKET_INFO: string = 'ducket_info'; - public static CREDITS: string = 'credits'; - public static AVATAR_EFFECTS: string = 'avatar_effects'; - public static HC_MEMBERSHIP: string = 'hc_membership'; - public static CLUB_GIFTS: string = 'club_gifts'; - public static LIMITED_SOLD: string = 'limited_sold'; - public static PET_ACCESSORIES: string = 'pet_accessories'; - public static TRAX_SONGS: string = 'trax_songs'; - public static NEW_ADDITIONS: string = 'new_additions'; - public static QUEST_SHELL: string = 'quest_shell'; - public static QUEST_SNOWFLAKES: string = 'quest_snowflakes'; - public static VAL_QUESTS: string = 'val_quests'; - public static GUILD_CUSTOM_FURNI: string = 'guild_custom_furni'; - public static GIFT_SHOP: string = 'gift_shop'; - public static HORSE_STYLES: string = 'horse_styles'; - public static HORSE_SHOE: string = 'horse_shoe'; - public static SET_EASTER: string = 'set_easter'; - public static ECOTRON_TRANSFORM: string = 'ecotron_transform'; - public static LOYALTY_INFO: string = 'loyalty_info'; - public static ROOM_BUNDLES: string = 'room_bundles'; - public static ROOM_BUNDLES_MOBILE: string = 'room_bundles_mobile'; - public static HABBO_CLUB_DESKTOP: string = 'habbo_club_desktop'; - public static MOBILE_SUBSCRIPTIONS: string = 'mobile_subscriptions'; -} diff --git a/src/api/catalog/CatalogPetPalette.ts b/src/api/catalog/CatalogPetPalette.ts deleted file mode 100644 index d92c40d..0000000 --- a/src/api/catalog/CatalogPetPalette.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { SellablePetPaletteData } from '@nitrots/nitro-renderer'; - -export class CatalogPetPalette -{ - constructor( - public readonly breed: string, - public readonly palettes: SellablePetPaletteData[] - ) - {} -} diff --git a/src/api/catalog/CatalogPurchaseState.ts b/src/api/catalog/CatalogPurchaseState.ts deleted file mode 100644 index b442f62..0000000 --- a/src/api/catalog/CatalogPurchaseState.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class CatalogPurchaseState -{ - public static NONE = 0; - public static CONFIRM = 1; - public static PURCHASE = 2; - public static NO_CREDITS = 3; - public static NO_POINTS = 4; - public static SOLD_OUT = 5; - public static FAILED = 6; -} diff --git a/src/api/catalog/CatalogType.ts b/src/api/catalog/CatalogType.ts deleted file mode 100644 index 670ad6f..0000000 --- a/src/api/catalog/CatalogType.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class CatalogType -{ - public static NORMAL: string = 'NORMAL'; - public static BUILDER: string = 'BUILDERS_CLUB'; -} diff --git a/src/api/catalog/CatalogUtilities.ts b/src/api/catalog/CatalogUtilities.ts deleted file mode 100644 index 7aff6a8..0000000 --- a/src/api/catalog/CatalogUtilities.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { GetRoomEngine, SellablePetPaletteData } from '@nitrots/nitro-renderer'; -import { ICatalogNode } from './ICatalogNode'; - -export const GetPixelEffectIcon = (id: number) => -{ - return ''; -} - -export const GetSubscriptionProductIcon = (id: number) => -{ - return ''; -} - -export const GetOfferNodes = (offerNodes: Map, offerId: number) => -{ - const nodes = offerNodes.get(offerId); - const allowedNodes: ICatalogNode[] = []; - - if(nodes && nodes.length) - { - for(const node of nodes) - { - if(!node.isVisible) continue; - - allowedNodes.push(node); - } - } - - return allowedNodes; -} - -export const FilterCatalogNode = (search: string, furniLines: string[], node: ICatalogNode, nodes: ICatalogNode[]) => -{ - if(node.isVisible && (node.pageId > 0)) - { - let nodeAdded = false; - - const hayStack = [ node.pageName, node.localization ].join(' ').toLowerCase().replace(/ /gi, ''); - - if(hayStack.indexOf(search) > -1) - { - nodes.push(node); - - nodeAdded = true; - } - - if(!nodeAdded) - { - for(const furniLine of furniLines) - { - if(hayStack.indexOf(furniLine) >= 0) - { - nodes.push(node); - - break; - } - } - } - } - - for(const child of node.children) FilterCatalogNode(search, furniLines, child, nodes); -} - -export function GetPetIndexFromLocalization(localization: string) -{ - if(!localization.length) return 0; - - let index = (localization.length - 1); - - while(index >= 0) - { - if(isNaN(parseInt(localization.charAt(index)))) break; - - index--; - } - - if(index > 0) return parseInt(localization.substring(index + 1)); - - return -1; -} - -export function GetPetAvailableColors(petIndex: number, palettes: SellablePetPaletteData[]): number[][] -{ - switch(petIndex) - { - case 0: - return [ [ 16743226 ], [ 16750435 ], [ 16764339 ], [ 0xF59500 ], [ 16498012 ], [ 16704690 ], [ 0xEDD400 ], [ 16115545 ], [ 16513201 ], [ 8694111 ], [ 11585939 ], [ 14413767 ], [ 6664599 ], [ 9553845 ], [ 12971486 ], [ 8358322 ], [ 10002885 ], [ 13292268 ], [ 10780600 ], [ 12623573 ], [ 14403561 ], [ 12418717 ], [ 14327229 ], [ 15517403 ], [ 14515069 ], [ 15764368 ], [ 16366271 ], [ 0xABABAB ], [ 0xD4D4D4 ], [ 0xFFFFFF ], [ 14256481 ], [ 14656129 ], [ 15848130 ], [ 14005087 ], [ 14337152 ], [ 15918540 ], [ 15118118 ], [ 15531929 ], [ 9764857 ], [ 11258085 ] ]; - case 1: - return [ [ 16743226 ], [ 16750435 ], [ 16764339 ], [ 0xF59500 ], [ 16498012 ], [ 16704690 ], [ 0xEDD400 ], [ 16115545 ], [ 16513201 ], [ 8694111 ], [ 11585939 ], [ 14413767 ], [ 6664599 ], [ 9553845 ], [ 12971486 ], [ 8358322 ], [ 10002885 ], [ 13292268 ], [ 10780600 ], [ 12623573 ], [ 14403561 ], [ 12418717 ], [ 14327229 ], [ 15517403 ], [ 14515069 ], [ 15764368 ], [ 16366271 ], [ 0xABABAB ], [ 0xD4D4D4 ], [ 0xFFFFFF ], [ 14256481 ], [ 14656129 ], [ 15848130 ], [ 14005087 ], [ 14337152 ], [ 15918540 ], [ 15118118 ], [ 15531929 ], [ 9764857 ], [ 11258085 ] ]; - case 2: - return [ [ 16579283 ], [ 15378351 ], [ 8830016 ], [ 15257125 ], [ 9340985 ], [ 8949607 ], [ 6198292 ], [ 8703620 ], [ 9889626 ], [ 8972045 ], [ 12161285 ], [ 13162269 ], [ 8620113 ], [ 12616503 ], [ 8628101 ], [ 0xD2FF00 ], [ 9764857 ] ]; - case 3: - return [ [ 0xFFFFFF ], [ 0xEEEEEE ], [ 0xDDDDDD ] ]; - case 4: - return [ [ 0xFFFFFF ], [ 16053490 ], [ 15464440 ], [ 16248792 ], [ 15396319 ], [ 15007487 ] ]; - case 5: - return [ [ 0xFFFFFF ], [ 0xEEEEEE ], [ 0xDDDDDD ] ]; - case 6: - return [ [ 0xFFFFFF ], [ 0xEEEEEE ], [ 0xDDDDDD ], [ 16767177 ], [ 16770205 ], [ 16751331 ] ]; - case 7: - return [ [ 0xCCCCCC ], [ 0xAEAEAE ], [ 16751331 ], [ 10149119 ], [ 16763290 ], [ 16743786 ] ]; - default: { - const colors: number[][] = []; - - for(const palette of palettes) - { - const petColorResult = GetRoomEngine().getPetColorResult(petIndex, palette.paletteId); - - if(!petColorResult) continue; - - if(petColorResult.primaryColor === petColorResult.secondaryColor) - { - colors.push([ petColorResult.primaryColor ]); - } - else - { - colors.push([ petColorResult.primaryColor, petColorResult.secondaryColor ]); - } - } - - return colors; - } - } -} diff --git a/src/api/catalog/FurnitureOffer.ts b/src/api/catalog/FurnitureOffer.ts deleted file mode 100644 index 367f247..0000000 --- a/src/api/catalog/FurnitureOffer.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { GetProductOfferComposer, IFurnitureData } from '@nitrots/nitro-renderer'; -import { GetProductDataForLocalization, SendMessageComposer } from '../nitro'; -import { ICatalogPage } from './ICatalogPage'; -import { IProduct } from './IProduct'; -import { IPurchasableOffer } from './IPurchasableOffer'; -import { Offer } from './Offer'; -import { Product } from './Product'; - -export class FurnitureOffer implements IPurchasableOffer -{ - private _furniData:IFurnitureData; - private _page: ICatalogPage; - private _product: IProduct; - - constructor(furniData: IFurnitureData) - { - this._furniData = furniData; - this._product = (new Product(this._furniData.type, this._furniData.id, this._furniData.customParams, 1, GetProductDataForLocalization(this._furniData.className), this._furniData) as IProduct); - } - - public activate(): void - { - SendMessageComposer(new GetProductOfferComposer((this._furniData.rentOfferId > -1) ? this._furniData.rentOfferId : this._furniData.purchaseOfferId)); - } - - public get offerId(): number - { - return (this.isRentOffer) ? this._furniData.rentOfferId : this._furniData.purchaseOfferId; - } - - public get priceInActivityPoints(): number - { - return 0; - } - - public get activityPointType(): number - { - return 0; - } - - public get priceInCredits(): number - { - return 0; - } - - public get page(): ICatalogPage - { - return this._page; - } - - public set page(page: ICatalogPage) - { - this._page = page; - } - - public get priceType(): string - { - return ''; - } - - public get product(): IProduct - { - return this._product; - } - - public get products(): IProduct[] - { - return [ this._product ]; - } - - public get localizationId(): string - { - return 'roomItem.name.' + this._furniData.id; - } - - public get bundlePurchaseAllowed(): boolean - { - return false; - } - - public get isRentOffer(): boolean - { - return (this._furniData.rentOfferId > -1); - } - - public get giftable(): boolean - { - return false; - } - - public get pricingModel(): string - { - return Offer.PRICING_MODEL_FURNITURE; - } - - public get clubLevel(): number - { - return 0; - } - - public get badgeCode(): string - { - return ''; - } - - public get localizationName(): string - { - return this._furniData.name; - } - - public get localizationDescription(): string - { - return this._furniData.description; - } - - public get isLazy(): boolean - { - return true; - } -} diff --git a/src/api/catalog/GetImageIconUrlForProduct.ts b/src/api/catalog/GetImageIconUrlForProduct.ts deleted file mode 100644 index 8c363e7..0000000 --- a/src/api/catalog/GetImageIconUrlForProduct.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { GetRoomEngine } from '@nitrots/nitro-renderer'; -import { ProductTypeEnum } from './ProductTypeEnum'; - -export const GetImageIconUrlForProduct = (productType: string, productClassId: number, extraData: string = null) => -{ - let imageUrl: string = null; - - switch(productType.toLocaleLowerCase()) - { - case ProductTypeEnum.FLOOR: - imageUrl = GetRoomEngine().getFurnitureFloorIconUrl(productClassId); - break; - case ProductTypeEnum.WALL: - imageUrl = GetRoomEngine().getFurnitureWallIconUrl(productClassId, extraData); - break; - } - - return imageUrl; -} diff --git a/src/api/catalog/GiftWrappingConfiguration.ts b/src/api/catalog/GiftWrappingConfiguration.ts deleted file mode 100644 index 9d29b8c..0000000 --- a/src/api/catalog/GiftWrappingConfiguration.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { GiftWrappingConfigurationParser } from '@nitrots/nitro-renderer'; - -export class GiftWrappingConfiguration -{ - private _isEnabled: boolean = false; - private _price: number = null; - private _stuffTypes: number[] = null; - private _boxTypes: number[] = null; - private _ribbonTypes: number[] = null; - private _defaultStuffTypes: number[] = null; - - constructor(parser: GiftWrappingConfigurationParser) - { - this._isEnabled = parser.isEnabled; - this._price = parser.price; - this._boxTypes = parser.boxTypes; - this._ribbonTypes = parser.ribbonTypes; - this._stuffTypes = parser.giftWrappers; - this._defaultStuffTypes = parser.giftFurnis; - } - - public get isEnabled(): boolean - { - return this._isEnabled; - } - - public get price(): number - { - return this._price; - } - - public get stuffTypes(): number[] - { - return this._stuffTypes; - } - - public get boxTypes(): number[] - { - return this._boxTypes; - } - - public get ribbonTypes(): number[] - { - return this._ribbonTypes; - } - - public get defaultStuffTypes(): number[] - { - return this._defaultStuffTypes; - } -} diff --git a/src/api/catalog/ICatalogNode.ts b/src/api/catalog/ICatalogNode.ts deleted file mode 100644 index c69f5a6..0000000 --- a/src/api/catalog/ICatalogNode.ts +++ /dev/null @@ -1,21 +0,0 @@ -export interface ICatalogNode -{ - activate(): void; - deactivate(): void; - open(): void; - close(): void; - addChild(node: ICatalogNode): void; - readonly depth: number; - readonly isBranch: boolean; - readonly isLeaf: boolean; - readonly localization: string; - readonly pageId: number; - readonly pageName: string; - readonly iconId: number; - readonly children: ICatalogNode[]; - readonly offerIds: number[]; - readonly parent: ICatalogNode; - readonly isVisible: boolean; - readonly isActive: boolean; - readonly isOpen: boolean; -} diff --git a/src/api/catalog/ICatalogOptions.ts b/src/api/catalog/ICatalogOptions.ts deleted file mode 100644 index 2035694..0000000 --- a/src/api/catalog/ICatalogOptions.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ClubGiftInfoParser, ClubOfferData, HabboGroupEntryData, MarketplaceConfigurationMessageParser } from '@nitrots/nitro-renderer'; -import { CatalogPetPalette } from './CatalogPetPalette'; -import { GiftWrappingConfiguration } from './GiftWrappingConfiguration'; - -export interface ICatalogOptions -{ - groups?: HabboGroupEntryData[]; - petPalettes?: CatalogPetPalette[]; - clubOffers?: ClubOfferData[]; - clubGifts?: ClubGiftInfoParser; - giftConfiguration?: GiftWrappingConfiguration; - marketplaceConfiguration?: MarketplaceConfigurationMessageParser; -} diff --git a/src/api/catalog/ICatalogPage.ts b/src/api/catalog/ICatalogPage.ts deleted file mode 100644 index ed11ba0..0000000 --- a/src/api/catalog/ICatalogPage.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { IPageLocalization } from './IPageLocalization'; -import { IPurchasableOffer } from './IPurchasableOffer'; - -export interface ICatalogPage -{ - readonly pageId: number; - readonly layoutCode: string; - readonly localization: IPageLocalization; - readonly offers: IPurchasableOffer[]; - readonly acceptSeasonCurrencyAsCredits: boolean; - readonly mode: number; -} diff --git a/src/api/catalog/IMarketplaceSearchOptions.ts b/src/api/catalog/IMarketplaceSearchOptions.ts deleted file mode 100644 index 9489ef0..0000000 --- a/src/api/catalog/IMarketplaceSearchOptions.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface IMarketplaceSearchOptions -{ - query: string; - type: number; - minPrice: number; - maxPrice: number; -} diff --git a/src/api/catalog/IPageLocalization.ts b/src/api/catalog/IPageLocalization.ts deleted file mode 100644 index ad652e1..0000000 --- a/src/api/catalog/IPageLocalization.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface IPageLocalization -{ - getText(index: number): string - getImage(index: number): string -} diff --git a/src/api/catalog/IProduct.ts b/src/api/catalog/IProduct.ts deleted file mode 100644 index 4a1a392..0000000 --- a/src/api/catalog/IProduct.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { IFurnitureData, IProductData } from '@nitrots/nitro-renderer'; -import { IPurchasableOffer } from './IPurchasableOffer'; - -export interface IProduct -{ - getIconUrl(offer?: IPurchasableOffer): string; - productType: string; - productClassId: number; - extraParam: string; - productCount: number; - productData: IProductData; - furnitureData: IFurnitureData; - isUniqueLimitedItem: boolean; - uniqueLimitedItemSeriesSize: number; - uniqueLimitedItemsLeft: number; -} diff --git a/src/api/catalog/IPurchasableOffer.ts b/src/api/catalog/IPurchasableOffer.ts deleted file mode 100644 index b182865..0000000 --- a/src/api/catalog/IPurchasableOffer.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ICatalogPage } from './ICatalogPage'; -import { IProduct } from './IProduct'; - -export interface IPurchasableOffer -{ - activate(): void; - clubLevel: number; - page: ICatalogPage; - offerId: number; - localizationId: string; - priceInCredits: number; - priceInActivityPoints: number; - activityPointType: number; - giftable: boolean; - product: IProduct; - pricingModel: string; - priceType: string; - bundlePurchaseAllowed: boolean; - isRentOffer: boolean; - badgeCode: string; - localizationName: string; - localizationDescription: string; - isLazy: boolean; - products: IProduct[]; -} diff --git a/src/api/catalog/IPurchaseOptions.ts b/src/api/catalog/IPurchaseOptions.ts deleted file mode 100644 index c9fab89..0000000 --- a/src/api/catalog/IPurchaseOptions.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { IObjectData } from '@nitrots/nitro-renderer'; - -export interface IPurchaseOptions -{ - quantity?: number; - extraData?: string; - extraParamRequired?: boolean; - previewStuffData?: IObjectData; -} diff --git a/src/api/catalog/MarketplaceOfferState.ts b/src/api/catalog/MarketplaceOfferState.ts deleted file mode 100644 index 20c0e45..0000000 --- a/src/api/catalog/MarketplaceOfferState.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class MarketPlaceOfferState -{ - public static readonly ONGOING = 1; - public static readonly ONGOING_OWN = 1; - public static readonly SOLD = 2; - public static readonly EXPIRED = 3; -} diff --git a/src/api/catalog/MarketplaceSearchType.ts b/src/api/catalog/MarketplaceSearchType.ts deleted file mode 100644 index ac7a701..0000000 --- a/src/api/catalog/MarketplaceSearchType.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class MarketplaceSearchType -{ - public static readonly BY_ACTIVITY = 1; - public static readonly BY_VALUE = 2; - public static readonly ADVANCED = 3; -} diff --git a/src/api/catalog/Offer.ts b/src/api/catalog/Offer.ts deleted file mode 100644 index c14d6ac..0000000 --- a/src/api/catalog/Offer.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { GetFurnitureData, GetProductDataForLocalization, LocalizeText, ProductTypeEnum } from '..'; -import { ICatalogPage } from './ICatalogPage'; -import { IProduct } from './IProduct'; -import { IPurchasableOffer } from './IPurchasableOffer'; -import { Product } from './Product'; - -export class Offer implements IPurchasableOffer -{ - public static PRICING_MODEL_UNKNOWN: string = 'pricing_model_unknown'; - public static PRICING_MODEL_SINGLE: string = 'pricing_model_single'; - public static PRICING_MODEL_MULTI: string = 'pricing_model_multi'; - public static PRICING_MODEL_BUNDLE: string = 'pricing_model_bundle'; - public static PRICING_MODEL_FURNITURE: string = 'pricing_model_furniture'; - public static PRICE_TYPE_NONE: string = 'price_type_none'; - public static PRICE_TYPE_CREDITS: string = 'price_type_credits'; - public static PRICE_TYPE_ACTIVITYPOINTS: string = 'price_type_activitypoints'; - public static PRICE_TYPE_CREDITS_ACTIVITYPOINTS: string = 'price_type_credits_and_activitypoints'; - - private _pricingModel: string; - private _priceType: string; - private _offerId: number; - private _localizationId: string; - private _priceInCredits: number; - private _priceInActivityPoints: number; - private _activityPointType: number; - private _giftable: boolean; - private _isRentOffer: boolean; - private _page: ICatalogPage; - private _clubLevel: number = 0; - private _products: IProduct[]; - private _badgeCode: string; - private _bundlePurchaseAllowed: boolean = false; - - constructor(offerId: number, localizationId: string, isRentOffer: boolean, priceInCredits: number, priceInActivityPoints: number, activityPointType: number, giftable: boolean, clubLevel: number, products: IProduct[], bundlePurchaseAllowed: boolean) - { - this._offerId = offerId; - this._localizationId = localizationId; - this._isRentOffer = isRentOffer; - this._priceInCredits = priceInCredits; - this._priceInActivityPoints = priceInActivityPoints; - this._activityPointType = activityPointType; - this._giftable = giftable; - this._clubLevel = clubLevel; - this._products = products; - this._bundlePurchaseAllowed = bundlePurchaseAllowed; - - this.setPricingModelForProducts(); - this.setPricingType(); - - for(const product of products) - { - if(product.productType === ProductTypeEnum.BADGE) - { - this._badgeCode = product.extraParam; - - break; - } - } - } - - public activate(): void - { - - } - - public get clubLevel(): number - { - return this._clubLevel; - } - - public get page(): ICatalogPage - { - return this._page; - } - - public set page(k: ICatalogPage) - { - this._page = k; - } - - public get offerId(): number - { - return this._offerId; - } - - public get localizationId(): string - { - return this._localizationId; - } - - public get priceInCredits(): number - { - return this._priceInCredits; - } - - public get priceInActivityPoints(): number - { - return this._priceInActivityPoints; - } - - public get activityPointType(): number - { - return this._activityPointType; - } - - public get giftable(): boolean - { - return this._giftable; - } - - public get product(): IProduct - { - if(!this._products || !this._products.length) return null; - - if(this._products.length === 1) return this._products[0]; - - const products = Product.stripAddonProducts(this._products); - - if(products.length) return products[0]; - - return null; - } - - public get pricingModel(): string - { - return this._pricingModel; - } - - public get priceType(): string - { - return this._priceType; - } - - public get bundlePurchaseAllowed(): boolean - { - return this._bundlePurchaseAllowed; - } - - public get isRentOffer(): boolean - { - return this._isRentOffer; - } - - public get badgeCode(): string - { - return this._badgeCode; - } - - public get localizationName(): string - { - const productData = GetProductDataForLocalization(this._localizationId); - - if(productData) return productData.name; - - return LocalizeText(this._localizationId); - } - - public get localizationDescription(): string - { - const productData = GetProductDataForLocalization(this._localizationId); - - if(productData) return productData.description; - - return LocalizeText(this._localizationId); - } - - public get isLazy(): boolean - { - return false; - } - - public get products(): IProduct[] - { - return this._products; - } - - private setPricingModelForProducts(): void - { - const products = Product.stripAddonProducts(this._products); - - if(products.length === 1) - { - if(products[0].productCount === 1) - { - this._pricingModel = Offer.PRICING_MODEL_SINGLE; - } - else - { - this._pricingModel = Offer.PRICING_MODEL_MULTI; - } - } - - else if(products.length > 1) - { - this._pricingModel = Offer.PRICING_MODEL_BUNDLE; - } - - else - { - this._pricingModel = Offer.PRICING_MODEL_UNKNOWN; - } - } - - private setPricingType(): void - { - if((this._priceInCredits > 0) && (this._priceInActivityPoints > 0)) - { - this._priceType = Offer.PRICE_TYPE_CREDITS_ACTIVITYPOINTS; - } - - else if(this._priceInCredits > 0) - { - this._priceType = Offer.PRICE_TYPE_CREDITS; - } - - else if(this._priceInActivityPoints > 0) - { - this._priceType = Offer.PRICE_TYPE_ACTIVITYPOINTS; - } - - else - { - this._priceType = Offer.PRICE_TYPE_NONE; - } - } - - public clone(): IPurchasableOffer - { - const products: IProduct[] = []; - const productData = GetProductDataForLocalization(this.localizationId); - - for(const product of this._products) - { - const furnitureData = GetFurnitureData(product.productClassId, product.productType); - - products.push(new Product(product.productType, product.productClassId, product.extraParam, product.productCount, productData, furnitureData)); - } - - const offer = new Offer(this.offerId, this.localizationId, this.isRentOffer, this.priceInCredits, this.priceInActivityPoints, this.activityPointType, this.giftable, this.clubLevel, products, this.bundlePurchaseAllowed); - - offer.page = this.page; - - return offer; - } -} diff --git a/src/api/catalog/PageLocalization.ts b/src/api/catalog/PageLocalization.ts deleted file mode 100644 index d433923..0000000 --- a/src/api/catalog/PageLocalization.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { GetConfigurationValue } from '../nitro'; -import { IPageLocalization } from './IPageLocalization'; - -export class PageLocalization implements IPageLocalization -{ - private _images: string[]; - private _texts: string[] - - constructor(images: string[], texts: string[]) - { - this._images = images; - this._texts = texts; - } - - public getText(index: number): string - { - let message = (this._texts[index] || ''); - - if(message && message.length) message = message.replace(/\r\n|\r|\n/g, '
'); - - return message; - } - - public getImage(index: number): string - { - const imageName = (this._images[index] || ''); - - if(!imageName || !imageName.length) return null; - - let assetUrl = GetConfigurationValue('catalog.asset.image.url'); - - assetUrl = assetUrl.replace('%name%', imageName); - - return assetUrl; - } -} diff --git a/src/api/catalog/PlacedObjectPurchaseData.ts b/src/api/catalog/PlacedObjectPurchaseData.ts deleted file mode 100644 index 84bad8c..0000000 --- a/src/api/catalog/PlacedObjectPurchaseData.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { IFurnitureData, IProductData } from '@nitrots/nitro-renderer'; -import { IPurchasableOffer } from './IPurchasableOffer'; - -export class PlacedObjectPurchaseData -{ - constructor( - public readonly roomId: number, - public readonly objectId: number, - public readonly category: number, - public readonly wallLocation: string, - public readonly x: number, - public readonly y: number, - public readonly direction: number, - public readonly offer: IPurchasableOffer) - {} - - public get offerId(): number - { - return this.offer.offerId; - } - - public get productClassId(): number - { - return this.offer.product.productClassId; - } - - public get productData(): IProductData - { - return this.offer.product.productData; - } - - public get furniData(): IFurnitureData - { - return this.offer.product.furnitureData; - } - - public get extraParam(): string - { - return this.offer.product.extraParam; - } -} diff --git a/src/api/catalog/Product.ts b/src/api/catalog/Product.ts deleted file mode 100644 index 17d9340..0000000 --- a/src/api/catalog/Product.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, IFurnitureData, IObjectData, IProductData } from '@nitrots/nitro-renderer'; -import { GetConfigurationValue } from '../nitro'; -import { GetPixelEffectIcon, GetSubscriptionProductIcon } from './CatalogUtilities'; -import { IProduct } from './IProduct'; -import { IPurchasableOffer } from './IPurchasableOffer'; -import { ProductTypeEnum } from './ProductTypeEnum'; - -export class Product implements IProduct -{ - public static EFFECT_CLASSID_NINJA_DISAPPEAR: number = 108; - - private _productType: string; - private _productClassId: number; - private _extraParam: string; - private _productCount: number; - private _productData: IProductData; - private _furnitureData: IFurnitureData; - private _isUniqueLimitedItem: boolean; - private _uniqueLimitedItemSeriesSize: number; - private _uniqueLimitedItemsLeft: number; - - constructor(productType: string, productClassId: number, extraParam: string, productCount: number, productData: IProductData, furnitureData: IFurnitureData, isUniqueLimitedItem: boolean = false, uniqueLimitedItemSeriesSize: number = 0, uniqueLimitedItemsLeft: number = 0) - { - this._productType = productType.toLowerCase(); - this._productClassId = productClassId; - this._extraParam = extraParam; - this._productCount = productCount; - this._productData = productData; - this._furnitureData = furnitureData; - this._isUniqueLimitedItem = isUniqueLimitedItem; - this._uniqueLimitedItemSeriesSize = uniqueLimitedItemSeriesSize; - this._uniqueLimitedItemsLeft = uniqueLimitedItemsLeft; - } - - public static stripAddonProducts(products: IProduct[]): IProduct[] - { - if(products.length === 1) return products; - - return products.filter(product => ((product.productType !== ProductTypeEnum.BADGE) && (product.productType !== ProductTypeEnum.EFFECT) && (product.productClassId !== Product.EFFECT_CLASSID_NINJA_DISAPPEAR))); - } - - public getIconUrl(offer: IPurchasableOffer = null, stuffData: IObjectData = null): string - { - switch(this._productType) - { - case ProductTypeEnum.FLOOR: - return GetRoomEngine().getFurnitureFloorIconUrl(this.productClassId); - case ProductTypeEnum.WALL: { - if(offer && this._furnitureData) - { - let iconName = ''; - - switch(this._furnitureData.className) - { - case 'floor': - iconName = [ 'th', this._furnitureData.className, offer.product.extraParam ].join('_'); - break; - case 'wallpaper': - iconName = [ 'th', 'wall', offer.product.extraParam ].join('_'); - break; - case 'landscape': - iconName = [ 'th', this._furnitureData.className, (offer.product.extraParam || '').replace('.', '_'), '001' ].join('_'); - break; - } - - if(iconName !== '') - { - const assetUrl = GetConfigurationValue('catalog.asset.url'); - - return `${ assetUrl }/${ iconName }.png`; - } - } - - return GetRoomEngine().getFurnitureWallIconUrl(this.productClassId, this._extraParam); - } - case ProductTypeEnum.EFFECT: - return GetPixelEffectIcon(this.productClassId); - case ProductTypeEnum.HABBO_CLUB: - return GetSubscriptionProductIcon(this.productClassId); - case ProductTypeEnum.BADGE: - return GetSessionDataManager().getBadgeUrl(this._extraParam); - case ProductTypeEnum.ROBOT: - return null; - } - - return null; - } - - public get productType(): string - { - return this._productType; - } - - public get productClassId(): number - { - return this._productClassId; - } - - public get extraParam(): string - { - return this._extraParam; - } - - public set extraParam(extraParam: string) - { - this._extraParam = extraParam; - } - - public get productCount(): number - { - return this._productCount; - } - - public get productData(): IProductData - { - return this._productData; - } - - public get furnitureData(): IFurnitureData - { - return this._furnitureData; - } - - public get isUniqueLimitedItem(): boolean - { - return this._isUniqueLimitedItem; - } - - public get uniqueLimitedItemSeriesSize(): number - { - return this._uniqueLimitedItemSeriesSize; - } - - public get uniqueLimitedItemsLeft(): number - { - return this._uniqueLimitedItemsLeft; - } - - public set uniqueLimitedItemsLeft(uniqueLimitedItemsLeft: number) - { - this._uniqueLimitedItemsLeft = uniqueLimitedItemsLeft; - } -} diff --git a/src/api/catalog/ProductTypeEnum.ts b/src/api/catalog/ProductTypeEnum.ts deleted file mode 100644 index f249081..0000000 --- a/src/api/catalog/ProductTypeEnum.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class ProductTypeEnum -{ - public static WALL: string = 'i'; - public static FLOOR: string = 's'; - public static EFFECT: string = 'e'; - public static HABBO_CLUB: string = 'h'; - public static BADGE: string = 'b'; - public static GAME_TOKEN: string = 'GAME_TOKEN'; - public static PET: string = 'p'; - public static ROBOT: string = 'r'; -} diff --git a/src/api/catalog/RequestedPage.ts b/src/api/catalog/RequestedPage.ts deleted file mode 100644 index 8c22730..0000000 --- a/src/api/catalog/RequestedPage.ts +++ /dev/null @@ -1,63 +0,0 @@ -export class RequestedPage -{ - public static REQUEST_TYPE_NONE: number = 0; - public static REQUEST_TYPE_ID: number = 1; - public static REQUEST_TYPE_OFFER: number = 2; - public static REQUEST_TYPE_NAME: number = 3; - - private _requestType: number; - private _requestById: number; - private _requestedByOfferId: number; - private _requestByName: string; - - constructor() - { - this._requestType = RequestedPage.REQUEST_TYPE_NONE; - } - - public resetRequest():void - { - this._requestType = RequestedPage.REQUEST_TYPE_NONE; - this._requestById = -1; - this._requestedByOfferId = -1; - this._requestByName = null; - } - - public get requestType(): number - { - return this._requestType; - } - - public get requestById(): number - { - return this._requestById; - } - - public set requestById(id: number) - { - this._requestType = RequestedPage.REQUEST_TYPE_ID; - this._requestById = id; - } - - public get requestedByOfferId(): number - { - return this._requestedByOfferId; - } - - public set requestedByOfferId(offerId: number) - { - this._requestType = RequestedPage.REQUEST_TYPE_OFFER; - this._requestedByOfferId = offerId; - } - - public get requestByName(): string - { - return this._requestByName; - } - - public set requestByName(name: string) - { - this._requestType = RequestedPage.REQUEST_TYPE_NAME; - this._requestByName = name; - } -} diff --git a/src/api/catalog/SearchResult.ts b/src/api/catalog/SearchResult.ts deleted file mode 100644 index 419f3cf..0000000 --- a/src/api/catalog/SearchResult.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ICatalogNode } from './ICatalogNode'; -import { IPurchasableOffer } from './IPurchasableOffer'; - -export class SearchResult -{ - constructor( - public readonly searchValue: string, - public readonly offers: IPurchasableOffer[], - public readonly filteredNodes: ICatalogNode[]) - {} -} diff --git a/src/api/catalog/index.ts b/src/api/catalog/index.ts deleted file mode 100644 index 6c5b9e2..0000000 --- a/src/api/catalog/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -export * from './BuilderFurniPlaceableStatus'; -export * from './CatalogNode'; -export * from './CatalogPage'; -export * from './CatalogPageName'; -export * from './CatalogPetPalette'; -export * from './CatalogPurchaseState'; -export * from './CatalogType'; -export * from './CatalogUtilities'; -export * from './FurnitureOffer'; -export * from './GetImageIconUrlForProduct'; -export * from './GiftWrappingConfiguration'; -export * from './ICatalogNode'; -export * from './ICatalogOptions'; -export * from './ICatalogPage'; -export * from './IMarketplaceSearchOptions'; -export * from './IPageLocalization'; -export * from './IProduct'; -export * from './IPurchasableOffer'; -export * from './IPurchaseOptions'; -export * from './MarketplaceOfferData'; -export * from './MarketplaceOfferState'; -export * from './MarketplaceSearchType'; -export * from './Offer'; -export * from './PageLocalization'; -export * from './PlacedObjectPurchaseData'; -export * from './Product'; -export * from './ProductTypeEnum'; -export * from './RequestedPage'; -export * from './SearchResult'; diff --git a/src/api/chat-history/ChatEntryType.ts b/src/api/chat-history/ChatEntryType.ts deleted file mode 100644 index 045f00c..0000000 --- a/src/api/chat-history/ChatEntryType.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class ChatEntryType -{ - public static TYPE_CHAT = 1; - public static TYPE_ROOM_INFO = 2; - public static TYPE_IM = 3; -} diff --git a/src/api/chat-history/ChatHistoryCurrentDate.ts b/src/api/chat-history/ChatHistoryCurrentDate.ts deleted file mode 100644 index 6947bca..0000000 --- a/src/api/chat-history/ChatHistoryCurrentDate.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const ChatHistoryCurrentDate = () => -{ - const currentTime = new Date(); - - return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`; -} diff --git a/src/api/chat-history/IChatEntry.ts b/src/api/chat-history/IChatEntry.ts deleted file mode 100644 index 1bf7a52..0000000 --- a/src/api/chat-history/IChatEntry.ts +++ /dev/null @@ -1,17 +0,0 @@ -export interface IChatEntry -{ - id: number; - webId: number; - entityId: number; - name: string; - look?: string; - message?: string; - entityType?: number; - style?: number; - chatType?: number; - imageUrl?: string; - color?: string; - roomId: number; - timestamp: string; - type: number; -} diff --git a/src/api/chat-history/IRoomHistoryEntry.ts b/src/api/chat-history/IRoomHistoryEntry.ts deleted file mode 100644 index 4986154..0000000 --- a/src/api/chat-history/IRoomHistoryEntry.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface IRoomHistoryEntry -{ - id: number; - name: string; -} diff --git a/src/api/chat-history/MessengerHistoryCurrentDate.ts b/src/api/chat-history/MessengerHistoryCurrentDate.ts deleted file mode 100644 index 3aeebc5..0000000 --- a/src/api/chat-history/MessengerHistoryCurrentDate.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const MessengerHistoryCurrentDate = (secondsSinceNow: number = 0) => -{ - const currentTime = secondsSinceNow ? new Date(Date.now() - secondsSinceNow * 1000) : new Date(); - - return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`; -} diff --git a/src/api/chat-history/index.ts b/src/api/chat-history/index.ts deleted file mode 100644 index a989374..0000000 --- a/src/api/chat-history/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './ChatEntryType'; -export * from './ChatHistoryCurrentDate'; -export * from './IChatEntry'; -export * from './IRoomHistoryEntry'; -export * from './MessengerHistoryCurrentDate'; diff --git a/src/api/events/DispatchEvent.ts b/src/api/events/DispatchEvent.ts deleted file mode 100644 index 79e2f5c..0000000 --- a/src/api/events/DispatchEvent.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { IEventDispatcher, NitroEvent } from '@nitrots/nitro-renderer'; - -export const DispatchEvent = (eventDispatcher: IEventDispatcher, event: NitroEvent) => eventDispatcher.dispatchEvent(event); diff --git a/src/api/events/DispatchMainEvent.ts b/src/api/events/DispatchMainEvent.ts deleted file mode 100644 index e316b30..0000000 --- a/src/api/events/DispatchMainEvent.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { GetEventDispatcher, NitroEvent } from '@nitrots/nitro-renderer'; -import { DispatchEvent } from './DispatchEvent'; - -export const DispatchMainEvent = (event: NitroEvent) => DispatchEvent(GetEventDispatcher(), event); diff --git a/src/api/events/DispatchUiEvent.ts b/src/api/events/DispatchUiEvent.ts deleted file mode 100644 index 5200bb4..0000000 --- a/src/api/events/DispatchUiEvent.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; -import { DispatchEvent } from './DispatchEvent'; -import { UI_EVENT_DISPATCHER } from './UI_EVENT_DISPATCHER'; - -export const DispatchUiEvent = (event: NitroEvent) => DispatchEvent(UI_EVENT_DISPATCHER, event); diff --git a/src/api/events/UI_EVENT_DISPATCHER.ts b/src/api/events/UI_EVENT_DISPATCHER.ts deleted file mode 100644 index cb57311..0000000 --- a/src/api/events/UI_EVENT_DISPATCHER.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { EventDispatcher, IEventDispatcher } from '@nitrots/nitro-renderer'; - -export const UI_EVENT_DISPATCHER: IEventDispatcher = new EventDispatcher(); diff --git a/src/api/events/index.ts b/src/api/events/index.ts deleted file mode 100644 index b7c22ee..0000000 --- a/src/api/events/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './DispatchEvent'; -export * from './DispatchMainEvent'; -export * from './DispatchUiEvent'; -export * from './UI_EVENT_DISPATCHER'; diff --git a/src/api/friends/GetGroupChatData.ts b/src/api/friends/GetGroupChatData.ts deleted file mode 100644 index 75df962..0000000 --- a/src/api/friends/GetGroupChatData.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { IGroupChatData } from './IGroupChatData'; - -export const GetGroupChatData = (extraData: string) => -{ - if(!extraData || !extraData.length) return null; - - const splitData = extraData.split('/'); - const username = splitData[0]; - const figure = splitData[1]; - const userId = parseInt(splitData[2]); - - return ({ username: username, figure: figure, userId: userId } as IGroupChatData); -} diff --git a/src/api/friends/IGroupChatData.ts b/src/api/friends/IGroupChatData.ts deleted file mode 100644 index 24a3f9c..0000000 --- a/src/api/friends/IGroupChatData.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface IGroupChatData -{ - username: string; - figure: string; - userId: number; -} diff --git a/src/api/friends/MessengerFriend.ts b/src/api/friends/MessengerFriend.ts deleted file mode 100644 index b5cfc88..0000000 --- a/src/api/friends/MessengerFriend.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { FriendParser } from '@nitrots/nitro-renderer'; - -export class MessengerFriend -{ - public static RELATIONSHIP_NONE: number = 0; - public static RELATIONSHIP_HEART: number = 1; - public static RELATIONSHIP_SMILE: number = 2; - public static RELATIONSHIP_BOBBA: number = 3; - - public id: number = -1; - public name: string = null; - public gender: number = 0; - public online: boolean = false; - public followingAllowed: boolean = false; - public figure: string = null; - public categoryId: number = 0; - public motto: string = null; - public realName: string = null; - public lastAccess: string = null; - public persistedMessageUser: boolean = false; - public vipMember: boolean = false; - public pocketHabboUser: boolean = false; - public relationshipStatus: number = -1; - public unread: number = 0; - - public populate(parser: FriendParser): void - { - this.id = parser.id; - this.name = parser.name; - this.gender = parser.gender; - this.online = parser.online; - this.followingAllowed = parser.followingAllowed; - this.figure = parser.figure; - this.categoryId = parser.categoryId; - this.motto = parser.motto; - this.realName = parser.realName; - this.lastAccess = parser.lastAccess; - this.persistedMessageUser = parser.persistedMessageUser; - this.vipMember = parser.vipMember; - this.pocketHabboUser = parser.pocketHabboUser; - this.relationshipStatus = parser.relationshipStatus; - } -} diff --git a/src/api/friends/MessengerGroupType.ts b/src/api/friends/MessengerGroupType.ts deleted file mode 100644 index d46a1b6..0000000 --- a/src/api/friends/MessengerGroupType.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class MessengerGroupType -{ - public static readonly GROUP_CHAT = 0; - public static readonly PRIVATE_CHAT = 1; -} diff --git a/src/api/friends/MessengerIconState.ts b/src/api/friends/MessengerIconState.ts deleted file mode 100644 index 63f8c13..0000000 --- a/src/api/friends/MessengerIconState.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class MessengerIconState -{ - public static HIDDEN: number = 0; - public static SHOW: number = 1; - public static UNREAD: number = 2; -} diff --git a/src/api/friends/MessengerRequest.ts b/src/api/friends/MessengerRequest.ts deleted file mode 100644 index 89ceec5..0000000 --- a/src/api/friends/MessengerRequest.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { FriendRequestData } from '@nitrots/nitro-renderer'; - -export class MessengerRequest -{ - private _id: number; - private _name: string; - private _requesterUserId: number; - private _figureString: string; - - public populate(data: FriendRequestData): boolean - { - if(!data) return false; - - this._id = data.requestId; - this._name = data.requesterName; - this._figureString = data.figureString; - this._requesterUserId = data.requesterUserId; - - return true; - } - - public get id(): number - { - return this._id; - } - - public get name(): string - { - return this._name; - } - - public get requesterUserId(): number - { - return this._requesterUserId; - } - - public get figureString(): string - { - return this._figureString; - } -} diff --git a/src/api/friends/MessengerSettings.ts b/src/api/friends/MessengerSettings.ts deleted file mode 100644 index e0fc8c2..0000000 --- a/src/api/friends/MessengerSettings.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { FriendCategoryData } from '@nitrots/nitro-renderer'; - -export class MessengerSettings -{ - constructor( - public userFriendLimit: number = 0, - public normalFriendLimit: number = 0, - public extendedFriendLimit: number = 0, - public categories: FriendCategoryData[] = []) - {} -} diff --git a/src/api/friends/MessengerThread.ts b/src/api/friends/MessengerThread.ts deleted file mode 100644 index 405ea33..0000000 --- a/src/api/friends/MessengerThread.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { GetGroupChatData } from './GetGroupChatData'; -import { MessengerFriend } from './MessengerFriend'; -import { MessengerGroupType } from './MessengerGroupType'; -import { MessengerThreadChat } from './MessengerThreadChat'; -import { MessengerThreadChatGroup } from './MessengerThreadChatGroup'; - -export class MessengerThread -{ - public static MESSAGE_RECEIVED: string = 'MT_MESSAGE_RECEIVED'; - public static THREAD_ID: number = 0; - - private _threadId: number; - private _participant: MessengerFriend; - private _groups: MessengerThreadChatGroup[]; - private _lastUpdated: Date; - private _unreadCount: number; - - constructor(participant: MessengerFriend) - { - this._threadId = ++MessengerThread.THREAD_ID; - this._participant = participant; - this._groups = []; - this._lastUpdated = new Date(); - this._unreadCount = 0; - } - - public addMessage(senderId: number, message: string, secondsSinceSent: number = 0, extraData: string = null, type: number = 0): MessengerThreadChat - { - const isGroupChat = (senderId < 0 && extraData); - const userId = isGroupChat ? GetGroupChatData(extraData).userId : senderId; - - const group = this.getLastGroup(userId); - - if(!group) return; - - if(isGroupChat) group.type = MessengerGroupType.GROUP_CHAT; - - const chat = new MessengerThreadChat(senderId, message, secondsSinceSent, extraData, type); - - group.addChat(chat); - - this._lastUpdated = new Date(); - - this._unreadCount++; - - return chat; - } - - private getLastGroup(userId: number): MessengerThreadChatGroup - { - let group = this._groups[(this._groups.length - 1)]; - - if(group && (group.userId === userId)) return group; - - group = new MessengerThreadChatGroup(userId); - - this._groups.push(group); - - return group; - } - - public setRead(): void - { - this._unreadCount = 0; - } - - public get threadId(): number - { - return this._threadId; - } - - public get participant(): MessengerFriend - { - return this._participant; - } - - public get groups(): MessengerThreadChatGroup[] - { - return this._groups; - } - - public get lastUpdated(): Date - { - return this._lastUpdated; - } - - public get unreadCount(): number - { - return this._unreadCount; - } - - public get unread(): boolean - { - return (this._unreadCount > 0); - } -} diff --git a/src/api/friends/MessengerThreadChat.ts b/src/api/friends/MessengerThreadChat.ts deleted file mode 100644 index 2927fec..0000000 --- a/src/api/friends/MessengerThreadChat.ts +++ /dev/null @@ -1,54 +0,0 @@ -export class MessengerThreadChat -{ - public static CHAT: number = 0; - public static ROOM_INVITE: number = 1; - public static STATUS_NOTIFICATION: number = 2; - public static SECURITY_NOTIFICATION: number = 3; - - private _type: number; - private _senderId: number; - private _message: string; - private _secondsSinceSent: number; - private _extraData: string; - private _date: Date; - - constructor(senderId: number, message: string, secondsSinceSent: number = 0, extraData: string = null, type: number = 0) - { - this._type = type; - this._senderId = senderId; - this._message = message; - this._secondsSinceSent = secondsSinceSent; - this._extraData = extraData; - this._date = new Date(); - } - - public get type(): number - { - return this._type; - } - - public get senderId(): number - { - return this._senderId; - } - - public get message(): string - { - return this._message; - } - - public get secondsSinceSent(): number - { - return this._secondsSinceSent; - } - - public get extraData(): string - { - return this._extraData; - } - - public get date(): Date - { - return this._date; - } -} diff --git a/src/api/friends/MessengerThreadChatGroup.ts b/src/api/friends/MessengerThreadChatGroup.ts deleted file mode 100644 index 1668aed..0000000 --- a/src/api/friends/MessengerThreadChatGroup.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { MessengerGroupType } from './MessengerGroupType'; -import { MessengerThreadChat } from './MessengerThreadChat'; - -export class MessengerThreadChatGroup -{ - private _userId: number; - private _chats: MessengerThreadChat[]; - private _type: number; - - constructor(userId: number, type = MessengerGroupType.PRIVATE_CHAT) - { - this._userId = userId; - this._chats = []; - this._type = type; - } - - public addChat(message: MessengerThreadChat): void - { - this._chats.push(message); - } - - public get userId(): number - { - return this._userId; - } - - public get chats(): MessengerThreadChat[] - { - return this._chats; - } - - public get type(): number - { - return this._type; - } - - public set type(type: number) - { - this._type = type; - } -} diff --git a/src/api/friends/OpenMessengerChat.ts b/src/api/friends/OpenMessengerChat.ts deleted file mode 100644 index 6050f2f..0000000 --- a/src/api/friends/OpenMessengerChat.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { CreateLinkEvent } from '@nitrots/nitro-renderer'; - -export function OpenMessengerChat(friendId: number = 0): void -{ - if(friendId === 0) CreateLinkEvent('friends-messenger/toggle'); - else CreateLinkEvent(`friends-messenger/${ friendId }`); -} diff --git a/src/api/friends/index.ts b/src/api/friends/index.ts deleted file mode 100644 index ce1ed60..0000000 --- a/src/api/friends/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -export * from './GetGroupChatData'; -export * from './IGroupChatData'; -export * from './MessengerFriend'; -export * from './MessengerGroupType'; -export * from './MessengerIconState'; -export * from './MessengerRequest'; -export * from './MessengerSettings'; -export * from './MessengerThread'; -export * from './MessengerThreadChat'; -export * from './MessengerThreadChatGroup'; -export * from './OpenMessengerChat'; diff --git a/src/api/groups/GetGroupInformation.ts b/src/api/groups/GetGroupInformation.ts deleted file mode 100644 index 14fe326..0000000 --- a/src/api/groups/GetGroupInformation.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { GroupInformationComposer } from '@nitrots/nitro-renderer'; -import { SendMessageComposer } from '../nitro'; - -export function GetGroupInformation(groupId: number): void -{ - SendMessageComposer(new GroupInformationComposer(groupId, true)); -} diff --git a/src/api/groups/GetGroupManager.ts b/src/api/groups/GetGroupManager.ts deleted file mode 100644 index 2044a45..0000000 --- a/src/api/groups/GetGroupManager.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { CreateLinkEvent } from '@nitrots/nitro-renderer'; - -export function GetGroupManager(groupId: number): void -{ - CreateLinkEvent(`groups/manage/${ groupId }`); -} diff --git a/src/api/groups/GetGroupMembers.ts b/src/api/groups/GetGroupMembers.ts deleted file mode 100644 index 9e10b01..0000000 --- a/src/api/groups/GetGroupMembers.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { CreateLinkEvent } from '@nitrots/nitro-renderer'; - -export function GetGroupMembers(groupId: number, levelId?: number): void -{ - if(!levelId) CreateLinkEvent(`group-members/${ groupId }`); - else CreateLinkEvent(`group-members/${ groupId }/${ levelId }`); -} diff --git a/src/api/groups/GroupBadgePart.ts b/src/api/groups/GroupBadgePart.ts deleted file mode 100644 index 09c137c..0000000 --- a/src/api/groups/GroupBadgePart.ts +++ /dev/null @@ -1,30 +0,0 @@ -export class GroupBadgePart -{ - public static BASE: string = 'b'; - public static SYMBOL: string = 's'; - - public type: string; - public key: number; - public color: number; - public position: number; - - constructor(type: string, key?: number, color?: number, position?: number) - { - this.type = type; - this.key = key ? key : 0; - this.color = color ? color : 0; - this.position = position ? position : 4; - } - - public get code(): string - { - if((this.key === 0) && (this.type !== GroupBadgePart.BASE)) return null; - - return GroupBadgePart.getCode(this.type, this.key, this.color, this.position); - } - - public static getCode(type: string, key: number, color: number, position: number): string - { - return type + (key < 10 ? '0' : '') + key + (color < 10 ? '0' : '') + color + position; - } -} diff --git a/src/api/groups/GroupMembershipType.ts b/src/api/groups/GroupMembershipType.ts deleted file mode 100644 index 532c836..0000000 --- a/src/api/groups/GroupMembershipType.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class GroupMembershipType -{ - public static NOT_MEMBER: number = 0; - public static MEMBER: number = 1; - public static REQUEST_PENDING: number = 2; -} diff --git a/src/api/groups/GroupType.ts b/src/api/groups/GroupType.ts deleted file mode 100644 index 58ae72c..0000000 --- a/src/api/groups/GroupType.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class GroupType -{ - public static REGULAR: number = 0; - public static EXCLUSIVE: number = 1; - public static PRIVATE: number = 2; -} diff --git a/src/api/groups/IGroupCustomize.ts b/src/api/groups/IGroupCustomize.ts deleted file mode 100644 index 44fc4ff..0000000 --- a/src/api/groups/IGroupCustomize.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface IGroupCustomize -{ - badgeBases: { id: number, images: string[] }[]; - badgeSymbols: { id: number, images: string[] }[]; - badgePartColors: { id: number, color: string }[]; - groupColorsA: { id: number, color: string }[]; - groupColorsB: { id: number, color: string }[]; -} diff --git a/src/api/groups/IGroupData.ts b/src/api/groups/IGroupData.ts deleted file mode 100644 index bb65b49..0000000 --- a/src/api/groups/IGroupData.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { GroupBadgePart } from './GroupBadgePart'; - -export interface IGroupData -{ - groupId: number; - groupName: string; - groupDescription: string; - groupHomeroomId: number; - groupState: number; - groupCanMembersDecorate: boolean; - groupColors: number[]; - groupBadgeParts: GroupBadgePart[]; -} diff --git a/src/api/groups/ToggleFavoriteGroup.ts b/src/api/groups/ToggleFavoriteGroup.ts deleted file mode 100644 index 572e05d..0000000 --- a/src/api/groups/ToggleFavoriteGroup.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { GroupFavoriteComposer, GroupUnfavoriteComposer, HabboGroupEntryData } from '@nitrots/nitro-renderer'; -import { SendMessageComposer } from '../nitro'; - -export const ToggleFavoriteGroup = (group: HabboGroupEntryData) => -{ - SendMessageComposer(group.favourite ? new GroupUnfavoriteComposer(group.groupId) : new GroupFavoriteComposer(group.groupId)); -} diff --git a/src/api/groups/TryJoinGroup.ts b/src/api/groups/TryJoinGroup.ts deleted file mode 100644 index 63959bf..0000000 --- a/src/api/groups/TryJoinGroup.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { GroupJoinComposer } from '@nitrots/nitro-renderer'; -import { SendMessageComposer } from '../nitro'; - -export const TryJoinGroup = (groupId: number) => SendMessageComposer(new GroupJoinComposer(groupId)); diff --git a/src/api/groups/index.ts b/src/api/groups/index.ts deleted file mode 100644 index 4842948..0000000 --- a/src/api/groups/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './GetGroupInformation'; -export * from './GetGroupManager'; -export * from './GetGroupMembers'; -export * from './GroupBadgePart'; -export * from './GroupMembershipType'; -export * from './GroupType'; -export * from './IGroupCustomize'; -export * from './IGroupData'; -export * from './ToggleFavoriteGroup'; -export * from './TryJoinGroup'; diff --git a/src/api/guide-tool/GuideSessionState.ts b/src/api/guide-tool/GuideSessionState.ts deleted file mode 100644 index c5e24f3..0000000 --- a/src/api/guide-tool/GuideSessionState.ts +++ /dev/null @@ -1,23 +0,0 @@ -export class GuideSessionState -{ - public static readonly NONE: string = 'NONE'; - public static readonly ERROR: string = 'ERROR'; - public static readonly REJECTED: string = 'REJECTED'; - public static readonly USER_CREATE: string = 'USER_CREATE'; - public static readonly USER_PENDING: string = 'USER_PENDING'; - public static readonly USER_ONGOING: string = 'USER_ONGOING'; - public static readonly USER_FEEDBACK: string = 'USER_FEEDBACK'; - public static readonly USER_NO_HELPERS: string = 'USER_NO_HELPERS'; - public static readonly USER_SOMETHING_WRONG: string = 'USER_SOMETHING_WRONG'; - public static readonly USER_THANKS: string = 'USER_THANKS'; - public static readonly USER_GUIDE_DISCONNECTED: string = 'USER_GUIDE_DISCONNECTED'; - public static readonly GUIDE_TOOL_MENU: string = 'GUIDE_TOOL_MENU'; - public static readonly GUIDE_ACCEPT: string = 'GUIDE_ACCEPT'; - public static readonly GUIDE_ONGOING: string = 'GUIDE_ONGOING'; - public static readonly GUIDE_CLOSED: string = 'GUIDE_CLOSED'; - public static readonly GUARDIAN_CHAT_REVIEW_ACCEPT: string = 'GUARDIAN_CHAT_REVIEW_ACCEPT'; - public static readonly GUARDIAN_CHAT_REVIEW_WAIT_FOR_VOTERS: string = 'GUARDIAN_CHAT_REVIEW_WAIT_FOR_VOTERS'; - public static readonly GUARDIAN_CHAT_REVIEW_VOTE: string = 'GUARDIAN_CHAT_REVIEW_VOTE'; - public static readonly GUARDIAN_CHAT_REVIEW_WAIT_FOR_RESULTS: string = 'GUARDIAN_CHAT_REVIEW_WAIT_FOR_RESULTS'; - public static readonly GUARDIAN_CHAT_REVIEW_RESULTS: string = 'GUARDIAN_CHAT_REVIEW_RESULTS'; -} diff --git a/src/api/guide-tool/GuideToolMessage.ts b/src/api/guide-tool/GuideToolMessage.ts deleted file mode 100644 index 3810726..0000000 --- a/src/api/guide-tool/GuideToolMessage.ts +++ /dev/null @@ -1,21 +0,0 @@ -export class GuideToolMessage -{ - private _message: string; - private _roomId: number; - - constructor(message: string, roomId?: number) - { - this._message = message; - this._roomId = roomId; - } - - public get message(): string - { - return this._message; - } - - public get roomId(): number - { - return this._roomId; - } -} diff --git a/src/api/guide-tool/GuideToolMessageGroup.ts b/src/api/guide-tool/GuideToolMessageGroup.ts deleted file mode 100644 index bf03c9b..0000000 --- a/src/api/guide-tool/GuideToolMessageGroup.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { GuideToolMessage } from './GuideToolMessage'; - -export class GuideToolMessageGroup -{ - private _userId: number; - private _messages: GuideToolMessage[]; - - constructor(userId: number) - { - this._userId = userId; - this._messages = []; - } - - public addChat(message: GuideToolMessage): void - { - this._messages.push(message); - } - - public get userId(): number - { - return this._userId; - } - - public get messages(): GuideToolMessage[] - { - return this._messages; - } -} diff --git a/src/api/guide-tool/index.ts b/src/api/guide-tool/index.ts deleted file mode 100644 index 1400adc..0000000 --- a/src/api/guide-tool/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './GuideSessionState'; -export * from './GuideToolMessage'; -export * from './GuideToolMessageGroup'; diff --git a/src/api/hc-center/ClubStatus.ts b/src/api/hc-center/ClubStatus.ts deleted file mode 100644 index 8200b14..0000000 --- a/src/api/hc-center/ClubStatus.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class ClubStatus -{ - public static ACTIVE: string = 'active'; - public static NONE: string = 'none'; - public static EXPIRED: string = 'expired'; -} diff --git a/src/api/hc-center/GetClubBadge.ts b/src/api/hc-center/GetClubBadge.ts deleted file mode 100644 index 6b779e0..0000000 --- a/src/api/hc-center/GetClubBadge.ts +++ /dev/null @@ -1,11 +0,0 @@ -const DEFAULT_BADGE: string = 'HC1'; -const BADGES: string[] = [ 'ACH_VipHC1', 'ACH_VipHC2', 'ACH_VipHC3', 'ACH_VipHC4', 'ACH_VipHC5', 'HC1', 'HC2', 'HC3', 'HC4', 'HC5' ]; - -export const GetClubBadge = (badgeCodes: string[]) => -{ - let badgeCode: string = null; - - BADGES.forEach(badge => ((badgeCodes.indexOf(badge) > -1) && (badgeCode = badge))); - - return (badgeCode || DEFAULT_BADGE); -} diff --git a/src/api/hc-center/index.ts b/src/api/hc-center/index.ts deleted file mode 100644 index cee8f69..0000000 --- a/src/api/hc-center/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './ClubStatus'; -export * from './GetClubBadge'; diff --git a/src/api/help/CallForHelpResult.ts b/src/api/help/CallForHelpResult.ts deleted file mode 100644 index 37e7ea1..0000000 --- a/src/api/help/CallForHelpResult.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class CallForHelpResult -{ - public static readonly TOO_MANY_PENDING_CALLS_CODE = 1; - public static readonly HAS_ABUSIVE_CALL_CODE = 2; -} diff --git a/src/api/help/GetCloseReasonKey.ts b/src/api/help/GetCloseReasonKey.ts deleted file mode 100644 index 520d14f..0000000 --- a/src/api/help/GetCloseReasonKey.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const GetCloseReasonKey = (code: number) => -{ - if(code === 1) return 'useless'; - - if(code === 2) return 'abusive'; - - return 'resolved'; -} diff --git a/src/api/help/IHelpReport.ts b/src/api/help/IHelpReport.ts deleted file mode 100644 index 8611707..0000000 --- a/src/api/help/IHelpReport.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { IChatEntry } from '../chat-history'; - -export interface IHelpReport -{ - reportType: number; - reportedUserId: number; - reportedChats: IChatEntry[]; - cfhCategory: number; - cfhTopic: number; - roomId: number; - roomName: string; - groupId: number; - threadId: number; - messageId: number; - extraData: string; - roomObjectId: number; - message: string; - currentStep: number; -} diff --git a/src/api/help/IReportedUser.ts b/src/api/help/IReportedUser.ts deleted file mode 100644 index 90a3887..0000000 --- a/src/api/help/IReportedUser.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface IReportedUser -{ - id: number; - username: string; -} diff --git a/src/api/help/ReportState.ts b/src/api/help/ReportState.ts deleted file mode 100644 index ae3a3bd..0000000 --- a/src/api/help/ReportState.ts +++ /dev/null @@ -1,8 +0,0 @@ -export class ReportState -{ - public static readonly SELECT_USER = 0; - public static readonly SELECT_CHATS = 1; - public static readonly SELECT_TOPICS = 2; - public static readonly INPUT_REPORT_MESSAGE = 3; - public static readonly REPORT_SUMMARY = 4; -} diff --git a/src/api/help/ReportType.ts b/src/api/help/ReportType.ts deleted file mode 100644 index 24eb7ae..0000000 --- a/src/api/help/ReportType.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class ReportType -{ - public static readonly EMERGENCY = 1; - public static readonly GUIDE = 2; - public static readonly IM = 3; - public static readonly ROOM = 4; - public static readonly BULLY = 6; - public static readonly THREAD = 7; - public static readonly MESSAGE = 8; - public static readonly PHOTO = 9; -} diff --git a/src/api/help/index.ts b/src/api/help/index.ts deleted file mode 100644 index 6fa2045..0000000 --- a/src/api/help/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './CallForHelpResult'; -export * from './GetCloseReasonKey'; -export * from './IHelpReport'; -export * from './IReportedUser'; -export * from './ReportState'; -export * from './ReportType'; diff --git a/src/api/index.ts b/src/api/index.ts deleted file mode 100644 index 7089277..0000000 --- a/src/api/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -export * from './GetRendererVersion'; -export * from './GetUIVersion'; -export * from './achievements'; -export * from './avatar'; -export * from './camera'; -export * from './campaign'; -export * from './catalog'; -export * from './chat-history'; -export * from './events'; -export * from './friends'; -export * from './groups'; -export * from './guide-tool'; -export * from './hc-center'; -export * from './help'; -export * from './inventory'; -export * from './mod-tools'; -export * from './navigator'; -export * from './nitro'; -export * from './nitro/room'; -export * from './nitro/session'; -export * from './notification'; -export * from './purse'; -export * from './room'; -export * from './room/events'; -export * from './room/widgets'; -export * from './user'; -export * from './utils'; -export * from './wired'; diff --git a/src/api/inventory/FurniCategory.ts b/src/api/inventory/FurniCategory.ts deleted file mode 100644 index 6528947..0000000 --- a/src/api/inventory/FurniCategory.ts +++ /dev/null @@ -1,26 +0,0 @@ -export class FurniCategory -{ - public static DEFAULT: number = 1; - public static WALL_PAPER: number = 2; - public static FLOOR: number = 3; - public static LANDSCAPE: number = 4; - public static POST_IT: number = 5; - public static POSTER: number = 6; - public static SOUND_SET: number = 7; - public static TRAX_SONG: number = 8; - public static PRESENT: number = 9; - public static ECOTRON_BOX: number = 10; - public static TROPHY: number = 11; - public static CREDIT_FURNI: number = 12; - public static PET_SHAMPOO: number = 13; - public static PET_CUSTOM_PART: number = 14; - public static PET_CUSTOM_PART_SHAMPOO: number = 15; - public static PET_SADDLE: number = 16; - public static GUILD_FURNI: number = 17; - public static GAME_FURNI: number = 18; - public static MONSTERPLANT_SEED: number = 19; - public static MONSTERPLANT_REVIVAL: number = 20; - public static MONSTERPLANT_REBREED: number = 21; - public static MONSTERPLANT_FERTILIZE: number = 22; - public static FIGURE_PURCHASABLE_SET: number = 23; -} diff --git a/src/api/inventory/FurnitureItem.ts b/src/api/inventory/FurnitureItem.ts deleted file mode 100644 index f5f2f0f..0000000 --- a/src/api/inventory/FurnitureItem.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { GetTickerTime, IFurnitureItemData, IObjectData } from '@nitrots/nitro-renderer'; -import { IFurnitureItem } from './IFurnitureItem'; - -export class FurnitureItem implements IFurnitureItem -{ - private _expirationTimeStamp: number; - private _isWallItem: boolean; - private _songId: number; - private _locked: boolean; - private _id: number; - private _ref: number; - private _category: number; - private _type: number; - private _stuffData: IObjectData; - private _extra: number; - private _recyclable: boolean; - private _tradeable: boolean; - private _groupable: boolean; - private _sellable: boolean; - private _secondsToExpiration: number; - private _hasRentPeriodStarted: boolean; - private _creationDay: number; - private _creationMonth: number; - private _creationYear: number; - private _slotId: string; - private _isRented: boolean; - private _flatId: number; - - constructor(parser: IFurnitureItemData) - { - if(!parser) return; - - this._locked = false; - this._id = parser.itemId; - this._type = parser.spriteId; - this._ref = parser.ref; - this._category = parser.category; - this._groupable = ((parser.isGroupable) && (!(parser.rentable))); - this._tradeable = parser.tradable; - this._recyclable = parser.isRecycleable; - this._sellable = parser.sellable; - this._stuffData = parser.stuffData; - this._extra = parser.extra; - this._secondsToExpiration = parser.secondsToExpiration; - this._expirationTimeStamp = parser.expirationTimeStamp; - this._hasRentPeriodStarted = parser.hasRentPeriodStarted; - this._creationDay = parser.creationDay; - this._creationMonth = parser.creationMonth; - this._creationYear = parser.creationYear; - this._slotId = parser.slotId; - this._songId = parser.songId; - this._flatId = parser.flatId; - this._isRented = parser.rentable; - this._isWallItem = parser.isWallItem; - } - - public get rentable(): boolean - { - return this._isRented; - } - - public get id(): number - { - return this._id; - } - - public get ref(): number - { - return this._ref; - } - - public get category(): number - { - return this._category; - } - - public get type(): number - { - return this._type; - } - - public get stuffData(): IObjectData - { - return this._stuffData; - } - - public set stuffData(k: IObjectData) - { - this._stuffData = k; - } - - public get extra(): number - { - return this._extra; - } - - public get recyclable(): boolean - { - return this._recyclable; - } - - public get isTradable(): boolean - { - return this._tradeable; - } - - public get isGroupable(): boolean - { - return this._groupable; - } - - public get sellable(): boolean - { - return this._sellable; - } - - public get secondsToExpiration(): number - { - if(this._secondsToExpiration === -1) return -1; - - let time = -1; - - if(this._hasRentPeriodStarted) - { - time = (this._secondsToExpiration - ((GetTickerTime() - this._expirationTimeStamp) / 1000)); - - if(time < 0) time = 0; - } - else - { - time = this._secondsToExpiration; - } - - return time; - } - - public get creationDay(): number - { - return this._creationDay; - } - - public get creationMonth(): number - { - return this._creationMonth; - } - - public get creationYear(): number - { - return this._creationYear; - } - - public get slotId(): string - { - return this._slotId; - } - - public get songId(): number - { - return this._songId; - } - - public get locked(): boolean - { - return this._locked; - } - - public set locked(k: boolean) - { - this._locked = k; - } - - public get flatId(): number - { - return this._flatId; - } - - public get isWallItem(): boolean - { - return this._isWallItem; - } - - public get hasRentPeriodStarted(): boolean - { - return this._hasRentPeriodStarted; - } - - public get expirationTimeStamp(): number - { - return this._expirationTimeStamp; - } - - public update(parser: IFurnitureItemData): void - { - this._type = parser.spriteId; - this._ref = parser.ref; - this._category = parser.category; - this._groupable = (parser.isGroupable && !parser.rentable); - this._tradeable = parser.tradable; - this._recyclable = parser.isRecycleable; - this._sellable = parser.sellable; - this._stuffData = parser.stuffData; - this._extra = parser.extra; - this._secondsToExpiration = parser.secondsToExpiration; - this._expirationTimeStamp = parser.expirationTimeStamp; - this._hasRentPeriodStarted = parser.hasRentPeriodStarted; - this._creationDay = parser.creationDay; - this._creationMonth = parser.creationMonth; - this._creationYear = parser.creationYear; - this._slotId = parser.slotId; - this._songId = parser.songId; - this._flatId = parser.flatId; - this._isRented = parser.rentable; - this._isWallItem = parser.isWallItem; - } - - public clone(): FurnitureItem - { - const item = new FurnitureItem(null); - - item._expirationTimeStamp = this._expirationTimeStamp; - item._isWallItem = this._isWallItem; - item._songId = this._songId; - item._locked = this._locked; - item._id = this._id; - item._ref = this._ref; - item._category = this._category; - item._type = this._type; - item._stuffData = this._stuffData; - item._extra = this._extra; - item._recyclable = this._recyclable; - item._tradeable = this._tradeable; - item._groupable = this._groupable; - item._sellable = this._sellable; - item._secondsToExpiration = this._secondsToExpiration; - item._hasRentPeriodStarted = this._hasRentPeriodStarted; - item._creationDay = this._creationDay; - item._creationMonth = this._creationMonth; - item._creationYear = this._creationYear; - item._slotId = this._slotId; - item._isRented = this._isRented; - item._flatId = this._flatId; - - return item; - } -} diff --git a/src/api/inventory/FurnitureUtilities.ts b/src/api/inventory/FurnitureUtilities.ts deleted file mode 100644 index 1c12803..0000000 --- a/src/api/inventory/FurnitureUtilities.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { FurnitureListItemParser, GetRoomEngine, IObjectData } from '@nitrots/nitro-renderer'; -import { FurniCategory } from './FurniCategory'; -import { FurnitureItem } from './FurnitureItem'; -import { GroupItem } from './GroupItem'; - -export const createGroupItem = (type: number, category: number, stuffData: IObjectData, extra: number = NaN) => new GroupItem(type, category, GetRoomEngine(), stuffData, extra); - -const addSingleFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) => -{ - const groupItems: GroupItem[] = []; - - for(const groupItem of set) - { - if(groupItem.type === item.type) groupItems.push(groupItem); - } - - for(const groupItem of groupItems) - { - if(groupItem.getItemById(item.id)) return groupItem; - } - - const groupItem = createGroupItem(item.type, item.category, item.stuffData, item.extra); - - groupItem.push(item); - - if(unseen) - { - groupItem.hasUnseenItems = true; - - set.unshift(groupItem); - } - else - { - set.push(groupItem); - } - - return groupItem; -} - -const addGroupableFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) => -{ - let existingGroup: GroupItem = null; - - for(const groupItem of set) - { - if((groupItem.type === item.type) && (groupItem.isWallItem === item.isWallItem) && groupItem.isGroupable) - { - if(item.category === FurniCategory.POSTER) - { - if(groupItem.stuffData.getLegacyString() === item.stuffData.getLegacyString()) - { - existingGroup = groupItem; - - break; - } - } - - else if(item.category === FurniCategory.GUILD_FURNI) - { - if(item.stuffData.compare(groupItem.stuffData)) - { - existingGroup = groupItem; - - break; - } - } - - else - { - existingGroup = groupItem; - - break; - } - } - } - - if(existingGroup) - { - existingGroup.push(item); - - if(unseen) - { - existingGroup.hasUnseenItems = true; - - const index = set.indexOf(existingGroup); - - if(index >= 0) set.splice(index, 1); - - set.unshift(existingGroup); - } - - return existingGroup; - } - - existingGroup = createGroupItem(item.type, item.category, item.stuffData, item.extra); - - existingGroup.push(item); - - if(unseen) - { - existingGroup.hasUnseenItems = true; - - set.unshift(existingGroup); - } - else - { - set.push(existingGroup); - } - - return existingGroup; -} - -export const addFurnitureItem = (set: GroupItem[], item: FurnitureItem, unseen: boolean) => -{ - if(!item.isGroupable) - { - addSingleFurnitureItem(set, item, unseen); - } - else - { - addGroupableFurnitureItem(set, item, unseen); - } -} - -export const mergeFurniFragments = (fragment: Map, totalFragments: number, fragmentNumber: number, fragments: Map[]) => -{ - if(totalFragments === 1) return fragment; - - fragments[fragmentNumber] = fragment; - - for(const frag of fragments) - { - if(!frag) return null; - } - - const merged: Map = new Map(); - - for(const frag of fragments) - { - for(const [ key, value ] of frag) merged.set(key, value); - - frag.clear(); - } - - fragments = null; - - return merged; -} - -export const getAllItemIds = (groupItems: GroupItem[]) => -{ - const itemIds: number[] = []; - - for(const groupItem of groupItems) - { - let totalCount = groupItem.getTotalCount(); - - if(groupItem.category === FurniCategory.POST_IT) totalCount = 1; - - let i = 0; - - while(i < totalCount) - { - itemIds.push(groupItem.getItemByIndex(i).id); - - i++; - } - } - - return itemIds; -} diff --git a/src/api/inventory/GroupItem.ts b/src/api/inventory/GroupItem.ts deleted file mode 100644 index 8569321..0000000 --- a/src/api/inventory/GroupItem.ts +++ /dev/null @@ -1,461 +0,0 @@ -import { IObjectData, IRoomEngine } from '@nitrots/nitro-renderer'; -import { LocalizeText } from '../utils'; -import { FurniCategory } from './FurniCategory'; -import { FurnitureItem } from './FurnitureItem'; -import { IFurnitureItem } from './IFurnitureItem'; - -export class GroupItem -{ - private _type: number; - private _category: number; - private _roomEngine: IRoomEngine; - private _stuffData: IObjectData; - private _extra: number; - private _isWallItem: boolean; - private _iconUrl: string; - private _name: string; - private _description: string; - private _locked: boolean; - private _selected: boolean; - private _hasUnseenItems: boolean; - private _items: FurnitureItem[]; - - constructor(type: number = -1, category: number = -1, roomEngine: IRoomEngine = null, stuffData: IObjectData = null, extra: number = -1) - { - this._type = type; - this._category = category; - this._roomEngine = roomEngine; - this._stuffData = stuffData; - this._extra = extra; - this._isWallItem = false; - this._iconUrl = null; - this._name = null; - this._description = null; - this._locked = false; - this._selected = false; - this._hasUnseenItems = false; - this._items = []; - } - - public clone(): GroupItem - { - const groupItem = new GroupItem(); - - groupItem._type = this._type; - groupItem._category = this._category; - groupItem._roomEngine = this._roomEngine; - groupItem._stuffData = this._stuffData; - groupItem._extra = this._extra; - groupItem._isWallItem = this._isWallItem; - groupItem._iconUrl = this._iconUrl; - groupItem._name = this._name; - groupItem._description = this._description; - groupItem._locked = this._locked; - groupItem._selected = this._selected; - groupItem._hasUnseenItems = this._hasUnseenItems; - groupItem._items = this._items; - - return groupItem; - } - - public prepareGroup(): void - { - this.setIcon(); - this.setName(); - this.setDescription(); - } - - public dispose(): void - { - - } - - public getItemByIndex(index: number): FurnitureItem - { - return this._items[index]; - } - - public getItemById(id: number): FurnitureItem - { - for(const item of this._items) - { - if(item.id !== id) continue; - - return item; - } - - return null; - } - - public getTradeItems(count: number): IFurnitureItem[] - { - const items: IFurnitureItem[] = []; - - const furnitureItem = this.getLastItem(); - - if(!furnitureItem) return items; - - let found = 0; - let i = 0; - - while(i < this._items.length) - { - if(found >= count) break; - - const item = this.getItemByIndex(i); - - if(!item.locked && item.isTradable && (item.type === furnitureItem.type)) - { - items.push(item); - - found++; - } - - i++; - } - - return items; - } - - public push(item: FurnitureItem): void - { - const items = [ ...this._items ]; - - let index = 0; - - while(index < items.length) - { - let existingItem = items[index]; - - if(existingItem.id === item.id) - { - existingItem = existingItem.clone(); - - existingItem.locked = false; - - items.splice(index, 1); - - items.push(existingItem); - - this._items = items; - - return; - } - - index++; - } - - items.push(item); - - this._items = items; - - if(this._items.length === 1) this.prepareGroup(); - } - - public pop(): FurnitureItem - { - const items = [ ...this._items ]; - - let item: FurnitureItem = null; - - if(items.length > 0) - { - const index = (items.length - 1); - - item = items[index]; - - items.splice(index, 1); - } - - this._items = items; - - return item; - } - - public remove(k: number): FurnitureItem - { - const items = [ ...this._items ]; - - let index = 0; - - while(index < items.length) - { - let existingItem = items[index]; - - if(existingItem.id === k) - { - items.splice(index, 1); - - this._items = items; - - return existingItem; - } - - index++; - } - - return null; - } - - public getTotalCount(): number - { - if(this._category === FurniCategory.POST_IT) - { - let count = 0; - let index = 0; - - while(index < this._items.length) - { - const item = this.getItemByIndex(index); - - count = (count + parseInt(item.stuffData.getLegacyString())); - - index++; - } - - return count; - } - - return this._items.length; - } - - public getUnlockedCount(): number - { - if(this.category === FurniCategory.POST_IT) return this.getTotalCount(); - - let count = 0; - let index = 0; - - while(index < this._items.length) - { - const item = this.getItemByIndex(index); - - if(!item.locked) count++; - - index++; - } - - return count; - } - - public getLastItem(): FurnitureItem - { - if(!this._items.length) return null; - - const item = this.getItemByIndex((this._items.length - 1)); - - return item; - } - - public unlockAllItems(): void - { - const items = [ ...this._items ]; - - let index = 0; - - while(index < items.length) - { - const item = items[index]; - - if(item.locked) - { - const newItem = item.clone(); - - newItem.locked = false; - - items[index] = newItem; - } - - index++; - } - - this._items = items; - } - - public lockItemIds(itemIds: number[]): boolean - { - const items = [ ...this._items ]; - - let index = 0; - let updated = false; - - while(index < items.length) - { - const item = items[index]; - const locked = (itemIds.indexOf(item.ref) >= 0); - - if(item.locked !== locked) - { - updated = true; - - const newItem = item.clone(); - - newItem.locked = locked; - - items[index] = newItem; - } - - index++; - } - - this._items = items; - - return updated; - } - - private setName(): void - { - const k = this.getLastItem(); - - if(!k) - { - this._name = ''; - - return; - } - - let key = ''; - - switch(this._category) - { - case FurniCategory.POSTER: - key = (('poster_' + k.stuffData.getLegacyString()) + '_name'); - break; - case FurniCategory.TRAX_SONG: - this._name = 'SONG_NAME'; - return; - default: - if(this.isWallItem) - { - key = ('wallItem.name.' + k.type); - } - else - { - key = ('roomItem.name.' + k.type); - } - } - - this._name = LocalizeText(key); - } - - private setDescription(): void - { - this._description = ''; - } - - private setIcon(): void - { - if(this._iconUrl) return; - - let url = null; - - if(this.isWallItem) - { - url = this._roomEngine.getFurnitureWallIconUrl(this._type, this._stuffData.getLegacyString()); - } - else - { - url = this._roomEngine.getFurnitureFloorIconUrl(this._type); - } - - if(!url) return; - - this._iconUrl = url; - } - - public get type(): number - { - return this._type; - } - - public get category(): number - { - return this._category; - } - - public get stuffData(): IObjectData - { - return this._stuffData; - } - - public get extra(): number - { - return this._extra; - } - - public get iconUrl(): string - { - return this._iconUrl; - } - - public get name(): string - { - return this._name; - } - - public get description(): string - { - return this._description; - } - - public get hasUnseenItems(): boolean - { - return this._hasUnseenItems; - } - - public set hasUnseenItems(flag: boolean) - { - this._hasUnseenItems = flag; - } - - public get locked(): boolean - { - return this._locked; - } - - public set locked(flag: boolean) - { - this._locked = flag; - } - - public get selected(): boolean - { - return this._selected; - } - - public set selected(flag: boolean) - { - this._selected = flag; - } - - public get isWallItem(): boolean - { - const item = this.getItemByIndex(0); - - return (item ? item.isWallItem : false); - } - - public get isGroupable(): boolean - { - const item = this.getItemByIndex(0); - - return (item ? item.isGroupable : false); - } - - public get isSellable(): boolean - { - const item = this.getItemByIndex(0); - - return (item ? item.sellable : false); - } - - public get items(): FurnitureItem[] - { - return this._items; - } - - public set items(items: FurnitureItem[]) - { - this._items = items; - } -} diff --git a/src/api/inventory/IBotItem.ts b/src/api/inventory/IBotItem.ts deleted file mode 100644 index 0a370ba..0000000 --- a/src/api/inventory/IBotItem.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { BotData } from '@nitrots/nitro-renderer'; - -export interface IBotItem -{ - botData: BotData; -} diff --git a/src/api/inventory/IFurnitureItem.ts b/src/api/inventory/IFurnitureItem.ts deleted file mode 100644 index 435597d..0000000 --- a/src/api/inventory/IFurnitureItem.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { IObjectData } from '@nitrots/nitro-renderer'; - -export interface IFurnitureItem -{ - id: number; - ref: number; - type: number; - stuffData: IObjectData; - extra: number; - category: number; - recyclable: boolean; - isTradable: boolean; - isGroupable: boolean; - sellable: boolean; - locked: boolean; - isWallItem: boolean; -} diff --git a/src/api/inventory/IPetItem.ts b/src/api/inventory/IPetItem.ts deleted file mode 100644 index 910d5df..0000000 --- a/src/api/inventory/IPetItem.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { PetData } from '@nitrots/nitro-renderer'; - -export interface IPetItem -{ - petData: PetData; -} diff --git a/src/api/inventory/IUnseenItemTracker.ts b/src/api/inventory/IUnseenItemTracker.ts deleted file mode 100644 index 8a70a16..0000000 --- a/src/api/inventory/IUnseenItemTracker.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface IUnseenItemTracker -{ - dispose(): void; - resetCategory(category: number): boolean; - resetItems(category: number, itemIds: number[]): boolean; - isUnseen(category: number, itemId: number): boolean; - removeUnseen(category: number, itemId: number): boolean; - getIds(category: number): number[]; - getCount(category: number): number; - getFullCount(): number; - addItems(category: number, itemIds: number[]): void; -} diff --git a/src/api/inventory/InventoryUtilities.ts b/src/api/inventory/InventoryUtilities.ts deleted file mode 100644 index c383e07..0000000 --- a/src/api/inventory/InventoryUtilities.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { CreateLinkEvent, FurniturePlacePaintComposer, GetRoomEngine, GetRoomSessionManager, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType } from '@nitrots/nitro-renderer'; -import { SendMessageComposer } from '../nitro'; -import { FurniCategory } from './FurniCategory'; -import { GroupItem } from './GroupItem'; -import { IBotItem } from './IBotItem'; -import { IPetItem } from './IPetItem'; - -let objectMoverRequested = false; -let itemIdInPlacing = -1; - -export const isObjectMoverRequested = () => objectMoverRequested; - -export const setObjectMoverRequested = (flag: boolean) => objectMoverRequested = flag; - -export const getPlacingItemId = () => itemIdInPlacing; - -export const setPlacingItemId = (id: number) => (itemIdInPlacing = id); - -export const cancelRoomObjectPlacement = () => -{ - if(getPlacingItemId() === -1) return; - - GetRoomEngine().cancelRoomObjectPlacement(); - - setPlacingItemId(-1); - setObjectMoverRequested(false); -} - -export const attemptPetPlacement = (petItem: IPetItem, flag: boolean = false) => -{ - const petData = petItem.petData; - - if(!petData) return false; - - const session = GetRoomSessionManager().getSession(1); - - if(!session) return false; - - if(!session.isRoomOwner && !session.allowPets) return false; - - CreateLinkEvent('inventory/hide'); - - if(GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.INVENTORY, -(petData.id), RoomObjectCategory.UNIT, RoomObjectType.PET, petData.figureData.figuredata)) - { - setPlacingItemId(petData.id); - setObjectMoverRequested(true); - } - - return true; -} - -export const attemptItemPlacement = (groupItem: GroupItem, flag: boolean = false) => -{ - if(!groupItem || !groupItem.getUnlockedCount()) return false; - - const item = groupItem.getLastItem(); - - if(!item) return false; - - if((item.category === FurniCategory.FLOOR) || (item.category === FurniCategory.WALL_PAPER) || (item.category === FurniCategory.LANDSCAPE)) - { - if(flag) return false; - - SendMessageComposer(new FurniturePlacePaintComposer(item.id)); - - return false; - } - else - { - CreateLinkEvent('inventory/hide'); - - let category = 0; - let isMoving = false; - - if(item.isWallItem) category = RoomObjectCategory.WALL; - else category = RoomObjectCategory.FLOOR; - - if((item.category === FurniCategory.POSTER)) // or external image from furnidata - { - isMoving = GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.INVENTORY, item.id, category, item.type, item.stuffData.getLegacyString()); - } - else - { - isMoving = GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.INVENTORY, item.id, category, item.type, item.extra.toString(), item.stuffData); - } - - if(isMoving) - { - setPlacingItemId(item.ref); - setObjectMoverRequested(true); - } - } - - return true; -} - - -export const attemptBotPlacement = (botItem: IBotItem, flag: boolean = false) => -{ - const botData = botItem.botData; - - if(!botData) return false; - - const session = GetRoomSessionManager().getSession(1); - - if(!session || !session.isRoomOwner) return false; - - CreateLinkEvent('inventory/hide'); - - if(GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.INVENTORY, -(botData.id), RoomObjectCategory.UNIT, RoomObjectType.RENTABLE_BOT, botData.figure)) - { - setPlacingItemId(botData.id); - setObjectMoverRequested(true); - } - - return true; -} diff --git a/src/api/inventory/PetUtilities.ts b/src/api/inventory/PetUtilities.ts deleted file mode 100644 index bee286a..0000000 --- a/src/api/inventory/PetUtilities.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { CreateLinkEvent, PetData } from '@nitrots/nitro-renderer'; -import { IPetItem } from './IPetItem'; -import { cancelRoomObjectPlacement, getPlacingItemId } from './InventoryUtilities'; -import { UnseenItemCategory } from './UnseenItemCategory'; - -export const getAllPetIds = (petItems: IPetItem[]) => petItems.map(item => item.petData.id); - -export const addSinglePetItem = (petData: PetData, set: IPetItem[], unseen: boolean = true) => -{ - const petItem = { petData }; - - if(unseen) - { - //petItem.isUnseen = true; - - set.unshift(petItem); - } - else - { - set.push(petItem); - } - - return petItem; -} - -export const removePetItemById = (id: number, set: IPetItem[]) => -{ - let index = 0; - - while(index < set.length) - { - const petItem = set[index]; - - if(petItem && (petItem.petData.id === id)) - { - if(getPlacingItemId() === petItem.petData.id) - { - cancelRoomObjectPlacement(); - - CreateLinkEvent('inventory/open'); - } - - set.splice(index, 1); - - return petItem; - } - - index++; - } - - return null; -} - -export const processPetFragment = (set: IPetItem[], fragment: Map, isUnseen: (category: number, itemId: number) => boolean) => -{ - const existingIds = getAllPetIds(set); - const addedIds: number[] = []; - const removedIds: number[] = []; - - for(const key of fragment.keys()) (existingIds.indexOf(key) === -1) && addedIds.push(key); - - for(const itemId of existingIds) (!fragment.get(itemId)) && removedIds.push(itemId); - - const emptyExistingSet = (existingIds.length === 0); - - for(const id of removedIds) removePetItemById(id, set); - - for(const id of addedIds) - { - const parser = fragment.get(id); - - if(!parser) continue; - - addSinglePetItem(parser, set, isUnseen(UnseenItemCategory.PET, parser.id)); - } - - return set; -} - -export const mergePetFragments = (fragment: Map, totalFragments: number, fragmentNumber: number, fragments: Map[]) => -{ - if(totalFragments === 1) return fragment; - - fragments[fragmentNumber] = fragment; - - for(const frag of fragments) - { - if(!frag) return null; - } - - const merged: Map = new Map(); - - for(const frag of fragments) - { - for(const [ key, value ] of frag) merged.set(key, value); - - frag.clear(); - } - - fragments = null; - - return merged; -} diff --git a/src/api/inventory/TradeState.ts b/src/api/inventory/TradeState.ts deleted file mode 100644 index 3df418b..0000000 --- a/src/api/inventory/TradeState.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class TradeState -{ - public static TRADING_STATE_READY: number = 0; - public static TRADING_STATE_RUNNING: number = 1; - public static TRADING_STATE_COUNTDOWN: number = 2; - public static TRADING_STATE_CONFIRMING: number = 3; - public static TRADING_STATE_CONFIRMED: number = 4; - public static TRADING_STATE_COMPLETED: number = 5; - public static TRADING_STATE_CANCELLED: number = 6; -} diff --git a/src/api/inventory/TradeUserData.ts b/src/api/inventory/TradeUserData.ts deleted file mode 100644 index 452c7ee..0000000 --- a/src/api/inventory/TradeUserData.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { AdvancedMap } from '@nitrots/nitro-renderer'; -import { GroupItem } from './GroupItem'; - -export class TradeUserData -{ - constructor( - public userId: number = -1, - public userName: string = '', - public userItems: AdvancedMap = new AdvancedMap(), - public itemCount: number = 0, - public creditsCount: number = 0, - public accepts: boolean = false, - public canTrade: boolean = false) - {} -} diff --git a/src/api/inventory/TradingNotificationType.ts b/src/api/inventory/TradingNotificationType.ts deleted file mode 100644 index 4aed490..0000000 --- a/src/api/inventory/TradingNotificationType.ts +++ /dev/null @@ -1,12 +0,0 @@ -export class TradingNotificationType -{ - public static ALERT_SCAM: number = 0; - public static HOTEL_TRADING_DISABLED = 1; - public static YOU_NOT_ALLOWED: number = 2; - public static THEY_NOT_ALLOWED: number = 4; - public static ROOM_DISABLED: number = 6; - public static YOU_OPEN: number = 7; - public static THEY_OPEN: number = 8; - public static ERROR_WHILE_COMMIT: number = 9; - public static THEY_CANCELLED: number = 10; -} diff --git a/src/api/inventory/TradingUtilities.ts b/src/api/inventory/TradingUtilities.ts deleted file mode 100644 index cd18fba..0000000 --- a/src/api/inventory/TradingUtilities.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { AdvancedMap, GetSessionDataManager, IObjectData, ItemDataStructure, StringDataType } from '@nitrots/nitro-renderer'; -import { FurniCategory } from './FurniCategory'; -import { FurnitureItem } from './FurnitureItem'; -import { createGroupItem } from './FurnitureUtilities'; -import { GroupItem } from './GroupItem'; - -const isExternalImage = (spriteId: number) => GetSessionDataManager().getWallItemData(spriteId)?.isExternalImage || false; - -export const parseTradeItems = (items: ItemDataStructure[]) => -{ - const existingItems = new AdvancedMap(); - const totalItems = items.length; - - if(totalItems) - { - for(const item of items) - { - const spriteId = item.spriteId; - const category = item.category; - - let name = (item.furniType + spriteId); - - if(!item.isGroupable || isExternalImage(spriteId)) - { - name = ('itemid' + item.itemId); - } - - if(item.category === FurniCategory.POSTER) - { - name = (item.itemId + 'poster' + item.stuffData.getLegacyString()); - } - - else if(item.category === FurniCategory.GUILD_FURNI) - { - name = ''; - } - - let groupItem = ((item.isGroupable && !isExternalImage(item.spriteId)) ? existingItems.getValue(name) : null); - - if(!groupItem) - { - groupItem = createGroupItem(spriteId, category, item.stuffData); - - existingItems.add(name, groupItem); - } - - groupItem.push(new FurnitureItem(item)); - } - } - - return existingItems; -} - -export const getGuildFurniType = (spriteId: number, stuffData: IObjectData) => -{ - let type = spriteId.toString(); - - if(!(stuffData instanceof StringDataType)) return type; - - let i = 1; - - while(i < 5) - { - type = (type + (',' + stuffData.getValue(i))); - - i++; - } - - return type; -} diff --git a/src/api/inventory/UnseenItemCategory.ts b/src/api/inventory/UnseenItemCategory.ts deleted file mode 100644 index cbd7e9b..0000000 --- a/src/api/inventory/UnseenItemCategory.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class UnseenItemCategory -{ - public static FURNI: number = 1; - public static RENTABLE: number = 2; - public static PET: number = 3; - public static BADGE: number = 4; - public static BOT: number = 5; - public static GAMES: number = 6; -} diff --git a/src/api/inventory/index.ts b/src/api/inventory/index.ts deleted file mode 100644 index 6a245d7..0000000 --- a/src/api/inventory/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -export * from './FurniCategory'; -export * from './FurnitureItem'; -export * from './FurnitureUtilities'; -export * from './GroupItem'; -export * from './IBotItem'; -export * from './IFurnitureItem'; -export * from './IPetItem'; -export * from './IUnseenItemTracker'; -export * from './InventoryUtilities'; -export * from './PetUtilities'; -export * from './TradeState'; -export * from './TradeUserData'; -export * from './TradingNotificationType'; -export * from './TradingUtilities'; -export * from './UnseenItemCategory'; diff --git a/src/api/mod-tools/GetIssueCategoryName.ts b/src/api/mod-tools/GetIssueCategoryName.ts deleted file mode 100644 index 81a3f86..0000000 --- a/src/api/mod-tools/GetIssueCategoryName.ts +++ /dev/null @@ -1,35 +0,0 @@ -export const GetIssueCategoryName = (categoryId: number) => -{ - switch(categoryId) - { - case 1: - case 2: - return 'Normal'; - case 3: - return 'Automatic'; - case 4: - return 'Automatic IM'; - case 5: - return 'Guide System'; - case 6: - return 'IM'; - case 7: - return 'Room'; - case 8: - return 'Panic'; - case 9: - return 'Guardian'; - case 10: - return 'Automatic Helper'; - case 11: - return 'Discussion'; - case 12: - return 'Selfie'; - case 14: - return 'Photo'; - case 15: - return 'Ambassador'; - } - - return 'Unknown'; -} diff --git a/src/api/mod-tools/ISelectedUser.ts b/src/api/mod-tools/ISelectedUser.ts deleted file mode 100644 index 4f6e76b..0000000 --- a/src/api/mod-tools/ISelectedUser.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface ISelectedUser -{ - userId: number; - username: string; -} diff --git a/src/api/mod-tools/IUserInfo.ts b/src/api/mod-tools/IUserInfo.ts deleted file mode 100644 index 8d49aa7..0000000 --- a/src/api/mod-tools/IUserInfo.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface IUserInfo -{ - nameKey: string; - nameKeyFallback: string; - value: string; -} diff --git a/src/api/mod-tools/ModActionDefinition.ts b/src/api/mod-tools/ModActionDefinition.ts deleted file mode 100644 index b28aa9c..0000000 --- a/src/api/mod-tools/ModActionDefinition.ts +++ /dev/null @@ -1,49 +0,0 @@ -export class ModActionDefinition -{ - public static ALERT: number = 1; - public static MUTE: number = 2; - public static BAN: number = 3; - public static KICK: number = 4; - public static TRADE_LOCK: number = 5; - public static MESSAGE: number = 6; - - private readonly _actionId: number; - private readonly _name: string; - private readonly _actionType: number; - private readonly _sanctionTypeId: number; - private readonly _actionLengthHours: number; - - constructor(actionId: number, actionName: string, actionType: number, sanctionTypeId: number, actionLengthHours:number) - { - this._actionId = actionId; - this._name = actionName; - this._actionType = actionType; - this._sanctionTypeId = sanctionTypeId; - this._actionLengthHours = actionLengthHours; - } - - public get actionId(): number - { - return this._actionId; - } - - public get name(): string - { - return this._name; - } - - public get actionType(): number - { - return this._actionType; - } - - public get sanctionTypeId(): number - { - return this._sanctionTypeId; - } - - public get actionLengthHours(): number - { - return this._actionLengthHours; - } -} diff --git a/src/api/mod-tools/index.ts b/src/api/mod-tools/index.ts deleted file mode 100644 index 004bbaa..0000000 --- a/src/api/mod-tools/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './GetIssueCategoryName'; -export * from './ISelectedUser'; -export * from './IUserInfo'; -export * from './ModActionDefinition'; diff --git a/src/api/navigator/DoorStateType.ts b/src/api/navigator/DoorStateType.ts deleted file mode 100644 index 1f8a8ef..0000000 --- a/src/api/navigator/DoorStateType.ts +++ /dev/null @@ -1,12 +0,0 @@ -export class DoorStateType -{ - public static NONE: number = 0; - public static START_DOORBELL: number = 1; - public static START_PASSWORD: number = 2; - public static STATE_PENDING_SERVER: number = 3; - public static UPDATE_STATE: number = 4; - public static STATE_WAITING: number = 5; - public static STATE_NO_ANSWER: number = 6; - public static STATE_WRONG_PASSWORD: number = 7; - public static STATE_ACCEPTED: number = 8; -} diff --git a/src/api/navigator/INavigatorData.ts b/src/api/navigator/INavigatorData.ts deleted file mode 100644 index e50b6fe..0000000 --- a/src/api/navigator/INavigatorData.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { RoomDataParser } from '@nitrots/nitro-renderer'; - -export interface INavigatorData -{ - homeRoomId: number; - settingsReceived: boolean; - enteredGuestRoom: RoomDataParser; - currentRoomOwner: boolean; - currentRoomId: number; - currentRoomIsStaffPick: boolean; - createdFlatId: number; - avatarId: number; - roomPicker: boolean; - eventMod: boolean; - currentRoomRating: number; - canRate: boolean; -} diff --git a/src/api/navigator/INavigatorSearchFilter.ts b/src/api/navigator/INavigatorSearchFilter.ts deleted file mode 100644 index 179d5d5..0000000 --- a/src/api/navigator/INavigatorSearchFilter.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface INavigatorSearchFilter -{ - name: string; - query: string; -} diff --git a/src/api/navigator/IRoomChatSettings.ts b/src/api/navigator/IRoomChatSettings.ts deleted file mode 100644 index aee426c..0000000 --- a/src/api/navigator/IRoomChatSettings.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface IRoomChatSettings -{ - mode: number; - weight: number; - speed: number; - distance: number; - protection: number; -} diff --git a/src/api/navigator/IRoomData.ts b/src/api/navigator/IRoomData.ts deleted file mode 100644 index 9146314..0000000 --- a/src/api/navigator/IRoomData.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { IRoomChatSettings } from './IRoomChatSettings'; -import { IRoomModerationSettings } from './IRoomModerationSettings'; - -export interface IRoomData -{ - roomId: number; - roomName: string; - roomDescription: string; - categoryId: number; - userCount: number; - tags: string[]; - tradeState: number; - allowWalkthrough: boolean; - lockState: number; - password: string; - allowPets: boolean; - allowPetsEat: boolean; - hideWalls: boolean; - wallThickness: number; - floorThickness: number; - chatSettings: IRoomChatSettings; - moderationSettings: IRoomModerationSettings; -} diff --git a/src/api/navigator/IRoomModel.ts b/src/api/navigator/IRoomModel.ts deleted file mode 100644 index 73dfe27..0000000 --- a/src/api/navigator/IRoomModel.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface IRoomModel -{ - clubLevel: number; - tileSize: number; - name: string; -} diff --git a/src/api/navigator/IRoomModerationSettings.ts b/src/api/navigator/IRoomModerationSettings.ts deleted file mode 100644 index 266fe47..0000000 --- a/src/api/navigator/IRoomModerationSettings.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface IRoomModerationSettings -{ - allowMute: number; - allowKick: number; - allowBan: number; -} diff --git a/src/api/navigator/NavigatorSearchResultViewDisplayMode.ts b/src/api/navigator/NavigatorSearchResultViewDisplayMode.ts deleted file mode 100644 index b532d1a..0000000 --- a/src/api/navigator/NavigatorSearchResultViewDisplayMode.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class NavigatorSearchResultViewDisplayMode -{ - public static readonly LIST: number = 0; - public static readonly THUMBNAILS: number = 1; - public static readonly FORCED_THUMBNAILS: number = 2; -} diff --git a/src/api/navigator/RoomInfoData.ts b/src/api/navigator/RoomInfoData.ts deleted file mode 100644 index fc0a93b..0000000 --- a/src/api/navigator/RoomInfoData.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { RoomDataParser } from '@nitrots/nitro-renderer'; - -export class RoomInfoData -{ - private _enteredGuestRoom: RoomDataParser = null; - private _createdRoomId: number = 0; - private _currentRoomId: number = 0; - private _currentRoomOwner: boolean = false; - private _canRate: boolean = false; - - public get enteredGuestRoom(): RoomDataParser - { - return this._enteredGuestRoom; - } - - public set enteredGuestRoom(data: RoomDataParser) - { - this._enteredGuestRoom = data; - } - - public get createdRoomId(): number - { - return this._createdRoomId; - } - - public set createdRoomId(id: number) - { - this._createdRoomId = id; - } - - public get currentRoomId(): number - { - return this._currentRoomId; - } - - public set currentRoomId(id: number) - { - this._currentRoomId = id; - } - - public get currentRoomOwner(): boolean - { - return this._currentRoomOwner; - } - - public set currentRoomOwner(flag: boolean) - { - this._currentRoomOwner = flag; - } - - public get canRate(): boolean - { - return this._canRate; - } - - public set canRate(flag: boolean) - { - this._canRate = flag; - } -} diff --git a/src/api/navigator/RoomSettingsUtils.ts b/src/api/navigator/RoomSettingsUtils.ts deleted file mode 100644 index bc611da..0000000 --- a/src/api/navigator/RoomSettingsUtils.ts +++ /dev/null @@ -1,10 +0,0 @@ -const BuildMaxVisitorsList = () => -{ - const list: number[] = []; - - for(let i = 10; i <= 100; i = i + 10) list.push(i); - - return list; -} - -export const GetMaxVisitorsList = BuildMaxVisitorsList(); diff --git a/src/api/navigator/SearchFilterOptions.ts b/src/api/navigator/SearchFilterOptions.ts deleted file mode 100644 index aaf1290..0000000 --- a/src/api/navigator/SearchFilterOptions.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { INavigatorSearchFilter } from './INavigatorSearchFilter'; - -export const SearchFilterOptions: INavigatorSearchFilter[] = [ - { - name: 'anything', - query: null - }, - { - name: 'room.name', - query: 'roomname' - }, - { - name: 'owner', - query: 'owner' - }, - { - name: 'tag', - query: 'tag' - }, - { - name: 'group', - query: 'group' - } -]; diff --git a/src/api/navigator/TryVisitRoom.ts b/src/api/navigator/TryVisitRoom.ts deleted file mode 100644 index 81138d6..0000000 --- a/src/api/navigator/TryVisitRoom.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { GetGuestRoomMessageComposer } from '@nitrots/nitro-renderer'; -import { SendMessageComposer } from '../nitro'; - -export function TryVisitRoom(roomId: number): void -{ - SendMessageComposer(new GetGuestRoomMessageComposer(roomId, false, true)); -} diff --git a/src/api/navigator/index.ts b/src/api/navigator/index.ts deleted file mode 100644 index bceb33e..0000000 --- a/src/api/navigator/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -export * from './DoorStateType'; -export * from './INavigatorData'; -export * from './INavigatorSearchFilter'; -export * from './IRoomChatSettings'; -export * from './IRoomData'; -export * from './IRoomModel'; -export * from './IRoomModerationSettings'; -export * from './NavigatorSearchResultViewDisplayMode'; -export * from './RoomInfoData'; -export * from './RoomSettingsUtils'; -export * from './SearchFilterOptions'; -export * from './TryVisitRoom'; diff --git a/src/api/nitro/GetConfigurationValue.ts b/src/api/nitro/GetConfigurationValue.ts deleted file mode 100644 index 4438444..0000000 --- a/src/api/nitro/GetConfigurationValue.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GetConfiguration } from '@nitrots/nitro-renderer'; - -export function GetConfigurationValue(key: string, value: T = null): T -{ - return GetConfiguration().getValue(key, value); -} diff --git a/src/api/nitro/OpenUrl.ts b/src/api/nitro/OpenUrl.ts deleted file mode 100644 index 0329c00..0000000 --- a/src/api/nitro/OpenUrl.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { CreateLinkEvent, HabboWebTools } from '@nitrots/nitro-renderer'; - -export const OpenUrl = (url: string) => -{ - if(!url || !url.length) return; - - if(url.startsWith('http')) - { - HabboWebTools.openWebPage(url); - } - else - { - CreateLinkEvent(url); - } -} diff --git a/src/api/nitro/SendMessageComposer.ts b/src/api/nitro/SendMessageComposer.ts deleted file mode 100644 index 4229c28..0000000 --- a/src/api/nitro/SendMessageComposer.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { GetCommunication, IMessageComposer } from '@nitrots/nitro-renderer'; - -export const SendMessageComposer = (event: IMessageComposer) => GetCommunication().connection.send(event); diff --git a/src/api/nitro/index.ts b/src/api/nitro/index.ts deleted file mode 100644 index 11b9d02..0000000 --- a/src/api/nitro/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './GetConfigurationValue'; -export * from './OpenUrl'; -export * from './SendMessageComposer'; -export * from './room'; -export * from './session'; diff --git a/src/api/nitro/room/DispatchMouseEvent.ts b/src/api/nitro/room/DispatchMouseEvent.ts deleted file mode 100644 index c28e5e4..0000000 --- a/src/api/nitro/room/DispatchMouseEvent.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { GetRoomEngine, MouseEventType } from '@nitrots/nitro-renderer'; - -let didMouseMove = false; -let lastClick = 0; -let clickCount = 0; - -export const DispatchMouseEvent = (event: MouseEvent, canvasId: number = 1) => -{ - const x = event.clientX; - const y = event.clientY; - - let eventType = event.type; - - if(eventType === MouseEventType.MOUSE_CLICK) - { - if(lastClick) - { - clickCount = 1; - - if(lastClick >= Date.now() - 300) clickCount++; - } - - lastClick = Date.now(); - - if(clickCount === 2) - { - if(!didMouseMove) eventType = MouseEventType.DOUBLE_CLICK; - - clickCount = 0; - lastClick = null; - } - } - - switch(eventType) - { - case MouseEventType.MOUSE_CLICK: - break; - case MouseEventType.DOUBLE_CLICK: - break; - case MouseEventType.MOUSE_MOVE: - didMouseMove = true; - break; - case MouseEventType.MOUSE_DOWN: - didMouseMove = false; - break; - case MouseEventType.MOUSE_UP: - break; - case MouseEventType.RIGHT_CLICK: - break; - default: return; - } - - GetRoomEngine().dispatchMouseEvent(canvasId, x, y, eventType, event.altKey, (event.ctrlKey || event.metaKey), event.shiftKey, false); -} diff --git a/src/api/nitro/room/DispatchTouchEvent.ts b/src/api/nitro/room/DispatchTouchEvent.ts deleted file mode 100644 index 0f31bdc..0000000 --- a/src/api/nitro/room/DispatchTouchEvent.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { GetRoomEngine, MouseEventType, TouchEventType } from '@nitrots/nitro-renderer'; - -let didMouseMove = false; -let lastClick = 0; -let clickCount = 0; - -export const DispatchTouchEvent = (event: TouchEvent, canvasId: number = 1, longTouch: boolean = false, altKey: boolean = false, ctrlKey: boolean = false, shiftKey: boolean = false) => -{ - let x = 0; - let y = 0; - - if(event.touches[0]) - { - x = event.touches[0].clientX; - y = event.touches[0].clientY; - } - - else if(event.changedTouches[0]) - { - x = event.changedTouches[0].clientX; - y = event.changedTouches[0].clientY; - } - - let eventType = event.type; - - if(longTouch) eventType = TouchEventType.TOUCH_LONG; - - if(eventType === MouseEventType.MOUSE_CLICK || eventType === TouchEventType.TOUCH_END) - { - eventType = MouseEventType.MOUSE_CLICK; - - if(lastClick) - { - clickCount = 1; - - if(lastClick >= (Date.now() - 300)) clickCount++; - } - - lastClick = Date.now(); - - if(clickCount === 2) - { - if(!didMouseMove) eventType = MouseEventType.DOUBLE_CLICK; - - clickCount = 0; - lastClick = null; - } - } - - switch(eventType) - { - case MouseEventType.MOUSE_CLICK: - break; - case MouseEventType.DOUBLE_CLICK: - break; - case TouchEventType.TOUCH_START: - eventType = MouseEventType.MOUSE_DOWN; - - didMouseMove = false; - break; - case TouchEventType.TOUCH_MOVE: - eventType = MouseEventType.MOUSE_MOVE; - - didMouseMove = true; - break; - case TouchEventType.TOUCH_END: - eventType = MouseEventType.MOUSE_UP; - break; - case TouchEventType.TOUCH_LONG: - eventType = MouseEventType.MOUSE_DOWN_LONG; - break; - default: return; - } - - if (eventType === TouchEventType.TOUCH_START) - { - GetRoomEngine().dispatchMouseEvent(canvasId, x, y, eventType, altKey, ctrlKey, shiftKey, false); - } - - GetRoomEngine().dispatchMouseEvent(canvasId, x, y, eventType, altKey, ctrlKey, shiftKey, false); -} diff --git a/src/api/nitro/room/GetOwnRoomObject.ts b/src/api/nitro/room/GetOwnRoomObject.ts deleted file mode 100644 index aae0b77..0000000 --- a/src/api/nitro/room/GetOwnRoomObject.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, IRoomObjectController, RoomObjectCategory } from '@nitrots/nitro-renderer'; -import { GetRoomSession } from '../session'; - -export function GetOwnRoomObject(): IRoomObjectController -{ - const userId = GetSessionDataManager().userId; - const roomId = GetRoomEngine().activeRoomId; - const category = RoomObjectCategory.UNIT; - const totalObjects = GetRoomEngine().getTotalObjectsForManager(roomId, category); - - let i = 0; - - while(i < totalObjects) - { - const roomObject = GetRoomEngine().getRoomObjectByIndex(roomId, i, category); - - if(roomObject) - { - const userData = GetRoomSession().userDataManager.getUserDataByIndex(roomObject.id); - - if(userData) - { - if(userData.webID === userId) return roomObject; - } - } - - i++; - } - - return null; -} diff --git a/src/api/nitro/room/GetRoomObjectBounds.ts b/src/api/nitro/room/GetRoomObjectBounds.ts deleted file mode 100644 index e32fd25..0000000 --- a/src/api/nitro/room/GetRoomObjectBounds.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { GetRoomEngine } from '@nitrots/nitro-renderer'; - -export const GetRoomObjectBounds = (roomId: number, objectId: number, category: number, canvasId = 1) => -{ - const rectangle = GetRoomEngine().getRoomObjectBoundingRectangle(roomId, objectId, category, canvasId); - - if(!rectangle) return null; - - rectangle.x = Math.round(rectangle.x); - rectangle.y = Math.round(rectangle.y); - - return rectangle; -} diff --git a/src/api/nitro/room/GetRoomObjectScreenLocation.ts b/src/api/nitro/room/GetRoomObjectScreenLocation.ts deleted file mode 100644 index 58cbc92..0000000 --- a/src/api/nitro/room/GetRoomObjectScreenLocation.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { GetRoomEngine } from '@nitrots/nitro-renderer'; - -export const GetRoomObjectScreenLocation = (roomId: number, objectId: number, category: number, canvasId = 1) => -{ - const point = GetRoomEngine().getRoomObjectScreenLocation(roomId, objectId, category, canvasId); - - if(!point) return null; - - point.x = Math.round(point.x); - point.y = Math.round(point.y); - - return point; -} diff --git a/src/api/nitro/room/InitializeRoomInstanceRenderingCanvas.ts b/src/api/nitro/room/InitializeRoomInstanceRenderingCanvas.ts deleted file mode 100644 index 4f3eae5..0000000 --- a/src/api/nitro/room/InitializeRoomInstanceRenderingCanvas.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { GetRoomEngine } from '@nitrots/nitro-renderer'; - -export const InitializeRoomInstanceRenderingCanvas = (width: number, height: number, canvasId: number = 1) => -{ - const roomEngine = GetRoomEngine(); - const roomId = roomEngine.activeRoomId; - - roomEngine.initializeRoomInstanceRenderingCanvas(roomId, canvasId, width, height); -} diff --git a/src/api/nitro/room/IsFurnitureSelectionDisabled.ts b/src/api/nitro/room/IsFurnitureSelectionDisabled.ts deleted file mode 100644 index e86f9a3..0000000 --- a/src/api/nitro/room/IsFurnitureSelectionDisabled.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, RoomEngineObjectEvent, RoomObjectVariable } from '@nitrots/nitro-renderer'; - -export function IsFurnitureSelectionDisabled(event: RoomEngineObjectEvent): boolean -{ - let result = false; - - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(roomObject) - { - const selectionDisabled = (roomObject.model.getValue(RoomObjectVariable.FURNITURE_SELECTION_DISABLED) === 1); - - if(selectionDisabled) - { - result = true; - - if(GetSessionDataManager().isModerator) result = false; - } - } - - return result; -} diff --git a/src/api/nitro/room/ProcessRoomObjectOperation.ts b/src/api/nitro/room/ProcessRoomObjectOperation.ts deleted file mode 100644 index 5a1c997..0000000 --- a/src/api/nitro/room/ProcessRoomObjectOperation.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GetRoomEngine } from '@nitrots/nitro-renderer'; - -export function ProcessRoomObjectOperation(objectId: number, category: number, operation: string): void -{ - GetRoomEngine().processRoomObjectOperation(objectId, category, operation); -} diff --git a/src/api/nitro/room/SetActiveRoomId.ts b/src/api/nitro/room/SetActiveRoomId.ts deleted file mode 100644 index 9446537..0000000 --- a/src/api/nitro/room/SetActiveRoomId.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GetRoomEngine } from '@nitrots/nitro-renderer'; - -export function SetActiveRoomId(roomId: number): void -{ - GetRoomEngine().setActiveRoomId(roomId); -} diff --git a/src/api/nitro/room/index.ts b/src/api/nitro/room/index.ts deleted file mode 100644 index 2af9c28..0000000 --- a/src/api/nitro/room/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export * from './DispatchMouseEvent'; -export * from './DispatchTouchEvent'; -export * from './GetOwnRoomObject'; -export * from './GetRoomObjectBounds'; -export * from './GetRoomObjectScreenLocation'; -export * from './InitializeRoomInstanceRenderingCanvas'; -export * from './IsFurnitureSelectionDisabled'; -export * from './ProcessRoomObjectOperation'; -export * from './SetActiveRoomId'; diff --git a/src/api/nitro/session/CanManipulateFurniture.ts b/src/api/nitro/session/CanManipulateFurniture.ts deleted file mode 100644 index ba89efd..0000000 --- a/src/api/nitro/session/CanManipulateFurniture.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, IRoomSession, RoomControllerLevel } from '@nitrots/nitro-renderer'; -import { IsOwnerOfFurniture } from './IsOwnerOfFurniture'; - -export function CanManipulateFurniture(roomSession: IRoomSession, objectId: number, category: number): boolean -{ - if(!roomSession) return false; - - return (roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator || IsOwnerOfFurniture(GetRoomEngine().getRoomObject(roomSession.roomId, objectId, category))); -} diff --git a/src/api/nitro/session/CreateRoomSession.ts b/src/api/nitro/session/CreateRoomSession.ts deleted file mode 100644 index 3f12bb4..0000000 --- a/src/api/nitro/session/CreateRoomSession.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GetRoomSessionManager } from '@nitrots/nitro-renderer'; - -export function CreateRoomSession(roomId: number, password: string = null): void -{ - GetRoomSessionManager().createSession(roomId, password); -} diff --git a/src/api/nitro/session/GetCanStandUp.ts b/src/api/nitro/session/GetCanStandUp.ts deleted file mode 100644 index 4915d18..0000000 --- a/src/api/nitro/session/GetCanStandUp.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { AvatarAction, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { GetOwnRoomObject } from '../room'; - -export function GetCanStandUp(): string -{ - const roomObject = GetOwnRoomObject(); - - if(!roomObject) return AvatarAction.POSTURE_STAND; - - const model = roomObject.model; - - return model.getValue(RoomObjectVariable.FIGURE_CAN_STAND_UP); -} diff --git a/src/api/nitro/session/GetCanUseExpression.ts b/src/api/nitro/session/GetCanUseExpression.ts deleted file mode 100644 index c7c7367..0000000 --- a/src/api/nitro/session/GetCanUseExpression.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { GetOwnRoomObject } from '../room'; - -export function GetCanUseExpression(): boolean -{ - const roomObject = GetOwnRoomObject(); - - if(!roomObject) return false; - - const model = roomObject.model; - const effectId = model.getValue(RoomObjectVariable.FIGURE_EFFECT); - - return !((effectId === 29) || (effectId === 30) || (effectId === 185)); -} diff --git a/src/api/nitro/session/GetClubMemberLevel.ts b/src/api/nitro/session/GetClubMemberLevel.ts deleted file mode 100644 index 97d4949..0000000 --- a/src/api/nitro/session/GetClubMemberLevel.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { GetSessionDataManager, HabboClubLevelEnum } from '@nitrots/nitro-renderer'; -import { GetConfigurationValue } from '../GetConfigurationValue'; - -export function GetClubMemberLevel(): number -{ - if(GetConfigurationValue('hc.disabled', false)) return HabboClubLevelEnum.VIP; - - return GetSessionDataManager().clubLevel; -} diff --git a/src/api/nitro/session/GetFurnitureData.ts b/src/api/nitro/session/GetFurnitureData.ts deleted file mode 100644 index b7646df..0000000 --- a/src/api/nitro/session/GetFurnitureData.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { GetSessionDataManager, IFurnitureData } from '@nitrots/nitro-renderer'; -import { ProductTypeEnum } from '../../catalog'; - -export function GetFurnitureData(furniClassId: number, productType: string): IFurnitureData -{ - let furniData: IFurnitureData = null; - - switch(productType.toLowerCase()) - { - case ProductTypeEnum.FLOOR: - furniData = GetSessionDataManager().getFloorItemData(furniClassId); - break; - case ProductTypeEnum.WALL: - furniData = GetSessionDataManager().getWallItemData(furniClassId); - break; - } - - return furniData; -} diff --git a/src/api/nitro/session/GetFurnitureDataForProductOffer.ts b/src/api/nitro/session/GetFurnitureDataForProductOffer.ts deleted file mode 100644 index 95a6256..0000000 --- a/src/api/nitro/session/GetFurnitureDataForProductOffer.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { CatalogPageMessageProductData, FurnitureType, GetSessionDataManager, IFurnitureData } from '@nitrots/nitro-renderer'; - -export function GetFurnitureDataForProductOffer(offer: CatalogPageMessageProductData): IFurnitureData -{ - if(!offer) return null; - - let furniData: IFurnitureData = null; - - switch((offer.productType.toUpperCase())) - { - case FurnitureType.FLOOR: - furniData = GetSessionDataManager().getFloorItemData(offer.furniClassId); - break; - case FurnitureType.WALL: - furniData = GetSessionDataManager().getWallItemData(offer.furniClassId); - break; - } - - return furniData; -} diff --git a/src/api/nitro/session/GetFurnitureDataForRoomObject.ts b/src/api/nitro/session/GetFurnitureDataForRoomObject.ts deleted file mode 100644 index fb76b9e..0000000 --- a/src/api/nitro/session/GetFurnitureDataForRoomObject.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, IFurnitureData, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer'; - -export function GetFurnitureDataForRoomObject(roomId: number, objectId: number, category: number): IFurnitureData -{ - const roomObject = GetRoomEngine().getRoomObject(roomId, objectId, category); - - if(!roomObject) return; - - const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); - - switch(category) - { - case RoomObjectCategory.FLOOR: - return GetSessionDataManager().getFloorItemData(typeId); - case RoomObjectCategory.WALL: - return GetSessionDataManager().getWallItemData(typeId); - } - - return null; -} diff --git a/src/api/nitro/session/GetOwnPosture.ts b/src/api/nitro/session/GetOwnPosture.ts deleted file mode 100644 index fe0c5f3..0000000 --- a/src/api/nitro/session/GetOwnPosture.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { AvatarAction, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { GetOwnRoomObject } from '../room'; - -export function GetOwnPosture(): string -{ - const roomObject = GetOwnRoomObject(); - - if(!roomObject) return AvatarAction.POSTURE_STAND; - - const model = roomObject.model; - - return model.getValue(RoomObjectVariable.FIGURE_POSTURE); -} diff --git a/src/api/nitro/session/GetProductDataForLocalization.ts b/src/api/nitro/session/GetProductDataForLocalization.ts deleted file mode 100644 index ac89803..0000000 --- a/src/api/nitro/session/GetProductDataForLocalization.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { GetSessionDataManager, IProductData } from '@nitrots/nitro-renderer'; - -export function GetProductDataForLocalization(localizationId: string): IProductData -{ - if(!localizationId) return null; - - return GetSessionDataManager().getProductData(localizationId); -} diff --git a/src/api/nitro/session/GetRoomSession.ts b/src/api/nitro/session/GetRoomSession.ts deleted file mode 100644 index da2af41..0000000 --- a/src/api/nitro/session/GetRoomSession.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { GetRoomSessionManager } from '@nitrots/nitro-renderer'; - -export const GetRoomSession = () => GetRoomSessionManager().getSession(-1); diff --git a/src/api/nitro/session/GoToDesktop.ts b/src/api/nitro/session/GoToDesktop.ts deleted file mode 100644 index 34f2031..0000000 --- a/src/api/nitro/session/GoToDesktop.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { DesktopViewComposer } from '@nitrots/nitro-renderer'; -import { SendMessageComposer } from '../SendMessageComposer'; - -export function GoToDesktop(): void -{ - SendMessageComposer(new DesktopViewComposer()); -} diff --git a/src/api/nitro/session/HasHabboClub.ts b/src/api/nitro/session/HasHabboClub.ts deleted file mode 100644 index 9cee03f..0000000 --- a/src/api/nitro/session/HasHabboClub.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GetSessionDataManager, HabboClubLevelEnum } from '@nitrots/nitro-renderer'; - -export function HasHabboClub(): boolean -{ - return (GetSessionDataManager().clubLevel >= HabboClubLevelEnum.CLUB); -} diff --git a/src/api/nitro/session/HasHabboVip.ts b/src/api/nitro/session/HasHabboVip.ts deleted file mode 100644 index f5a3e21..0000000 --- a/src/api/nitro/session/HasHabboVip.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GetSessionDataManager, HabboClubLevelEnum } from '@nitrots/nitro-renderer'; - -export function HasHabboVip(): boolean -{ - return (GetSessionDataManager().clubLevel >= HabboClubLevelEnum.VIP); -} diff --git a/src/api/nitro/session/IsOwnerOfFloorFurniture.ts b/src/api/nitro/session/IsOwnerOfFloorFurniture.ts deleted file mode 100644 index 5675db9..0000000 --- a/src/api/nitro/session/IsOwnerOfFloorFurniture.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { GetRoomSession } from './GetRoomSession'; - -export function IsOwnerOfFloorFurniture(id: number): boolean -{ - const roomObject = GetRoomEngine().getRoomObject(GetRoomSession().roomId, id, RoomObjectCategory.FLOOR); - - if(!roomObject || !roomObject.model) return false; - - const userId = GetSessionDataManager().userId; - const objectOwnerId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID); - - return (userId === objectOwnerId); -} diff --git a/src/api/nitro/session/IsOwnerOfFurniture.ts b/src/api/nitro/session/IsOwnerOfFurniture.ts deleted file mode 100644 index 49ce166..0000000 --- a/src/api/nitro/session/IsOwnerOfFurniture.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { GetSessionDataManager, IRoomObject, RoomObjectVariable } from '@nitrots/nitro-renderer'; - -export function IsOwnerOfFurniture(roomObject: IRoomObject): boolean -{ - if(!roomObject || !roomObject.model) return false; - - const userId = GetSessionDataManager().userId; - const objectOwnerId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID); - - return (userId === objectOwnerId); -} diff --git a/src/api/nitro/session/IsRidingHorse.ts b/src/api/nitro/session/IsRidingHorse.ts deleted file mode 100644 index f946b69..0000000 --- a/src/api/nitro/session/IsRidingHorse.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { GetOwnRoomObject } from '../room'; - -export function IsRidingHorse(): boolean -{ - const roomObject = GetOwnRoomObject(); - - if(!roomObject) return false; - - const model = roomObject.model; - const effectId = model.getValue(RoomObjectVariable.FIGURE_EFFECT); - - return (effectId === 77); -} diff --git a/src/api/nitro/session/StartRoomSession.ts b/src/api/nitro/session/StartRoomSession.ts deleted file mode 100644 index c203a77..0000000 --- a/src/api/nitro/session/StartRoomSession.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GetRoomSessionManager, IRoomSession } from '@nitrots/nitro-renderer'; - -export function StartRoomSession(session: IRoomSession): void -{ - GetRoomSessionManager().startSession(session); -} diff --git a/src/api/nitro/session/VisitDesktop.ts b/src/api/nitro/session/VisitDesktop.ts deleted file mode 100644 index 9fe3fb7..0000000 --- a/src/api/nitro/session/VisitDesktop.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { GetRoomSessionManager } from '@nitrots/nitro-renderer'; -import { GetRoomSession } from './GetRoomSession'; -import { GoToDesktop } from './GoToDesktop'; - -export const VisitDesktop = () => -{ - if(!GetRoomSession()) return; - - GoToDesktop(); - GetRoomSessionManager().removeSession(-1); -} diff --git a/src/api/nitro/session/index.ts b/src/api/nitro/session/index.ts deleted file mode 100644 index 4c0491d..0000000 --- a/src/api/nitro/session/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -export * from './CanManipulateFurniture'; -export * from './CreateRoomSession'; -export * from './GetCanStandUp'; -export * from './GetCanUseExpression'; -export * from './GetClubMemberLevel'; -export * from './GetFurnitureData'; -export * from './GetFurnitureDataForProductOffer'; -export * from './GetFurnitureDataForRoomObject'; -export * from './GetOwnPosture'; -export * from './GetProductDataForLocalization'; -export * from './GetRoomSession'; -export * from './GoToDesktop'; -export * from './HasHabboClub'; -export * from './HasHabboVip'; -export * from './IsOwnerOfFloorFurniture'; -export * from './IsOwnerOfFurniture'; -export * from './IsRidingHorse'; -export * from './StartRoomSession'; -export * from './VisitDesktop'; diff --git a/src/api/notification/NotificationAlertItem.ts b/src/api/notification/NotificationAlertItem.ts deleted file mode 100644 index 2d7702c..0000000 --- a/src/api/notification/NotificationAlertItem.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { NotificationAlertType } from './NotificationAlertType'; - -export class NotificationAlertItem -{ - private static ITEM_ID: number = -1; - - private _id: number; - private _messages: string[]; - private _alertType: string; - private _clickUrl: string; - private _clickUrlText: string; - private _title: string; - private _imageUrl: string; - - constructor(messages: string[], alertType: string = NotificationAlertType.DEFAULT, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null) - { - NotificationAlertItem.ITEM_ID += 1; - - this._id = NotificationAlertItem.ITEM_ID; - this._messages = messages; - this._alertType = alertType; - this._clickUrl = clickUrl; - this._clickUrlText = clickUrlText; - this._title = title; - this._imageUrl = imageUrl; - } - - public get id(): number - { - return this._id; - } - - public get messages(): string[] - { - return this._messages; - } - - public set alertType(alertType: string) - { - this._alertType = alertType; - } - - public get alertType(): string - { - return this._alertType; - } - - public get clickUrl(): string - { - return this._clickUrl; - } - - public get clickUrlText(): string - { - return this._clickUrlText; - } - - public get title(): string - { - return this._title; - } - - public get imageUrl(): string - { - return this._imageUrl; - } -} diff --git a/src/api/notification/NotificationAlertType.ts b/src/api/notification/NotificationAlertType.ts deleted file mode 100644 index ad804e8..0000000 --- a/src/api/notification/NotificationAlertType.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class NotificationAlertType -{ - public static DEFAULT: string = 'default'; - public static MOTD: string = 'motd'; - public static MODERATION: string = 'moderation'; - public static EVENT: string = 'event'; - public static NITRO: string = 'nitro'; - public static SEARCH: string = 'search'; - public static ALERT: string = 'alert'; -} diff --git a/src/api/notification/NotificationBubbleItem.ts b/src/api/notification/NotificationBubbleItem.ts deleted file mode 100644 index fe90dab..0000000 --- a/src/api/notification/NotificationBubbleItem.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { NotificationBubbleType } from './NotificationBubbleType'; - -export class NotificationBubbleItem -{ - private static ITEM_ID: number = -1; - - private _id: number; - private _message: string; - private _notificationType: string; - private _iconUrl: string; - private _linkUrl: string; - - constructor(message: string, notificationType: string = NotificationBubbleType.INFO, iconUrl: string = null, linkUrl: string = null) - { - NotificationBubbleItem.ITEM_ID += 1; - - this._id = NotificationBubbleItem.ITEM_ID; - this._message = message; - this._notificationType = notificationType; - this._iconUrl = iconUrl; - this._linkUrl = linkUrl; - } - - public get id(): number - { - return this._id; - } - - public get message(): string - { - return this._message; - } - - public get notificationType(): string - { - return this._notificationType; - } - - public get iconUrl(): string - { - return this._iconUrl; - } - - public get linkUrl(): string - { - return this._linkUrl; - } -} diff --git a/src/api/notification/NotificationBubbleType.ts b/src/api/notification/NotificationBubbleType.ts deleted file mode 100644 index cce38f5..0000000 --- a/src/api/notification/NotificationBubbleType.ts +++ /dev/null @@ -1,19 +0,0 @@ -export class NotificationBubbleType -{ - public static FRIENDOFFLINE: string = 'friendoffline'; - public static FRIENDONLINE: string = 'friendonline'; - public static THIRDPARTYFRIENDOFFLINE: string = 'thirdpartyfriendoffline'; - public static THIRDPARTYFRIENDONLINE: string = 'thirdpartyfriendonline'; - public static ACHIEVEMENT: string = 'achievement'; - public static BADGE_RECEIVED: string = 'badge_received'; - public static INFO: string = 'info'; - public static RECYCLEROK: string = 'recyclerok'; - public static RESPECT: string = 'respect'; - public static CLUB: string = 'club'; - public static SOUNDMACHINE: string = 'soundmachine'; - public static PETLEVEL: string = 'petlevel'; - public static CLUBGIFT: string = 'clubgift'; - public static BUYFURNI: string = 'buyfurni'; - public static VIP: string = 'vip'; - public static ROOMMESSAGESPOSTED: string = 'roommessagesposted'; -} diff --git a/src/api/notification/NotificationConfirmItem.ts b/src/api/notification/NotificationConfirmItem.ts deleted file mode 100644 index 0455662..0000000 --- a/src/api/notification/NotificationConfirmItem.ts +++ /dev/null @@ -1,67 +0,0 @@ -export class NotificationConfirmItem -{ - private static ITEM_ID: number = -1; - - private _id: number; - private _confirmType: string; - private _message: string; - private _onConfirm: Function; - private _onCancel: Function; - private _confirmText: string; - private _cancelText: string; - private _title: string; - - constructor(confirmType: string, message: string, onConfirm: Function, onCancel: Function, confirmText: string, cancelText: string, title: string) - { - NotificationConfirmItem.ITEM_ID += 1; - - this._id = NotificationConfirmItem.ITEM_ID; - this._confirmType = confirmType; - this._message = message; - this._onConfirm = onConfirm; - this._onCancel = onCancel; - this._confirmText = confirmText; - this._cancelText = cancelText; - this._title = title; - } - - public get id(): number - { - return this._id; - } - - public get confirmType(): string - { - return this._confirmType; - } - - public get message(): string - { - return this._message; - } - - public get onConfirm(): Function - { - return this._onConfirm; - } - - public get onCancel(): Function - { - return this._onCancel; - } - - public get confirmText(): string - { - return this._confirmText; - } - - public get cancelText(): string - { - return this._cancelText; - } - - public get title(): string - { - return this._title; - } -} diff --git a/src/api/notification/NotificationConfirmType.ts b/src/api/notification/NotificationConfirmType.ts deleted file mode 100644 index 533ca05..0000000 --- a/src/api/notification/NotificationConfirmType.ts +++ /dev/null @@ -1,4 +0,0 @@ -export class NotificationConfirmType -{ - public static DEFAULT: string = 'default'; -} diff --git a/src/api/notification/index.ts b/src/api/notification/index.ts deleted file mode 100644 index 23476d3..0000000 --- a/src/api/notification/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './NotificationAlertItem'; -export * from './NotificationAlertType'; -export * from './NotificationBubbleItem'; -export * from './NotificationBubbleType'; -export * from './NotificationConfirmItem'; -export * from './NotificationConfirmType'; diff --git a/src/api/purse/IPurse.ts b/src/api/purse/IPurse.ts deleted file mode 100644 index 9fffb18..0000000 --- a/src/api/purse/IPurse.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface IPurse -{ - credits: number; - activityPoints: Map; - clubDays: number; - clubPeriods: number; - hasClubLeft: boolean; - isVip: boolean; - pastClubDays: number; - pastVipDays: number; - isExpiring: boolean; - minutesUntilExpiration: number; - minutesSinceLastModified: number; - clubLevel: number; -} diff --git a/src/api/purse/Purse.ts b/src/api/purse/Purse.ts deleted file mode 100644 index 6970e59..0000000 --- a/src/api/purse/Purse.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { GetTickerTime, HabboClubLevelEnum } from '@nitrots/nitro-renderer'; -import { IPurse } from './IPurse'; - -export class Purse implements IPurse -{ - private _credits: number = 0; - private _activityPoints: Map = new Map(); - private _clubDays: number = 0; - private _clubPeriods: number = 0; - private _isVIP: boolean = false; - private _pastClubDays: number = 0; - private _pastVipDays: number = 0; - private _isExpiring: boolean = false; - private _minutesUntilExpiration: number = 0; - private _minutesSinceLastModified: number = 0; - private _lastUpdated: number = 0; - - public static from(purse: Purse): Purse - { - const newPurse = new Purse(); - - newPurse._credits = purse._credits; - newPurse._activityPoints = purse._activityPoints; - newPurse._clubDays = purse._clubDays; - newPurse._clubPeriods = purse._clubPeriods; - newPurse._isVIP = purse._isVIP; - newPurse._pastClubDays = purse._pastClubDays; - newPurse._pastVipDays = purse._pastVipDays; - newPurse._isExpiring = purse._isExpiring; - newPurse._minutesUntilExpiration = purse._minutesUntilExpiration; - newPurse._minutesSinceLastModified = purse._minutesSinceLastModified; - newPurse._lastUpdated = purse._lastUpdated; - - return newPurse; - } - - public get credits(): number - { - return this._credits; - } - - public set credits(credits: number) - { - this._lastUpdated = GetTickerTime(); - this._credits = credits; - } - - public get activityPoints(): Map - { - return this._activityPoints; - } - - public set activityPoints(k: Map) - { - this._lastUpdated = GetTickerTime(); - this._activityPoints = k; - } - - public get clubDays(): number - { - return this._clubDays; - } - - public set clubDays(k: number) - { - this._lastUpdated = GetTickerTime(); - this._clubDays = k; - } - - public get clubPeriods(): number - { - return this._clubPeriods; - } - - public set clubPeriods(k: number) - { - this._lastUpdated = GetTickerTime(); - this._clubPeriods = k; - } - - public get hasClubLeft(): boolean - { - return (this._clubDays > 0) || (this._clubPeriods > 0); - } - - public get isVip(): boolean - { - return this._isVIP; - } - - public set isVip(k: boolean) - { - this._isVIP = k; - } - - public get pastClubDays(): number - { - return this._pastClubDays; - } - - public set pastClubDays(k: number) - { - this._lastUpdated = GetTickerTime(); - this._pastClubDays = k; - } - - public get pastVipDays(): number - { - return this._pastVipDays; - } - - public set pastVipDays(k: number) - { - this._lastUpdated = GetTickerTime(); - this._pastVipDays = k; - } - - public get isExpiring(): boolean - { - return this._isExpiring; - } - - public set isExpiring(k: boolean) - { - this._isExpiring = k; - } - - public get minutesUntilExpiration(): number - { - var k: number = ((GetTickerTime() - this._lastUpdated) / (1000 * 60)); - var _local_2: number = (this._minutesUntilExpiration - k); - return (_local_2 > 0) ? _local_2 : 0; - } - - public set minutesUntilExpiration(k: number) - { - this._lastUpdated = GetTickerTime(); - this._minutesUntilExpiration = k; - } - - public get minutesSinceLastModified(): number - { - return this._minutesSinceLastModified; - } - - public set minutesSinceLastModified(k: number) - { - this._lastUpdated = GetTickerTime(); - this._minutesSinceLastModified = k; - } - - public get lastUpdated(): number - { - return this._lastUpdated; - } - - public get clubLevel(): number - { - if(((this.clubDays === 0) && (this.clubPeriods === 0))) return HabboClubLevelEnum.NO_CLUB; - - if(this.isVip) return HabboClubLevelEnum.VIP; - - return HabboClubLevelEnum.CLUB; - } -} diff --git a/src/api/purse/index.ts b/src/api/purse/index.ts deleted file mode 100644 index ed34480..0000000 --- a/src/api/purse/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './IPurse'; -export * from './Purse'; diff --git a/src/api/room/events/RoomWidgetPollUpdateEvent.ts b/src/api/room/events/RoomWidgetPollUpdateEvent.ts deleted file mode 100644 index edfb8fd..0000000 --- a/src/api/room/events/RoomWidgetPollUpdateEvent.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { IPollQuestion } from '@nitrots/nitro-renderer'; -import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; - -export class RoomWidgetPollUpdateEvent extends RoomWidgetUpdateEvent -{ - public static readonly OFFER = 'RWPUW_OFFER'; - public static readonly ERROR = 'RWPUW_ERROR'; - public static readonly CONTENT = 'RWPUW_CONTENT'; - - private _id = -1; - private _summary: string; - private _headline: string; - private _numQuestions = 0; - private _startMessage = ''; - private _endMessage = ''; - private _questionArray: IPollQuestion[] = null; - private _pollType = ''; - private _npsPoll = false; - - constructor(type: string, id: number) - { - super(type); - this._id = id; - } - - public get id(): number - { - return this._id; - } - - public get summary(): string - { - return this._summary; - } - - public set summary(k: string) - { - this._summary = k; - } - - public get headline(): string - { - return this._headline; - } - - public set headline(k: string) - { - this._headline = k; - } - - public get numQuestions(): number - { - return this._numQuestions; - } - - public set numQuestions(k: number) - { - this._numQuestions = k; - } - - public get startMessage(): string - { - return this._startMessage; - } - - public set startMessage(k: string) - { - this._startMessage = k; - } - - public get endMessage(): string - { - return this._endMessage; - } - - public set endMessage(k: string) - { - this._endMessage = k; - } - - public get questionArray(): IPollQuestion[] - { - return this._questionArray; - } - - public set questionArray(k: IPollQuestion[]) - { - this._questionArray = k; - } - - public get pollType(): string - { - return this._pollType; - } - - public set pollType(k: string) - { - this._pollType = k; - } - - public get npsPoll(): boolean - { - return this._npsPoll; - } - - public set npsPoll(k: boolean) - { - this._npsPoll = k; - } -} diff --git a/src/api/room/events/RoomWidgetUpdateBackgroundColorPreviewEvent.ts b/src/api/room/events/RoomWidgetUpdateBackgroundColorPreviewEvent.ts deleted file mode 100644 index 30135a3..0000000 --- a/src/api/room/events/RoomWidgetUpdateBackgroundColorPreviewEvent.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; - -export class RoomWidgetUpdateBackgroundColorPreviewEvent extends RoomWidgetUpdateEvent -{ - public static PREVIEW = 'RWUBCPE_PREVIEW'; - public static CLEAR_PREVIEW = 'RWUBCPE_CLEAR_PREVIEW'; - - private _hue: number; - private _saturation: number; - private _lightness: number; - - constructor(type: string, hue: number = 0, saturation: number = 0, lightness: number = 0) - { - super(type); - - this._hue = hue; - this._saturation = saturation; - this._lightness = lightness; - } - - public get hue(): number - { - return this._hue; - } - - public get saturation(): number - { - return this._saturation; - } - - public get lightness(): number - { - return this._lightness; - } -} diff --git a/src/api/room/events/RoomWidgetUpdateChatInputContentEvent.ts b/src/api/room/events/RoomWidgetUpdateChatInputContentEvent.ts deleted file mode 100644 index 9352372..0000000 --- a/src/api/room/events/RoomWidgetUpdateChatInputContentEvent.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; - -export class RoomWidgetUpdateChatInputContentEvent extends RoomWidgetUpdateEvent -{ - public static CHAT_INPUT_CONTENT: string = 'RWUCICE_CHAT_INPUT_CONTENT'; - public static WHISPER: string = 'whisper'; - public static SHOUT: string = 'shout'; - - private _chatMode: string = ''; - private _userName: string = ''; - - constructor(chatMode: string, userName: string) - { - super(RoomWidgetUpdateChatInputContentEvent.CHAT_INPUT_CONTENT); - - this._chatMode = chatMode; - this._userName = userName; - } - - public get chatMode(): string - { - return this._chatMode; - } - - public get userName(): string - { - return this._userName; - } -} diff --git a/src/api/room/events/RoomWidgetUpdateEvent.ts b/src/api/room/events/RoomWidgetUpdateEvent.ts deleted file mode 100644 index 0ac8ff8..0000000 --- a/src/api/room/events/RoomWidgetUpdateEvent.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; - -export class RoomWidgetUpdateEvent extends NitroEvent -{} diff --git a/src/api/room/events/RoomWidgetUpdateRentableBotChatEvent.ts b/src/api/room/events/RoomWidgetUpdateRentableBotChatEvent.ts deleted file mode 100644 index 6191e1b..0000000 --- a/src/api/room/events/RoomWidgetUpdateRentableBotChatEvent.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; - -export class RoomWidgetUpdateRentableBotChatEvent extends RoomWidgetUpdateEvent -{ - public static UPDATE_CHAT: string = 'RWURBCE_UPDATE_CHAT'; - - private _objectId: number; - private _category: number; - private _botId: number; - private _chat: string; - private _automaticChat: boolean; - private _chatDelay: number; - private _mixSentences: boolean; - - constructor(objectId: number, category: number, botId: number, chat: string, automaticChat: boolean, chatDelay: number, mixSentences: boolean) - { - super(RoomWidgetUpdateRentableBotChatEvent.UPDATE_CHAT); - - this._objectId = objectId; - this._category = category; - this._botId = botId; - this._chat = chat; - this._automaticChat = automaticChat; - this._chatDelay = chatDelay; - this._mixSentences = mixSentences; - } - - public get objectId(): number - { - return this._objectId; - } - - public get category(): number - { - return this._category; - } - - public get botId(): number - { - return this._botId; - } - - public get chat(): string - { - return this._chat; - } - - public get automaticChat(): boolean - { - return this._automaticChat; - } - - public get chatDelay(): number - { - return this._chatDelay; - } - - public get mixSentences(): boolean - { - return this._mixSentences; - } -} diff --git a/src/api/room/events/RoomWidgetUpdateRoomObjectEvent.ts b/src/api/room/events/RoomWidgetUpdateRoomObjectEvent.ts deleted file mode 100644 index 0660276..0000000 --- a/src/api/room/events/RoomWidgetUpdateRoomObjectEvent.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; - -export class RoomWidgetUpdateRoomObjectEvent extends RoomWidgetUpdateEvent -{ - public static OBJECT_SELECTED: string = 'RWUROE_OBJECT_SELECTED'; - public static OBJECT_DESELECTED: string = 'RWUROE_OBJECT_DESELECTED'; - public static USER_REMOVED: string = 'RWUROE_USER_REMOVED'; - public static FURNI_REMOVED: string = 'RWUROE_FURNI_REMOVED'; - public static FURNI_ADDED: string = 'RWUROE_FURNI_ADDED'; - public static USER_ADDED: string = 'RWUROE_USER_ADDED'; - public static OBJECT_ROLL_OVER: string = 'RWUROE_OBJECT_ROLL_OVER'; - public static OBJECT_ROLL_OUT: string = 'RWUROE_OBJECT_ROLL_OUT'; - public static OBJECT_REQUEST_MANIPULATION: string = 'RWUROE_OBJECT_REQUEST_MANIPULATION'; - public static OBJECT_DOUBLE_CLICKED: string = 'RWUROE_OBJECT_DOUBLE_CLICKED'; - - private _id: number; - private _category: number; - private _roomId: number; - - constructor(type: string, id: number, category: number, roomId: number) - { - super(type); - - this._id = id; - this._category = category; - this._roomId = roomId; - } - - public get id(): number - { - return this._id; - } - - public get category(): number - { - return this._category; - } - - public get roomId(): number - { - return this._roomId; - } -} diff --git a/src/api/room/events/index.ts b/src/api/room/events/index.ts deleted file mode 100644 index e5ed0d8..0000000 --- a/src/api/room/events/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './RoomWidgetPollUpdateEvent'; -export * from './RoomWidgetUpdateBackgroundColorPreviewEvent'; -export * from './RoomWidgetUpdateChatInputContentEvent'; -export * from './RoomWidgetUpdateEvent'; -export * from './RoomWidgetUpdateRentableBotChatEvent'; -export * from './RoomWidgetUpdateRoomObjectEvent'; diff --git a/src/api/room/index.ts b/src/api/room/index.ts deleted file mode 100644 index 56aea79..0000000 --- a/src/api/room/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './events'; -export * from './widgets'; diff --git a/src/api/room/widgets/AvatarInfoFurni.ts b/src/api/room/widgets/AvatarInfoFurni.ts deleted file mode 100644 index 47743e9..0000000 --- a/src/api/room/widgets/AvatarInfoFurni.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { IObjectData } from '@nitrots/nitro-renderer'; -import { IAvatarInfo } from './IAvatarInfo'; - -export class AvatarInfoFurni implements IAvatarInfo -{ - public static FURNI: string = 'IFI_FURNI'; - - public id: number = 0; - public category: number = 0; - public name: string = ''; - public description: string = ''; - public isWallItem: boolean = false; - public isStickie: boolean = false; - public isRoomOwner: boolean = false; - public roomControllerLevel: number = 0; - public isAnyRoomController: boolean = false; - public expiration: number = -1; - public purchaseCatalogPageId: number = -1; - public purchaseOfferId: number = -1; - public extraParam: string = ''; - public isOwner: boolean = false; - public stuffData: IObjectData = null; - public groupId: number = 0; - public ownerId: number = 0; - public ownerName: string = ''; - public usagePolicy: number = 0; - public rentCatalogPageId: number = -1; - public rentOfferId: number = -1; - public purchaseCouldBeUsedForBuyout: boolean = false; - public rentCouldBeUsedForBuyout: boolean = false; - public availableForBuildersClub: boolean = false; - public tileSizeX: number = 1; - public tileSizeY: number = 1; - - constructor(public readonly type: string) - {} -} diff --git a/src/api/room/widgets/AvatarInfoName.ts b/src/api/room/widgets/AvatarInfoName.ts deleted file mode 100644 index 66a6a7e..0000000 --- a/src/api/room/widgets/AvatarInfoName.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class AvatarInfoName -{ - constructor( - public readonly roomIndex: number, - public readonly category: number, - public readonly id: number, - public readonly name: string, - public readonly userType: number, - public readonly isFriend: boolean = false) - {} -} diff --git a/src/api/room/widgets/AvatarInfoPet.ts b/src/api/room/widgets/AvatarInfoPet.ts deleted file mode 100644 index 0c0435a..0000000 --- a/src/api/room/widgets/AvatarInfoPet.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { IAvatarInfo } from './IAvatarInfo'; - -export class AvatarInfoPet implements IAvatarInfo -{ - public static PET_INFO: string = 'IPI_PET_INFO'; - - public level: number = 0; - public maximumLevel: number = 0; - public experience: number = 0; - public levelExperienceGoal: number = 0; - public energy: number = 0; - public maximumEnergy: number = 0; - public happyness: number = 0; - public maximumHappyness: number = 0; - public respectsPetLeft: number = 0; - public respect: number = 0; - public age: number = 0; - public name: string = ''; - public id: number = -1; - public image: HTMLImageElement = null; - public petType: number = 0; - public petBreed: number = 0; - public petFigure: string = ''; - public posture: string = 'std'; - public isOwner: boolean = false; - public ownerId: number = -1; - public ownerName: string = ''; - public canRemovePet: boolean = false; - public roomIndex: number = 0; - public unknownRarityLevel: number = 0; - public saddle: boolean = false; - public rider: boolean = false; - public breedable: boolean = false; - public skillTresholds: number[] = []; - public publiclyRideable: number = 0; - public fullyGrown: boolean = false; - public dead: boolean = false; - public rarityLevel: number = 0; - public maximumTimeToLive: number = 0; - public remainingTimeToLive: number = 0; - public remainingGrowTime: number = 0; - public publiclyBreedable: boolean = false; - - constructor(public readonly type: string) - {} -} diff --git a/src/api/room/widgets/AvatarInfoRentableBot.ts b/src/api/room/widgets/AvatarInfoRentableBot.ts deleted file mode 100644 index 77fb10c..0000000 --- a/src/api/room/widgets/AvatarInfoRentableBot.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { IAvatarInfo } from './IAvatarInfo'; - -export class AvatarInfoRentableBot implements IAvatarInfo -{ - public static RENTABLE_BOT: string = 'IRBI_RENTABLE_BOT'; - - public name: string = ''; - public motto: string = ''; - public webID: number = 0; - public figure: string = ''; - public badges: string[] = []; - public carryItem: number = 0; - public roomIndex: number = 0; - public amIOwner: boolean = false; - public amIAnyRoomController: boolean = false; - public roomControllerLevel: number = 0; - public ownerId: number = -1; - public ownerName: string = ''; - public botSkills: number[] = []; - - constructor(public readonly type: string) - {} -} diff --git a/src/api/room/widgets/AvatarInfoUser.ts b/src/api/room/widgets/AvatarInfoUser.ts deleted file mode 100644 index 270bfbd..0000000 --- a/src/api/room/widgets/AvatarInfoUser.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { IAvatarInfo } from './IAvatarInfo'; - -export class AvatarInfoUser implements IAvatarInfo -{ - public static OWN_USER: string = 'IUI_OWN_USER'; - public static PEER: string = 'IUI_PEER'; - public static BOT: string = 'IUI_BOT'; - public static TRADE_REASON_OK: number = 0; - public static TRADE_REASON_SHUTDOWN: number = 2; - public static TRADE_REASON_NO_TRADING: number = 3; - public static DEFAULT_BOT_BADGE_ID: string = 'BOT'; - - public name: string = ''; - public motto: string = ''; - public achievementScore: number = 0; - public webID: number = 0; - public xp: number = 0; - public userType: number = -1; - public figure: string = ''; - public badges: string[] = []; - public groupId: number = 0; - public groupName: string = ''; - public groupBadgeId: string = ''; - public carryItem: number = 0; - public roomIndex: number = 0; - public isSpectatorMode: boolean = false; - public allowNameChange: boolean = false; - public amIOwner: boolean = false; - public amIAnyRoomController: boolean = false; - public roomControllerLevel: number = 0; - public canBeKicked: boolean = false; - public canBeBanned: boolean = false; - public canBeMuted: boolean = false; - public respectLeft: number = 0; - public isIgnored: boolean = false; - public isGuildRoom: boolean = false; - public canTrade: boolean = false; - public canTradeReason: number = 0; - public targetRoomControllerLevel: number = 0; - public isAmbassador: boolean = false; - - constructor(public readonly type: string) - {} - - public get isOwnUser(): boolean - { - return (this.type === AvatarInfoUser.OWN_USER); - } -} diff --git a/src/api/room/widgets/AvatarInfoUtilities.ts b/src/api/room/widgets/AvatarInfoUtilities.ts deleted file mode 100644 index b670bde..0000000 --- a/src/api/room/widgets/AvatarInfoUtilities.ts +++ /dev/null @@ -1,439 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, GetTickerTime, IFurnitureData, IRoomModerationSettings, IRoomPetData, IRoomUserData, ObjectDataFactory, PetFigureData, PetType, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomTradingLevelEnum, RoomWidgetEnumItemExtradataParameter } from '@nitrots/nitro-renderer'; -import { GetRoomSession, IsOwnerOfFurniture } from '../../nitro'; -import { LocalizeText } from '../../utils'; -import { AvatarInfoFurni } from './AvatarInfoFurni'; -import { AvatarInfoName } from './AvatarInfoName'; -import { AvatarInfoPet } from './AvatarInfoPet'; -import { AvatarInfoRentableBot } from './AvatarInfoRentableBot'; -import { AvatarInfoUser } from './AvatarInfoUser'; - -export class AvatarInfoUtilities -{ - public static getObjectName(objectId: number, category: number): AvatarInfoName - { - const roomSession = GetRoomSession(); - - let id = -1; - let name: string = null; - let userType = 0; - - switch(category) - { - case RoomObjectCategory.FLOOR: - case RoomObjectCategory.WALL: { - const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, objectId, category); - - if(!roomObject) break; - - if(roomObject.type.indexOf('poster') === 0) - { - name = LocalizeText('${poster_' + parseInt(roomObject.type.replace('poster', '')) + '_name}'); - } - else - { - let furniData: IFurnitureData = null; - - const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); - - if(category === RoomObjectCategory.FLOOR) - { - furniData = GetSessionDataManager().getFloorItemData(typeId); - } - - else if(category === RoomObjectCategory.WALL) - { - furniData = GetSessionDataManager().getWallItemData(typeId); - } - - if(!furniData) break; - - id = furniData.id; - name = furniData.name; - } - break; - } - case RoomObjectCategory.UNIT: { - const userData = roomSession.userDataManager.getUserDataByIndex(objectId); - - if(!userData) break; - - id = userData.webID; - name = userData.name; - userType = userData.type; - break; - } - } - - if(!name || !name.length) return null; - - return new AvatarInfoName(objectId, category, id, name, userType); - } - - public static getFurniInfo(objectId: number, category: number): AvatarInfoFurni - { - const roomSession = GetRoomSession(); - const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, objectId, category); - - if(!roomObject) return null; - - const furniInfo = new AvatarInfoFurni(AvatarInfoFurni.FURNI); - - furniInfo.id = objectId; - furniInfo.category = category; - - const model = roomObject.model; - - if(model.getValue(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM)) furniInfo.extraParam = model.getValue(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM); - - const objectData = ObjectDataFactory.getData(model.getValue(RoomObjectVariable.FURNITURE_DATA_FORMAT)); - - objectData.initializeFromRoomObjectModel(model); - - furniInfo.stuffData = objectData; - - const objectType = roomObject.type; - - if(objectType.indexOf('poster') === 0) - { - const posterId = parseInt(objectType.replace('poster', '')); - - furniInfo.name = LocalizeText(('${poster_' + posterId) + '_name}'); - furniInfo.description = LocalizeText(('${poster_' + posterId) + '_desc}'); - } - else - { - const typeId = model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); - - let furnitureData: IFurnitureData = null; - - if(category === RoomObjectCategory.FLOOR) - { - furnitureData = GetSessionDataManager().getFloorItemData(typeId); - } - - else if(category === RoomObjectCategory.WALL) - { - furnitureData = GetSessionDataManager().getWallItemData(typeId); - } - - if(furnitureData) - { - furniInfo.name = furnitureData.name; - furniInfo.description = furnitureData.description; - furniInfo.purchaseOfferId = furnitureData.purchaseOfferId; - furniInfo.purchaseCouldBeUsedForBuyout = furnitureData.purchaseCouldBeUsedForBuyout; - furniInfo.rentOfferId = furnitureData.rentOfferId; - furniInfo.rentCouldBeUsedForBuyout = furnitureData.rentCouldBeUsedForBuyout; - furniInfo.availableForBuildersClub = furnitureData.availableForBuildersClub; - furniInfo.tileSizeX = furnitureData.tileSizeX; - furniInfo.tileSizeY = furnitureData.tileSizeY; - } - } - - if(objectType.indexOf('post_it') > -1) furniInfo.isStickie = true; - - const expiryTime = model.getValue(RoomObjectVariable.FURNITURE_EXPIRY_TIME); - const expiryTimestamp = model.getValue(RoomObjectVariable.FURNITURE_EXPIRTY_TIMESTAMP); - - furniInfo.expiration = ((expiryTime < 0) ? expiryTime : Math.max(0, (expiryTime - ((GetTickerTime() - expiryTimestamp) / 1000)))); - - /* let roomObjectImage = GetRoomEngine().getRoomObjectImage(roomSession.roomId, objectId, category, new Vector3d(180), 64, null); - - if(!roomObjectImage.data || (roomObjectImage.data.width > 140) || (roomObjectImage.data.height > 200)) - { - roomObjectImage = GetRoomEngine().getRoomObjectImage(roomSession.roomId, objectId, category, new Vector3d(180), 1, null); - } - - furniInfo.image = roomObjectImage.getImage(); */ - furniInfo.isWallItem = (category === RoomObjectCategory.WALL); - furniInfo.isRoomOwner = roomSession.isRoomOwner; - furniInfo.roomControllerLevel = roomSession.controllerLevel; - furniInfo.isAnyRoomController = GetSessionDataManager().isModerator; - furniInfo.ownerId = model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID); - furniInfo.ownerName = model.getValue(RoomObjectVariable.FURNITURE_OWNER_NAME); - furniInfo.usagePolicy = model.getValue(RoomObjectVariable.FURNITURE_USAGE_POLICY); - - const guildId = model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_GUILD_ID); - - if(guildId !== 0) furniInfo.groupId = guildId; - - if(IsOwnerOfFurniture(roomObject)) furniInfo.isOwner = true; - - return furniInfo; - } - - public static getUserInfo(category: number, userData: IRoomUserData): AvatarInfoUser - { - const roomSession = GetRoomSession(); - - const userInfo = new AvatarInfoUser((userData.webID === GetSessionDataManager().userId) ? AvatarInfoUser.OWN_USER : AvatarInfoUser.PEER); - - userInfo.isSpectatorMode = roomSession.isSpectator; - userInfo.name = userData.name; - userInfo.motto = userData.custom; - userInfo.achievementScore = userData.activityPoints; - userInfo.webID = userData.webID; - userInfo.roomIndex = userData.roomIndex; - userInfo.userType = RoomObjectType.USER; - - const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, userData.roomIndex, category); - - if(roomObject) userInfo.carryItem = (roomObject.model.getValue(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0); - - if(userInfo.type === AvatarInfoUser.OWN_USER) userInfo.allowNameChange = GetSessionDataManager().canChangeName; - - userInfo.amIOwner = roomSession.isRoomOwner; - userInfo.isGuildRoom = roomSession.isGuildRoom; - userInfo.roomControllerLevel = roomSession.controllerLevel; - userInfo.amIAnyRoomController = GetSessionDataManager().isModerator; - userInfo.isAmbassador = GetSessionDataManager().isAmbassador; - - if(userInfo.type === AvatarInfoUser.PEER) - { - if(roomObject) - { - userInfo.targetRoomControllerLevel = roomObject.model.getValue(RoomObjectVariable.FIGURE_FLAT_CONTROL); - userInfo.canBeMuted = this.canBeMuted(userInfo); - userInfo.canBeKicked = this.canBeKicked(userInfo); - userInfo.canBeBanned = this.canBeBanned(userInfo); - } - - userInfo.isIgnored = GetSessionDataManager().isUserIgnored(userData.name); - userInfo.respectLeft = GetSessionDataManager().respectsLeft; - - const isShuttingDown = GetSessionDataManager().isSystemShutdown; - const tradeMode = roomSession.tradeMode; - - if(isShuttingDown) - { - userInfo.canTrade = false; - } - else - { - switch(tradeMode) - { - case RoomTradingLevelEnum.ROOM_CONTROLLER_REQUIRED: { - const roomController = ((userInfo.roomControllerLevel !== RoomControllerLevel.NONE) && (userInfo.roomControllerLevel !== RoomControllerLevel.GUILD_MEMBER)); - const targetController = ((userInfo.targetRoomControllerLevel !== RoomControllerLevel.NONE) && (userInfo.targetRoomControllerLevel !== RoomControllerLevel.GUILD_MEMBER)); - - userInfo.canTrade = (roomController || targetController); - break; - } - case RoomTradingLevelEnum.FREE_TRADING: - userInfo.canTrade = true; - break; - default: - userInfo.canTrade = false; - break; - } - } - - userInfo.canTradeReason = AvatarInfoUser.TRADE_REASON_OK; - - if(isShuttingDown) userInfo.canTradeReason = AvatarInfoUser.TRADE_REASON_SHUTDOWN; - - if(tradeMode !== RoomTradingLevelEnum.FREE_TRADING) userInfo.canTradeReason = AvatarInfoUser.TRADE_REASON_NO_TRADING; - - // const _local_12 = GetSessionDataManager().userId; - // _local_13 = GetSessionDataManager().getUserTags(_local_12); - // this._Str_16287(_local_12, _local_13); - } - - userInfo.groupId = userData.groupId; - userInfo.groupBadgeId = GetSessionDataManager().getGroupBadge(userInfo.groupId); - userInfo.groupName = userData.groupName; - userInfo.badges = roomSession.userDataManager.getUserBadges(userData.webID); - userInfo.figure = userData.figure; - //var _local_8:Array = GetSessionDataManager().getUserTags(userData.webID); - //this._Str_16287(userData.webId, _local_8); - //this._container.habboGroupsManager.updateVisibleExtendedProfile(userData.webID); - //this._container.connection.send(new GetRelationshipStatusInfoMessageComposer(userData.webId)); - - return userInfo; - } - - public static getBotInfo(category: number, userData: IRoomUserData): AvatarInfoUser - { - const roomSession = GetRoomSession(); - const userInfo = new AvatarInfoUser(AvatarInfoUser.BOT); - - userInfo.name = userData.name; - userInfo.motto = userData.custom; - userInfo.webID = userData.webID; - userInfo.roomIndex = userData.roomIndex; - userInfo.userType = userData.type; - - const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, userData.roomIndex, category); - - if(roomObject) userInfo.carryItem = (roomObject.model.getValue(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0); - - userInfo.amIOwner = roomSession.isRoomOwner; - userInfo.isGuildRoom = roomSession.isGuildRoom; - userInfo.roomControllerLevel = roomSession.controllerLevel; - userInfo.amIAnyRoomController = GetSessionDataManager().isModerator; - userInfo.isAmbassador = GetSessionDataManager().isAmbassador; - userInfo.badges = [ AvatarInfoUser.DEFAULT_BOT_BADGE_ID ]; - userInfo.figure = userData.figure; - - return userInfo; - } - - public static getRentableBotInfo(category: number, userData: IRoomUserData): AvatarInfoRentableBot - { - const roomSession = GetRoomSession(); - const botInfo = new AvatarInfoRentableBot(AvatarInfoRentableBot.RENTABLE_BOT); - - botInfo.name = userData.name; - botInfo.motto = userData.custom; - botInfo.webID = userData.webID; - botInfo.roomIndex = userData.roomIndex; - botInfo.ownerId = userData.ownerId; - botInfo.ownerName = userData.ownerName; - botInfo.botSkills = userData.botSkills; - - const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, userData.roomIndex, category); - - if(roomObject) botInfo.carryItem = (roomObject.model.getValue(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0); - - botInfo.amIOwner = roomSession.isRoomOwner; - botInfo.roomControllerLevel = roomSession.controllerLevel; - botInfo.amIAnyRoomController = GetSessionDataManager().isModerator; - botInfo.badges = [ AvatarInfoUser.DEFAULT_BOT_BADGE_ID ]; - botInfo.figure = userData.figure; - - return botInfo; - } - - public static getPetInfo(petData: IRoomPetData): AvatarInfoPet - { - const roomSession = GetRoomSession(); - const userData = roomSession.userDataManager.getPetData(petData.id); - - if(!userData) return; - - const figure = new PetFigureData(userData.figure); - - let posture: string = null; - - if(figure.typeId === PetType.MONSTERPLANT) - { - if(petData.level >= petData.adultLevel) posture = 'std'; - else posture = ('grw' + petData.level); - } - - const isOwner = (petData.ownerId === GetSessionDataManager().userId); - const petInfo = new AvatarInfoPet(AvatarInfoPet.PET_INFO); - - petInfo.name = userData.name; - petInfo.id = petData.id; - petInfo.ownerId = petData.ownerId; - petInfo.ownerName = petData.ownerName; - petInfo.rarityLevel = petData.rarityLevel; - petInfo.petType = figure.typeId; - petInfo.petBreed = figure.paletteId; - petInfo.petFigure = userData.figure; - petInfo.posture = posture; - petInfo.isOwner = isOwner; - petInfo.roomIndex = userData.roomIndex; - petInfo.level = petData.level; - petInfo.maximumLevel = petData.maximumLevel; - petInfo.experience = petData.experience; - petInfo.levelExperienceGoal = petData.levelExperienceGoal; - petInfo.energy = petData.energy; - petInfo.maximumEnergy = petData.maximumEnergy; - petInfo.happyness = petData.happyness; - petInfo.maximumHappyness = petData.maximumHappyness; - petInfo.respect = petData.respect; - petInfo.respectsPetLeft = GetSessionDataManager().respectsPetLeft; - petInfo.age = petData.age; - petInfo.saddle = petData.saddle; - petInfo.rider = petData.rider; - petInfo.breedable = petData.breedable; - petInfo.fullyGrown = petData.fullyGrown; - petInfo.dead = petData.dead; - petInfo.rarityLevel = petData.rarityLevel; - petInfo.skillTresholds = petData.skillTresholds; - petInfo.canRemovePet = false; - petInfo.publiclyRideable = petData.publiclyRideable; - petInfo.maximumTimeToLive = petData.maximumTimeToLive; - petInfo.remainingTimeToLive = petData.remainingTimeToLive; - petInfo.remainingGrowTime = petData.remainingGrowTime; - petInfo.publiclyBreedable = petData.publiclyBreedable; - - if(isOwner || roomSession.isRoomOwner || GetSessionDataManager().isModerator || (roomSession.controllerLevel >= RoomControllerLevel.GUEST)) petInfo.canRemovePet = true; - - return petInfo; - } - - private static checkGuildSetting(userInfo: AvatarInfoUser): boolean - { - if(userInfo.isGuildRoom) return (userInfo.roomControllerLevel >= RoomControllerLevel.GUILD_ADMIN); - - return (userInfo.roomControllerLevel >= RoomControllerLevel.GUEST); - } - - private static isValidSetting(userInfo: AvatarInfoUser, checkSetting: (userInfo: AvatarInfoUser, moderation: IRoomModerationSettings) => boolean): boolean - { - const roomSession = GetRoomSession(); - - if(!roomSession.isPrivateRoom) return false; - - const moderation = roomSession.moderationSettings; - - let flag = false; - - if(moderation) flag = checkSetting(userInfo, moderation); - - return (flag && (userInfo.targetRoomControllerLevel < RoomControllerLevel.ROOM_OWNER)); - } - - private static canBeMuted(userInfo: AvatarInfoUser): boolean - { - const checkSetting = (userInfo: AvatarInfoUser, moderation: IRoomModerationSettings) => - { - switch(moderation.allowMute) - { - case RoomModerationSettings.MODERATION_LEVEL_USER_WITH_RIGHTS: - return this.checkGuildSetting(userInfo); - default: - return (userInfo.roomControllerLevel >= RoomControllerLevel.ROOM_OWNER); - } - } - - return this.isValidSetting(userInfo, checkSetting); - } - - private static canBeKicked(userInfo: AvatarInfoUser): boolean - { - const checkSetting = (userInfo: AvatarInfoUser, moderation: IRoomModerationSettings) => - { - switch(moderation.allowKick) - { - case RoomModerationSettings.MODERATION_LEVEL_ALL: - return true; - case RoomModerationSettings.MODERATION_LEVEL_USER_WITH_RIGHTS: - return this.checkGuildSetting(userInfo); - default: - return (userInfo.roomControllerLevel >= RoomControllerLevel.ROOM_OWNER); - } - } - - return this.isValidSetting(userInfo, checkSetting); - } - - private static canBeBanned(userInfo: AvatarInfoUser): boolean - { - const checkSetting = (userInfo: AvatarInfoUser, moderation: IRoomModerationSettings) => - { - switch(moderation.allowBan) - { - case RoomModerationSettings.MODERATION_LEVEL_USER_WITH_RIGHTS: - return this.checkGuildSetting(userInfo); - default: - return (userInfo.roomControllerLevel >= RoomControllerLevel.ROOM_OWNER); - } - } - - return this.isValidSetting(userInfo, checkSetting); - } -} diff --git a/src/api/room/widgets/BotSkillsEnum.ts b/src/api/room/widgets/BotSkillsEnum.ts deleted file mode 100644 index b879cdc..0000000 --- a/src/api/room/widgets/BotSkillsEnum.ts +++ /dev/null @@ -1,18 +0,0 @@ -export class BotSkillsEnum -{ - public static GENERIC_SKILL: number = 0; - public static DRESS_UP: number = 1; - public static SETUP_CHAT: number = 2; - public static RANDOM_WALK: number = 3; - public static DANCE: number = 4; - public static CHANGE_BOT_NAME: number = 5; - public static SERVE_BEVERAGE: number = 6; - public static INCLIENT_LINK: number = 7; - public static NUX_PROCEED: number = 8; - public static CHANGE_BOT_MOTTO: number = 9; - public static NUX_TAKE_TOUR: number = 10; - public static NO_PICK_UP: number = 12; - public static NAVIGATOR_SEARCH: number = 14; - public static DONATE_TO_USER: number = 24; - public static DONATE_TO_ALL: number = 25; -} diff --git a/src/api/room/widgets/ChatBubbleMessage.ts b/src/api/room/widgets/ChatBubbleMessage.ts deleted file mode 100644 index 44d848c..0000000 --- a/src/api/room/widgets/ChatBubbleMessage.ts +++ /dev/null @@ -1,54 +0,0 @@ -export class ChatBubbleMessage -{ - public static BUBBLE_COUNTER: number = 0; - - public id: number = -1; - public width: number = 0; - public height: number = 0; - public elementRef: HTMLDivElement = null; - public skipMovement: boolean = false; - - private _top: number = 0; - private _left: number = 0; - - constructor( - public senderId: number = -1, - public senderCategory: number = -1, - public roomId: number = -1, - public text: string = '', - public formattedText: string = '', - public username: string = '', - public location: { x: number, y: number } = null, - public type: number = 0, - public styleId: number = 0, - public imageUrl: string = null, - public color: string = null - ) - { - this.id = ++ChatBubbleMessage.BUBBLE_COUNTER; - } - - public get top(): number - { - return this._top; - } - - public set top(value: number) - { - this._top = value; - - if(this.elementRef) this.elementRef.style.top = (this._top + 'px'); - } - - public get left(): number - { - return this._left; - } - - public set left(value: number) - { - this._left = value; - - if(this.elementRef) this.elementRef.style.left = (this._left + 'px'); - } -} diff --git a/src/api/room/widgets/ChatBubbleUtilities.ts b/src/api/room/widgets/ChatBubbleUtilities.ts deleted file mode 100644 index 0ccbb14..0000000 --- a/src/api/room/widgets/ChatBubbleUtilities.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { AvatarFigurePartType, AvatarScaleType, AvatarSetType, GetAvatarRenderManager, GetRoomEngine, PetFigureData, TextureUtils, Vector3d } from '@nitrots/nitro-renderer'; - -export class ChatBubbleUtilities -{ - public static AVATAR_COLOR_CACHE: Map = new Map(); - public static AVATAR_IMAGE_CACHE: Map = new Map(); - public static PET_IMAGE_CACHE: Map = new Map(); - - private static placeHolderImageUrl: string = ''; - - public static async setFigureImage(figure: string): Promise - { - const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, null, { - resetFigure: figure => this.setFigureImage(figure), - dispose: () => - {}, - disposed: false - }); - - if(!avatarImage) return null; - - const isPlaceholder = avatarImage.isPlaceholder(); - - if(isPlaceholder && this.placeHolderImageUrl?.length) return this.placeHolderImageUrl; - - figure = avatarImage.getFigure().getFigureString(); - - const imageUrl = avatarImage.processAsImageUrl(AvatarSetType.HEAD); - const color = avatarImage.getPartColor(AvatarFigurePartType.CHEST); - - if(isPlaceholder) this.placeHolderImageUrl = imageUrl; - - this.AVATAR_COLOR_CACHE.set(figure, ((color && color.rgb) || 16777215)); - this.AVATAR_IMAGE_CACHE.set(figure, imageUrl); - - avatarImage.dispose(); - - return imageUrl; - } - - public static async getUserImage(figure: string): Promise - { - let existing = this.AVATAR_IMAGE_CACHE.get(figure); - - if(!existing) existing = await this.setFigureImage(figure); - - return existing; - } - - public static async getPetImage(figure: string, direction: number, _arg_3: boolean, scale: number = 64, posture: string = null) - { - let existing = this.PET_IMAGE_CACHE.get((figure + posture)); - - if(existing) return existing; - - const figureData = new PetFigureData(figure); - const typeId = figureData.typeId; - const image = GetRoomEngine().getRoomObjectPetImage(typeId, figureData.paletteId, figureData.color, new Vector3d((direction * 45)), scale, null, false, 0, figureData.customParts, posture); - - if(image) - { - existing = await TextureUtils.generateImageUrl(image.data); - - this.PET_IMAGE_CACHE.set((figure + posture), existing); - } - - return existing; - } -} diff --git a/src/api/room/widgets/ChatMessageTypeEnum.ts b/src/api/room/widgets/ChatMessageTypeEnum.ts deleted file mode 100644 index 1a5296b..0000000 --- a/src/api/room/widgets/ChatMessageTypeEnum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class ChatMessageTypeEnum -{ - public static CHAT_DEFAULT: number = 0; - public static CHAT_WHISPER: number = 1; - public static CHAT_SHOUT: number = 2; -} diff --git a/src/api/room/widgets/DimmerFurnitureWidgetPresetItem.ts b/src/api/room/widgets/DimmerFurnitureWidgetPresetItem.ts deleted file mode 100644 index 1a2759f..0000000 --- a/src/api/room/widgets/DimmerFurnitureWidgetPresetItem.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class DimmerFurnitureWidgetPresetItem -{ - constructor( - public id: number = 0, - public type: number = 0, - public color: number = 0, - public light: number = 0) - {} -} diff --git a/src/api/room/widgets/DoChatsOverlap.ts b/src/api/room/widgets/DoChatsOverlap.ts deleted file mode 100644 index 092ce5d..0000000 --- a/src/api/room/widgets/DoChatsOverlap.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ChatBubbleMessage } from './ChatBubbleMessage'; - -export const DoChatsOverlap = (a: ChatBubbleMessage, b: ChatBubbleMessage, additionalBTop: number, padding: number = 0) => -{ - return !((((a.left + padding) + a.width) < (b.left + padding)) || ((a.left + padding) > ((b.left + padding) + b.width)) || ((a.top + a.height) < (b.top + additionalBTop)) || (a.top > ((b.top + additionalBTop) + b.height))); -} - \ No newline at end of file diff --git a/src/api/room/widgets/FurnitureDimmerUtilities.ts b/src/api/room/widgets/FurnitureDimmerUtilities.ts deleted file mode 100644 index f55fc87..0000000 --- a/src/api/room/widgets/FurnitureDimmerUtilities.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { GetRoomEngine } from '@nitrots/nitro-renderer'; -import { GetRoomSession } from '../../nitro'; - -export class FurnitureDimmerUtilities -{ - public static AVAILABLE_COLORS: number[] = [ 7665141, 21495, 15161822, 15353138, 15923281, 8581961, 0 ]; - public static HTML_COLORS: string[] = [ '#74F5F5', '#0053F7', '#E759DE', '#EA4532', '#F2F851', '#82F349', '#000000' ]; - public static MIN_BRIGHTNESS: number = 76; - public static MAX_BRIGHTNESS: number = 255; - - public static savePreset(presetNumber: number, effectTypeId: number, color: number, brightness: number, apply: boolean): void - { - GetRoomSession().updateMoodlightData(presetNumber, effectTypeId, color, brightness, apply); - } - - public static changeState(): void - { - GetRoomSession().toggleMoodlightState(); - } - - public static previewDimmer(color: number, brightness: number, bgOnly: boolean): void - { - GetRoomEngine().updateObjectRoomColor(GetRoomSession().roomId, color, brightness, bgOnly); - } - - public static scaleBrightness(value: number): number - { - return ~~((((value - this.MIN_BRIGHTNESS) * (100 - 0)) / (this.MAX_BRIGHTNESS - this.MIN_BRIGHTNESS)) + 0); - } -} diff --git a/src/api/room/widgets/GetDiskColor.ts b/src/api/room/widgets/GetDiskColor.ts deleted file mode 100644 index 989f294..0000000 --- a/src/api/room/widgets/GetDiskColor.ts +++ /dev/null @@ -1,37 +0,0 @@ -const DISK_COLOR_RED_MIN: number = 130; -const DISK_COLOR_RED_RANGE: number = 100; -const DISK_COLOR_GREEN_MIN: number = 130; -const DISK_COLOR_GREEN_RANGE: number = 100; -const DISK_COLOR_BLUE_MIN: number = 130; -const DISK_COLOR_BLUE_RANGE: number = 100; - -export const GetDiskColor = (name: string) => -{ - let r: number = 0; - let g: number = 0; - let b: number = 0; - let index: number = 0; - - while (index < name.length) - { - switch ((index % 3)) - { - case 0: - r = (r + ( name.charCodeAt(index) * 37) ); - break; - case 1: - g = (g + ( name.charCodeAt(index) * 37) ); - break; - case 2: - b = (b + ( name.charCodeAt(index) * 37) ); - break; - } - index++; - } - - r = ((r % DISK_COLOR_RED_RANGE) + DISK_COLOR_RED_MIN); - g = ((g % DISK_COLOR_GREEN_RANGE) + DISK_COLOR_GREEN_MIN); - b = ((b % DISK_COLOR_BLUE_RANGE) + DISK_COLOR_BLUE_MIN); - - return `rgb(${ r },${ g },${ b })`; -} diff --git a/src/api/room/widgets/IAvatarInfo.ts b/src/api/room/widgets/IAvatarInfo.ts deleted file mode 100644 index 23fb47b..0000000 --- a/src/api/room/widgets/IAvatarInfo.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IAvatarInfo -{ - type: string; -} diff --git a/src/api/room/widgets/ICraftingIngredient.ts b/src/api/room/widgets/ICraftingIngredient.ts deleted file mode 100644 index cb2b031..0000000 --- a/src/api/room/widgets/ICraftingIngredient.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface ICraftingIngredient -{ - name: string; - iconUrl: string; - count: number; -} diff --git a/src/api/room/widgets/ICraftingRecipe.ts b/src/api/room/widgets/ICraftingRecipe.ts deleted file mode 100644 index dd99291..0000000 --- a/src/api/room/widgets/ICraftingRecipe.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface ICraftingRecipe -{ - name: string; - localizedName: string; - iconUrl: string; -} diff --git a/src/api/room/widgets/IPhotoData.ts b/src/api/room/widgets/IPhotoData.ts deleted file mode 100644 index 9a7b846..0000000 --- a/src/api/room/widgets/IPhotoData.ts +++ /dev/null @@ -1,42 +0,0 @@ -export interface IPhotoData -{ - /** - * creator username - */ - n?: string; - - /** - * creator user id - */ - s?: number; - - /** - * photo unique id - */ - u?: number; - - /** - * creation timestamp - */ - t?: number; - - /** - * photo caption - */ - m?: string; - - /** - * photo image url - */ - w?: string; - - /** - * owner id - */ - oi?: number; - - /** - * owner name - */ - o?: string; -} \ No newline at end of file diff --git a/src/api/room/widgets/MannequinUtilities.ts b/src/api/room/widgets/MannequinUtilities.ts deleted file mode 100644 index 9368a79..0000000 --- a/src/api/room/widgets/MannequinUtilities.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { AvatarFigurePartType, GetAvatarRenderManager, IAvatarFigureContainer } from '@nitrots/nitro-renderer'; - -export class MannequinUtilities -{ - public static MANNEQUIN_FIGURE = [ 'hd', 99999, [ 99998 ] ]; - public static MANNEQUIN_CLOTHING_PART_TYPES = [ - AvatarFigurePartType.CHEST_ACCESSORY, - AvatarFigurePartType.COAT_CHEST, - AvatarFigurePartType.CHEST, - AvatarFigurePartType.LEGS, - AvatarFigurePartType.SHOES, - AvatarFigurePartType.WAIST_ACCESSORY - ]; - - public static getMergedMannequinFigureContainer(figure: string, targetFigure: string): IAvatarFigureContainer - { - const figureContainer = GetAvatarRenderManager().createFigureContainer(figure); - const targetFigureContainer = GetAvatarRenderManager().createFigureContainer(targetFigure); - - for(const part of this.MANNEQUIN_CLOTHING_PART_TYPES) figureContainer.removePart(part); - - for(const part of targetFigureContainer.getPartTypeIds()) figureContainer.updatePart(part, targetFigureContainer.getPartSetId(part), targetFigureContainer.getPartColorIds(part)); - - return figureContainer; - } - - public static transformAsMannequinFigure(figureContainer: IAvatarFigureContainer): void - { - for(const part of figureContainer.getPartTypeIds()) - { - if(this.MANNEQUIN_CLOTHING_PART_TYPES.indexOf(part) >= 0) continue; - - figureContainer.removePart(part); - } - - figureContainer.updatePart((this.MANNEQUIN_FIGURE[0] as string), (this.MANNEQUIN_FIGURE[1] as number), (this.MANNEQUIN_FIGURE[2] as number[])); - }; -} diff --git a/src/api/room/widgets/PetSupplementEnum.ts b/src/api/room/widgets/PetSupplementEnum.ts deleted file mode 100644 index eb23687..0000000 --- a/src/api/room/widgets/PetSupplementEnum.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class PetSupplementEnum -{ - public static WATER: number = 0; - public static LIGHT: number = 1; -} diff --git a/src/api/room/widgets/PostureTypeEnum.ts b/src/api/room/widgets/PostureTypeEnum.ts deleted file mode 100644 index 21352d7..0000000 --- a/src/api/room/widgets/PostureTypeEnum.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class PostureTypeEnum -{ - public static POSTURE_STAND: number = 0; - public static POSTURE_SIT: number = 1; -} diff --git a/src/api/room/widgets/RoomDimmerPreset.ts b/src/api/room/widgets/RoomDimmerPreset.ts deleted file mode 100644 index 86600d5..0000000 --- a/src/api/room/widgets/RoomDimmerPreset.ts +++ /dev/null @@ -1,35 +0,0 @@ -export class RoomDimmerPreset -{ - private _id: number; - private _type: number; - private _color: number; - private _brightness: number; - - constructor(id: number, type: number, color: number, brightness: number) - { - this._id = id; - this._type = type; - this._color = color; - this._brightness = brightness; - } - - public get id(): number - { - return this._id; - } - - public get type(): number - { - return this._type; - } - - public get color(): number - { - return this._color; - } - - public get brightness(): number - { - return this._brightness; - } -} diff --git a/src/api/room/widgets/RoomObjectItem.ts b/src/api/room/widgets/RoomObjectItem.ts deleted file mode 100644 index f4fb2d6..0000000 --- a/src/api/room/widgets/RoomObjectItem.ts +++ /dev/null @@ -1,28 +0,0 @@ -export class RoomObjectItem -{ - private _id: number; - private _category: number; - private _name: string; - - constructor(id: number, category: number, name: string) - { - this._id = id; - this._category = category; - this._name = name; - } - - public get id(): number - { - return this._id; - } - - public get category(): number - { - return this._category; - } - - public get name(): string - { - return this._name; - } -} diff --git a/src/api/room/widgets/UseProductItem.ts b/src/api/room/widgets/UseProductItem.ts deleted file mode 100644 index d3e2088..0000000 --- a/src/api/room/widgets/UseProductItem.ts +++ /dev/null @@ -1,12 +0,0 @@ -export class UseProductItem -{ - constructor( - public readonly id: number, - public readonly category: number, - public readonly name: string, - public readonly requestRoomObjectId: number, - public readonly targetRoomObjectId: number, - public readonly requestInventoryStripId: number, - public readonly replace: boolean) - {} -} diff --git a/src/api/room/widgets/VoteValue.ts b/src/api/room/widgets/VoteValue.ts deleted file mode 100644 index ecf4336..0000000 --- a/src/api/room/widgets/VoteValue.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const VALUE_KEY_DISLIKE = '0'; -export const VALUE_KEY_LIKE = '1'; - -export interface VoteValue -{ - value: string; - secondsLeft: number; -} diff --git a/src/api/room/widgets/YoutubeVideoPlaybackStateEnum.ts b/src/api/room/widgets/YoutubeVideoPlaybackStateEnum.ts deleted file mode 100644 index 3a885d1..0000000 --- a/src/api/room/widgets/YoutubeVideoPlaybackStateEnum.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class YoutubeVideoPlaybackStateEnum -{ - public static readonly UNSTARTED = -1; - public static readonly ENDED = 0; - public static readonly PLAYING = 1; - public static readonly PAUSED = 2; - public static readonly BUFFERING = 3; - public static readonly CUED = 5; -} diff --git a/src/api/room/widgets/index.ts b/src/api/room/widgets/index.ts deleted file mode 100644 index 6c50c83..0000000 --- a/src/api/room/widgets/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -export * from './AvatarInfoFurni'; -export * from './AvatarInfoName'; -export * from './AvatarInfoPet'; -export * from './AvatarInfoRentableBot'; -export * from './AvatarInfoUser'; -export * from './AvatarInfoUtilities'; -export * from './BotSkillsEnum'; -export * from './ChatBubbleMessage'; -export * from './ChatBubbleUtilities'; -export * from './ChatMessageTypeEnum'; -export * from './DimmerFurnitureWidgetPresetItem'; -export * from './DoChatsOverlap'; -export * from './FurnitureDimmerUtilities'; -export * from './GetDiskColor'; -export * from './IAvatarInfo'; -export * from './ICraftingIngredient'; -export * from './ICraftingRecipe'; -export * from './IPhotoData'; -export * from './MannequinUtilities'; -export * from './PetSupplementEnum'; -export * from './PostureTypeEnum'; -export * from './RoomDimmerPreset'; -export * from './RoomObjectItem'; -export * from './UseProductItem'; -export * from './VoteValue'; -export * from './YoutubeVideoPlaybackStateEnum'; diff --git a/src/api/user/GetUserProfile.ts b/src/api/user/GetUserProfile.ts deleted file mode 100644 index 13c67aa..0000000 --- a/src/api/user/GetUserProfile.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { UserProfileComposer } from '@nitrots/nitro-renderer'; -import { SendMessageComposer } from '../nitro'; - -export function GetUserProfile(userId: number): void -{ - SendMessageComposer(new UserProfileComposer(userId)); -} diff --git a/src/api/user/index.ts b/src/api/user/index.ts deleted file mode 100644 index 1c609ea..0000000 --- a/src/api/user/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './GetUserProfile'; diff --git a/src/api/utils/CloneObject.ts b/src/api/utils/CloneObject.ts deleted file mode 100644 index 6cd8d3e..0000000 --- a/src/api/utils/CloneObject.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const CloneObject = (object: T): T => -{ - if((object == null) || ('object' != typeof object)) return object; - - // @ts-ignore - const copy = new object.constructor(); - - for(const attr in object) - { - if(object.hasOwnProperty(attr)) copy[attr] = object[attr]; - } - - return copy; -} diff --git a/src/api/utils/ColorUtils.ts b/src/api/utils/ColorUtils.ts deleted file mode 100644 index c32f8fb..0000000 --- a/src/api/utils/ColorUtils.ts +++ /dev/null @@ -1,65 +0,0 @@ -export class ColorUtils -{ - public static makeColorHex(color: string): string - { - return ('#' + color); - } - - public static makeColorNumberHex(color: number): string - { - let val = color.toString(16); - return ( '#' + val.padStart(6, '0')); - } - - public static convertFromHex(color: string): number - { - return parseInt(color.replace('#', ''), 16); - } - - public static uintHexColor(color: number): string - { - const realColor = color >>>0; - - return ColorUtils.makeColorHex(realColor.toString(16).substring(2)); - } - - /** - * Converts an integer format into an array of 8-bit values - * @param {number} value value in integer format - * @returns {Array} 8-bit values - */ - public static int_to_8BitVals(value: number): [number, number, number, number] - { - const val1 = ((value >> 24) & 0xFF) - const val2 = ((value >> 16) & 0xFF); - const val3 = ((value >> 8) & 0xFF); - const val4 = (value & 0xFF); - - return [ val1, val2, val3, val4 ]; - } - - /** - * Combines 4 8-bit values into a 32-bit integer. Values are combined in - * in the order of the parameters - * @param val1 - * @param val2 - * @param val3 - * @param val4 - * @returns 32-bit integer of combined values - */ - public static eight_bitVals_to_int(val1: number, val2: number, val3: number, val4: number): number - { - return (((val1) << 24) + ((val2) << 16) + ((val3) << 8) + (val4| 0)); - } - - 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(',') + ')'; - } -} diff --git a/src/api/utils/ConvertSeconds.ts b/src/api/utils/ConvertSeconds.ts deleted file mode 100644 index f559dea..0000000 --- a/src/api/utils/ConvertSeconds.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const ConvertSeconds = (seconds: number) => -{ - let numDays = Math.floor(seconds / 86400); - let numHours = Math.floor((seconds % 86400) / 3600); - let numMinutes = Math.floor(((seconds % 86400) % 3600) / 60); - let numSeconds = ((seconds % 86400) % 3600) % 60; - - return numDays.toString().padStart(2, '0') + ':' + numHours.toString().padStart(2, '0') + ':' + numMinutes.toString().padStart(2, '0') + ':' + numSeconds.toString().padStart(2, '0'); -} diff --git a/src/api/utils/FixedSizeStack.ts b/src/api/utils/FixedSizeStack.ts deleted file mode 100644 index af8e09a..0000000 --- a/src/api/utils/FixedSizeStack.ts +++ /dev/null @@ -1,65 +0,0 @@ -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 addValue(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 getMax(): 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 getMin(): 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; - } -} diff --git a/src/api/utils/FriendlyTime.ts b/src/api/utils/FriendlyTime.ts deleted file mode 100644 index 7acb39c..0000000 --- a/src/api/utils/FriendlyTime.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { LocalizeText } from './LocalizeText'; - -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 LocalizeText(key, [ 'amount' ], [ amount.toString() ]); - } -} diff --git a/src/api/utils/GetLocalStorage.ts b/src/api/utils/GetLocalStorage.ts deleted file mode 100644 index 769df6d..0000000 --- a/src/api/utils/GetLocalStorage.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const GetLocalStorage = (key: string) => -{ - try - { - JSON.parse(window.localStorage.getItem(key)) as T ?? null - } - catch(e) - { - return null; - } -} diff --git a/src/api/utils/LocalStorageKeys.ts b/src/api/utils/LocalStorageKeys.ts deleted file mode 100644 index 6c92279..0000000 --- a/src/api/utils/LocalStorageKeys.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class LocalStorageKeys -{ - public static CATALOG_PLACE_MULTIPLE_OBJECTS: string = 'catalogPlaceMultipleObjects'; - public static CATALOG_SKIP_PURCHASE_CONFIRMATION: string = 'catalogSkipPurchaseConfirmation'; -} diff --git a/src/api/utils/LocalizeBadgeDescription.ts b/src/api/utils/LocalizeBadgeDescription.ts deleted file mode 100644 index acf3795..0000000 --- a/src/api/utils/LocalizeBadgeDescription.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { GetLocalizationManager } from '@nitrots/nitro-renderer'; - -export const LocalizeBadgeDescription = (key: string) => -{ - let badgeDesc = GetLocalizationManager().getBadgeDesc(key); - - if(!badgeDesc || !badgeDesc.length) badgeDesc = `badge_desc_${ key }`; - - return badgeDesc; -} diff --git a/src/api/utils/LocalizeBageName.ts b/src/api/utils/LocalizeBageName.ts deleted file mode 100644 index 50d6ac5..0000000 --- a/src/api/utils/LocalizeBageName.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { GetLocalizationManager } from '@nitrots/nitro-renderer'; - -export const LocalizeBadgeName = (key: string) => -{ - let badgeName = GetLocalizationManager().getBadgeName(key); - - if(!badgeName || !badgeName.length) badgeName = `badge_name_${ key }`; - - return badgeName; -} diff --git a/src/api/utils/LocalizeFormattedNumber.ts b/src/api/utils/LocalizeFormattedNumber.ts deleted file mode 100644 index fab30d4..0000000 --- a/src/api/utils/LocalizeFormattedNumber.ts +++ /dev/null @@ -1,6 +0,0 @@ -export function LocalizeFormattedNumber(number: number): string -{ - if(!number || isNaN(number)) return '0'; - - return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' '); -}; diff --git a/src/api/utils/LocalizeShortNumber.ts b/src/api/utils/LocalizeShortNumber.ts deleted file mode 100644 index 30975ec..0000000 --- a/src/api/utils/LocalizeShortNumber.ts +++ /dev/null @@ -1,36 +0,0 @@ -export function LocalizeShortNumber(number: number): string -{ - if(!number || isNaN(number)) return '0'; - - let abs = Math.abs(number); - - const rounder = Math.pow(10, 1); - const isNegative = (number < 0); - - let key = ''; - - const powers = [ - { key: 'Q', value: Math.pow(10, 15) }, - { key: 'T', value: Math.pow(10, 12) }, - { key: 'B', value: Math.pow(10, 9) }, - { key: 'M', value: Math.pow(10, 6) }, - { key: 'K', value: 1000 } - ]; - - for(const power of powers) - { - let reduced = abs / power.value; - - reduced = Math.round(reduced * rounder) / rounder; - - if(reduced >= 1) - { - abs = reduced; - key = power.key; - - break; - } - } - - return ((isNegative ? '-' : '') + abs + key); -} diff --git a/src/api/utils/LocalizeText.ts b/src/api/utils/LocalizeText.ts deleted file mode 100644 index 68d0273..0000000 --- a/src/api/utils/LocalizeText.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GetLocalizationManager } from '@nitrots/nitro-renderer'; - -export function LocalizeText(key: string, parameters: string[] = null, replacements: string[] = null): string -{ - return GetLocalizationManager().getValueWithParameters(key, parameters, replacements); -} diff --git a/src/api/utils/PlaySound.ts b/src/api/utils/PlaySound.ts deleted file mode 100644 index 0f9a39d..0000000 --- a/src/api/utils/PlaySound.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { MouseEventType, NitroSoundEvent } from '@nitrots/nitro-renderer'; -import { DispatchMainEvent } from '../events'; - -let canPlaySound = false; - -export const PlaySound = (sampleCode: string) => -{ - if(!canPlaySound) return; - - DispatchMainEvent(new NitroSoundEvent(NitroSoundEvent.PLAY_SOUND, sampleCode)); -} - -const eventTypes = [ MouseEventType.MOUSE_CLICK ]; - -const startListening = () => -{ - const stopListening = () => eventTypes.forEach(type => window.removeEventListener(type, onEvent)); - - const onEvent = (event: Event) => ((canPlaySound = true) && stopListening()); - - eventTypes.forEach(type => window.addEventListener(type, onEvent)); -} - -startListening(); diff --git a/src/api/utils/ProductImageUtility.ts b/src/api/utils/ProductImageUtility.ts deleted file mode 100644 index b12c43d..0000000 --- a/src/api/utils/ProductImageUtility.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { CatalogPageMessageProductData, GetRoomEngine } from '@nitrots/nitro-renderer'; -import { FurniCategory } from '../inventory'; - -export class ProductImageUtility -{ - public static getProductImageUrl(productType: string, furniClassId: number, extraParam: string): string - { - let imageUrl: string = null; - - switch(productType) - { - case CatalogPageMessageProductData.S: - imageUrl = GetRoomEngine().getFurnitureFloorIconUrl(furniClassId); - break; - case CatalogPageMessageProductData.I: - const productCategory = this.getProductCategory(CatalogPageMessageProductData.I, furniClassId); - - if(productCategory === 1) - { - imageUrl = GetRoomEngine().getFurnitureWallIconUrl(furniClassId, extraParam); - } - else - { - switch(productCategory) - { - case FurniCategory.WALL_PAPER: - break; - case FurniCategory.LANDSCAPE: - break; - case FurniCategory.FLOOR: - break; - } - } - break; - case CatalogPageMessageProductData.E: - // fx_icon_furniClassId_png - break; - } - - return imageUrl; - } - - public static getProductCategory(productType: string, furniClassId: number): number - { - if(productType === CatalogPageMessageProductData.S) return 1; - - if(productType === CatalogPageMessageProductData.I) - { - if(furniClassId === 3001) return FurniCategory.WALL_PAPER; - - if(furniClassId === 3002) return FurniCategory.FLOOR; - - if(furniClassId === 4057) return FurniCategory.LANDSCAPE; - } - - return 1; - } -} diff --git a/src/api/utils/Randomizer.ts b/src/api/utils/Randomizer.ts deleted file mode 100644 index 1f67a12..0000000 --- a/src/api/utils/Randomizer.ts +++ /dev/null @@ -1,28 +0,0 @@ -export class Randomizer -{ - public static getRandomNumber(count: number): number - { - return Math.floor(Math.random() * count); - } - - public static getRandomElement(elements: T[]): T - { - return elements[this.getRandomNumber(elements.length)]; - } - - public static getRandomElements(elements: T[], count: number): T[] - { - const result: T[] = new Array(count); - let len = elements.length; - const taken = new Array(len); - - while(count--) - { - var x = this.getRandomNumber(len); - result[count] = elements[x in taken ? taken[x] : x]; - taken[x] = --len in taken ? taken[len] : len; - } - - return result; - } -} diff --git a/src/api/utils/RoomChatFormatter.ts b/src/api/utils/RoomChatFormatter.ts deleted file mode 100644 index a24cdf5..0000000 --- a/src/api/utils/RoomChatFormatter.ts +++ /dev/null @@ -1,75 +0,0 @@ -const allowedColours: Map = new Map(); - -allowedColours.set('r', 'red'); -allowedColours.set('b', 'blue'); -allowedColours.set('g', 'green'); -allowedColours.set('y', 'yellow'); -allowedColours.set('w', 'white'); -allowedColours.set('o', 'orange'); -allowedColours.set('c', 'cyan'); -allowedColours.set('br', 'brown'); -allowedColours.set('pr', 'purple'); -allowedColours.set('pk', 'pink'); - -allowedColours.set('red', 'red'); -allowedColours.set('blue', 'blue'); -allowedColours.set('green', 'green'); -allowedColours.set('yellow', 'yellow'); -allowedColours.set('white', 'white'); -allowedColours.set('orange', 'orange'); -allowedColours.set('cyan', 'cyan'); -allowedColours.set('brown', 'brown'); -allowedColours.set('purple', 'purple'); -allowedColours.set('pink', 'pink'); - -const encodeHTML = (str: string) => -{ - return str.replace(/([\u00A0-\u9999<>&])(.|$)/g, (full, char, next) => - { - if(char !== '&' || next !== '#') - { - if(/[\u00A0-\u9999<>&]/.test(next)) next = '&#' + next.charCodeAt(0) + ';'; - - return '&#' + char.charCodeAt(0) + ';' + next; - } - - return full; - }); -} - -export const RoomChatFormatter = (content: string) => -{ - let result = ''; - - content = encodeHTML(content); - //content = (joypixels.shortnameToUnicode(content) as string) - - if(content.startsWith('@') && content.indexOf('@', 1) > -1) - { - let match = null; - - while((match = /@[a-zA-Z]+@/g.exec(content)) !== null) - { - const colorTag = match[0].toString(); - const colorName = colorTag.substr(1, colorTag.length - 2); - const text = content.replace(colorTag, ''); - - if(!allowedColours.has(colorName)) - { - result = text; - } - else - { - const color = allowedColours.get(colorName); - result = '' + text + ''; - } - break; - } - } - else - { - result = content; - } - - return result; -} diff --git a/src/api/utils/SetLocalStorage.ts b/src/api/utils/SetLocalStorage.ts deleted file mode 100644 index 02aa8f3..0000000 --- a/src/api/utils/SetLocalStorage.ts +++ /dev/null @@ -1 +0,0 @@ -export const SetLocalStorage = (key: string, value: T) => window.localStorage.setItem(key, JSON.stringify(value)); diff --git a/src/api/utils/SoundNames.ts b/src/api/utils/SoundNames.ts deleted file mode 100644 index 4459651..0000000 --- a/src/api/utils/SoundNames.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class SoundNames -{ - public static CAMERA_SHUTTER = 'camera_shutter'; - public static CREDITS = 'credits'; - public static DUCKETS = 'duckets'; - public static MESSENGER_NEW_THREAD = 'messenger_new_thread'; - public static MESSENGER_MESSAGE_RECEIVED = 'messenger_message_received'; - public static MODTOOLS_NEW_TICKET = 'modtools_new_ticket'; -} diff --git a/src/api/utils/WindowSaveOptions.ts b/src/api/utils/WindowSaveOptions.ts deleted file mode 100644 index 9aa8456..0000000 --- a/src/api/utils/WindowSaveOptions.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface WindowSaveOptions -{ - offset: { x: number, y: number }; - size: { width: number, height: number }; -} diff --git a/src/api/utils/index.ts b/src/api/utils/index.ts deleted file mode 100644 index 1824add..0000000 --- a/src/api/utils/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -export * from './CloneObject'; -export * from './ColorUtils'; -export * from './ConvertSeconds'; -export * from './FixedSizeStack'; -export * from './FriendlyTime'; -export * from './GetLocalStorage'; -export * from './LocalStorageKeys'; -export * from './LocalizeBadgeDescription'; -export * from './LocalizeBageName'; -export * from './LocalizeFormattedNumber'; -export * from './LocalizeShortNumber'; -export * from './LocalizeText'; -export * from './PlaySound'; -export * from './ProductImageUtility'; -export * from './Randomizer'; -export * from './RoomChatFormatter'; -export * from './SetLocalStorage'; -export * from './SoundNames'; -export * from './WindowSaveOptions'; diff --git a/src/api/wired/GetWiredTimeLocale.ts b/src/api/wired/GetWiredTimeLocale.ts deleted file mode 100644 index 49025fe..0000000 --- a/src/api/wired/GetWiredTimeLocale.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const GetWiredTimeLocale = (value: number) => -{ - const time = Math.floor((value / 2)); - - if(!(value % 2)) return time.toString(); - - return (time + 0.5).toString(); -} diff --git a/src/api/wired/WiredActionLayoutCode.ts b/src/api/wired/WiredActionLayoutCode.ts deleted file mode 100644 index 5282dc5..0000000 --- a/src/api/wired/WiredActionLayoutCode.ts +++ /dev/null @@ -1,29 +0,0 @@ -export class WiredActionLayoutCode -{ - public static TOGGLE_FURNI_STATE: number = 0; - public static RESET: number = 1; - public static SET_FURNI_STATE: number = 3; - public static MOVE_FURNI: number = 4; - public static GIVE_SCORE: number = 6; - public static CHAT: number = 7; - public static TELEPORT: number = 8; - public static JOIN_TEAM: number = 9; - public static LEAVE_TEAM: number = 10; - public static CHASE: number = 11; - public static FLEE: number = 12; - public static MOVE_AND_ROTATE_FURNI: number = 13; - public static GIVE_SCORE_TO_PREDEFINED_TEAM: number = 14; - public static TOGGLE_TO_RANDOM_STATE: number = 15; - public static MOVE_FURNI_TO: number = 16; - public static GIVE_REWARD: number = 17; - public static CALL_ANOTHER_STACK: number = 18; - public static KICK_FROM_ROOM: number = 19; - public static MUTE_USER: number = 20; - public static BOT_TELEPORT: number = 21; - public static BOT_MOVE: number = 22; - public static BOT_TALK: number = 23; - public static BOT_GIVE_HAND_ITEM: number = 24; - public static BOT_FOLLOW_AVATAR: number = 25; - public static BOT_CHANGE_FIGURE: number = 26; - public static BOT_TALK_DIRECT_TO_AVTR: number = 27; -} diff --git a/src/api/wired/WiredConditionLayoutCode.ts b/src/api/wired/WiredConditionLayoutCode.ts deleted file mode 100644 index 58cae5d..0000000 --- a/src/api/wired/WiredConditionLayoutCode.ts +++ /dev/null @@ -1,29 +0,0 @@ -export class WiredConditionlayout -{ - public static STATES_MATCH: number = 0; - public static FURNIS_HAVE_AVATARS: number = 1; - public static ACTOR_IS_ON_FURNI: number = 2; - public static TIME_ELAPSED_MORE: number = 3; - public static TIME_ELAPSED_LESS: number = 4; - public static USER_COUNT_IN: number = 5; - public static ACTOR_IS_IN_TEAM: number = 6; - public static HAS_STACKED_FURNIS: number = 7; - public static STUFF_TYPE_MATCHES: number = 8; - public static STUFFS_IN_FORMATION: number = 9; - public static ACTOR_IS_GROUP_MEMBER: number = 10; - public static ACTOR_IS_WEARING_BADGE: number = 11; - public static ACTOR_IS_WEARING_EFFECT: number = 12; - public static NOT_STATES_MATCH: number = 13; - public static FURNI_NOT_HAVE_HABBO: number = 14; - public static NOT_ACTOR_ON_FURNI: number = 15; - public static NOT_USER_COUNT_IN: number = 16; - public static NOT_ACTOR_IN_TEAM: number = 17; - public static NOT_HAS_STACKED_FURNIS: number = 18; - public static NOT_FURNI_IS_OF_TYPE: number = 19; - public static NOT_STUFFS_IN_FORMATION: number = 20; - public static NOT_ACTOR_IN_GROUP: number = 21; - public static NOT_ACTOR_WEARS_BADGE: number = 22; - public static NOT_ACTOR_WEARING_EFFECT: number = 23; - public static DATE_RANGE_ACTIVE: number = 24; - public static ACTOR_HAS_HANDITEM: number = 25; -} diff --git a/src/api/wired/WiredDateToString.ts b/src/api/wired/WiredDateToString.ts deleted file mode 100644 index 825adc8..0000000 --- a/src/api/wired/WiredDateToString.ts +++ /dev/null @@ -1 +0,0 @@ -export const WiredDateToString = (date: Date) => `${ date.getFullYear() }/${ ('0' + (date.getMonth() + 1)).slice(-2) }/${ ('0' + date.getDate()).slice(-2) } ${ ('0' + date.getHours()).slice(-2) }:${ ('0' + date.getMinutes()).slice(-2) }`; diff --git a/src/api/wired/WiredFurniType.ts b/src/api/wired/WiredFurniType.ts deleted file mode 100644 index 447e970..0000000 --- a/src/api/wired/WiredFurniType.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class WiredFurniType -{ - public static STUFF_SELECTION_OPTION_NONE: number = 0; - public static STUFF_SELECTION_OPTION_BY_ID: number = 1; - public static STUFF_SELECTION_OPTION_BY_ID_OR_BY_TYPE: number = 2; - public static STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT: number = 3; -} diff --git a/src/api/wired/WiredSelectionVisualizer.ts b/src/api/wired/WiredSelectionVisualizer.ts deleted file mode 100644 index 18edbf7..0000000 --- a/src/api/wired/WiredSelectionVisualizer.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { GetRoomEngine, IRoomObject, IRoomObjectSpriteVisualization, RoomObjectCategory, WiredFilter } from '@nitrots/nitro-renderer'; - -export class WiredSelectionVisualizer -{ - private static _selectionShader: WiredFilter = new WiredFilter({ - lineColor: [ 1, 1, 1 ], - color: [ 0.6, 0.6, 0.6 ] - }); - - public static show(furniId: number): void - { - WiredSelectionVisualizer.applySelectionShader(WiredSelectionVisualizer.getRoomObject(furniId)); - } - - public static hide(furniId: number): void - { - WiredSelectionVisualizer.clearSelectionShader(WiredSelectionVisualizer.getRoomObject(furniId)); - } - - public static clearSelectionShaderFromFurni(furniIds: number[]): void - { - for(const furniId of furniIds) - { - WiredSelectionVisualizer.clearSelectionShader(WiredSelectionVisualizer.getRoomObject(furniId)); - } - } - - public static applySelectionShaderToFurni(furniIds: number[]): void - { - for(const furniId of furniIds) - { - WiredSelectionVisualizer.applySelectionShader(WiredSelectionVisualizer.getRoomObject(furniId)); - } - } - - private static getRoomObject(objectId: number): IRoomObject - { - const roomEngine = GetRoomEngine(); - - return roomEngine.getRoomObject(roomEngine.activeRoomId, objectId, RoomObjectCategory.FLOOR); - } - - private static applySelectionShader(roomObject: IRoomObject): void - { - if(!roomObject) return; - - const visualization = (roomObject.visualization as IRoomObjectSpriteVisualization); - - if(!visualization) return; - - for(const sprite of visualization.sprites) - { - if(sprite.blendMode === 'add') continue; - - if(!sprite.filters) sprite.filters = []; - - sprite.filters.push(WiredSelectionVisualizer._selectionShader); - - sprite.increaseUpdateCounter(); - } - } - - private static clearSelectionShader(roomObject: IRoomObject): void - { - if(!roomObject) return; - - const visualization = (roomObject.visualization as IRoomObjectSpriteVisualization); - - if(!visualization) return; - - for(const sprite of visualization.sprites) - { - if(!sprite.filters) continue; - - const index = sprite.filters.indexOf(WiredSelectionVisualizer._selectionShader); - - if(index >= 0) - { - sprite.filters.splice(index, 1); - - sprite.increaseUpdateCounter(); - } - } - } -} diff --git a/src/api/wired/WiredStringDelimeter.ts b/src/api/wired/WiredStringDelimeter.ts deleted file mode 100644 index bc4cf2e..0000000 --- a/src/api/wired/WiredStringDelimeter.ts +++ /dev/null @@ -1 +0,0 @@ -export const WIRED_STRING_DELIMETER: string = '\t'; diff --git a/src/api/wired/WiredTriggerLayoutCode.ts b/src/api/wired/WiredTriggerLayoutCode.ts deleted file mode 100644 index fd758df..0000000 --- a/src/api/wired/WiredTriggerLayoutCode.ts +++ /dev/null @@ -1,17 +0,0 @@ -export class WiredTriggerLayout -{ - public static AVATAR_SAYS_SOMETHING: number = 0; - public static AVATAR_WALKS_ON_FURNI: number = 1; - public static AVATAR_WALKS_OFF_FURNI: number = 2; - public static EXECUTE_ONCE: number = 3; - public static TOGGLE_FURNI: number = 4; - public static EXECUTE_PERIODICALLY: number = 6; - public static AVATAR_ENTERS_ROOM: number = 7; - public static GAME_STARTS: number = 8; - public static GAME_ENDS: number = 9; - public static SCORE_ACHIEVED: number = 10; - public static COLLISION: number = 11; - public static EXECUTE_PERIODICALLY_LONG: number = 12; - public static BOT_REACHED_STUFF: number = 13; - public static BOT_REACHED_AVATAR: number = 14; -} diff --git a/src/api/wired/index.ts b/src/api/wired/index.ts deleted file mode 100644 index 6590adf..0000000 --- a/src/api/wired/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export * from './GetWiredTimeLocale'; -export * from './WiredActionLayoutCode'; -export * from './WiredConditionLayoutCode'; -export * from './WiredDateToString'; -export * from './WiredFurniType'; -export * from './WiredSelectionVisualizer'; -export * from './WiredStringDelimeter'; -export * from './WiredTriggerLayoutCode'; diff --git a/src/assets/images/achievements/back-arrow.png b/src/assets/images/achievements/back-arrow.png deleted file mode 100644 index e795c0ee17a2c814a38a2162768cea21d1415327..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 331 zcmeAS@N?(olHy`uVBq!ia0vp^ia@Ny!3-pyt#kMcq!^2X+?^QKos)S9^9T5ZxB}^$H*fy`|39ay8OWaA{>2MOv6ck+1p@{DGyLAh7Yr2OEbxdd zW?urU&rLVW89&r!frI5JWMbB%utImyY{}>HFbLOx7 RSP$|ngQu&X%Q~loCIDqWec1p2 diff --git a/src/assets/images/avatareditor/arrow-left-icon.png b/src/assets/images/avatareditor/arrow-left-icon.png deleted file mode 100644 index f94a7dfdd74fedb7e359d24ca60df046b92f5d96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^GC(ZK!3HElnfhXYRIjItV~9uR(J6s^2NXD*6F>e7 zFN;(xN1y`;ub@ac-@%FyZMczwQ!VaBim-gV} zHLN{n1gjlyY=}}Qkh5mO3C!NTWW<2{{ rd%>5 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 diff --git a/src/assets/images/avatareditor/ca-selected-icon.png b/src/assets/images/avatareditor/ca-selected-icon.png deleted file mode 100644 index b118c3ed606a0dcc4f80f16b734481d1f9648bf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%3?x6Bmj(hU#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6-M0X`wFrB?h)O2i)>Q2zhGKd^J^+8h7VHtYdP%3nFu1f)1hg8YL2Ljc3Q z=Dm?XG0p;y$YKTtzQZ8Qcszea3Q%y3r;B5VMsV!}PO-xZ94>_`@BKeEx3%TT(wBS0 z3il}(ZW9S#x>R88_g^y&59HriCRJ9%+b1R4``wC&@9GvDvU%kAX) UJFE9tGtk`(p00i_>zopr0JCL=CjbBd diff --git a/src/assets/images/avatareditor/cc-icon.png b/src/assets/images/avatareditor/cc-icon.png deleted file mode 100644 index 4a8844e49c173bce47e93ac4fdc082b9a02db93b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^@<1%h!3-o*cen#d2FBtbcPEB*=VV?2IV|apzK#qG z8~eHcB(eheYymzYuB%tC1~R=BGZKLmQ%R6t@PCG<+YP*cJkA1-$YKTtzQZ8Qcszea z3Q(}$)5S5w!hdRiAm0H69;dJWrpIM6&Rr?L&n0zFT3+%bLz(X}id_del(Jc>k3~o& z{JGATetkQuUQ&+jzGltcwW|GgW^zxCrXQQP@P<-Ez4wz){j>kh>eqgr_rhiiTUCDT z=Vy;>Fa3V@k7wSbbrYm!?_C*o>Yj3F@a^*N>R*>wC7e&M{w#c)k?-L2k1Q*m|6%y^ XjcH^3xig=DPGj(N^>bP0l+XkKEAnbY diff --git a/src/assets/images/avatareditor/cc-selected-icon.png b/src/assets/images/avatareditor/cc-selected-icon.png deleted file mode 100644 index 3493751af159b7b23c4ca77cc536e885758b500d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^@<1%h!3-o*cen#d2FBtbcPEB*=VV?2IV|apzK#qG z8~eHcB(ehe`~f~8t_(&YD-K_(o4O&acoIIKNf-ZeOfgnYrMkJ8MttJO!Qv?bK^! z-xCF9KTbuP$4%w7 zUvqvz<*}&(*72Di#e|mp@^9R?N6YKe?A$+F_i+V%>L_0nUnH7;mdUc@W?04NJ&}H0 bAEV?qbh90lIj_kH^ag{ctDnm{r-UW|;Xr}e diff --git a/src/assets/images/avatareditor/ch-icon.png b/src/assets/images/avatareditor/ch-icon.png deleted file mode 100644 index ef7da1131b33a74fbc636893bee218a0e8fc1e9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^vOp}s!3-n~8`%1Q6k~CayA#8@b22Z19F}xPUq=Rp zjs4tz5?O(Kwg8_H*VU_61DW268HqrOsU*lR_&>wb?FL>z9%q3^WHAE+-(e7DJf6QI z1t=Kl>Ealo5&X7~k?(*42lLba^W{V~SQz|1pm)n*^&_EV$rU_h0pd>j-2u&e-)(vP zNUl+1c3;|ef%UGYAEzee**{vhYQ6ZE<@M9e+aKobv|r+@T_0t6sc)AOzgZ4b(3$x= R{ehM+c)I$ztaD0e0su4!N%{Z) diff --git a/src/assets/images/avatareditor/ch-selected-icon.png b/src/assets/images/avatareditor/ch-selected-icon.png deleted file mode 100644 index c5e9f3402c61cf8041f5555d09e633395f0c6e1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^vOp}s!3-n~8`%1Q6k~CayA#8@b22Z19F}xPUq=Rp zjs4tz5?O(K{s5m4*BSwVTb@q;GivuMDFMX}b<7QvtYXYby9AtTu4%PmiZLn^zX1eC2N zny$Rfa7$GxKl@yvo`u)qpgb%0<)^Z(7kr+`+!65I%;K%5wT{!z6$;XmHyLdYn;E!v xs$;9E8Ef?C=eN?=-+lD{+WeZ0`5St7Ficv=@`S(Y+I*nJ44$rjF6*2UngCQATr>ax diff --git a/src/assets/images/avatareditor/clear-icon.png b/src/assets/images/avatareditor/clear-icon.png deleted file mode 100644 index e0d50abca8bec826229748f4b83deb79888594af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ej#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6-$0X`wF_4V~f4(;E#ZY5Aa=f>$fAax}{e!>6$|7UQ}TKNUY=PdAuEM{Qf zI}E~%$MaXD00nD3T^vI+f@9BK6l*ZxU<%0o|Ns0=2i97NzT1(7&)+!8`k!-~vZ3`& zMqB7q&NAW6c~&mnS{@mb4_%jPsh2$%&9G zmoNLZE=rwryL_l@|E*lxWQo}PtW$!Y%=830gu&C* K&t;ucLK6Vke`HAj diff --git a/src/assets/images/avatareditor/cp-icon.png b/src/assets/images/avatareditor/cp-icon.png deleted file mode 100644 index 5e460f153c0b0988a9505db216b28110b07db358..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^azHG>!3-pCZQt7qq!^2X+?^QKos)S9vjzBsxUOEk8p!lk%t!=MOeH~n!T%YaZa44(@;D1TB8wRq_zr_GaKbQY1a@}Fm6}m~`>&q8vu)N;TVYE!|+a`u&wO72?R>qmV qDeV;h-&3mp_?i0O4ry20=Zxl?n5-6Pvfcn%&fw|l=d#Wzp$P!U99262 diff --git a/src/assets/images/avatareditor/cp-selected-icon.png b/src/assets/images/avatareditor/cp-selected-icon.png deleted file mode 100644 index a067085d27617cfad160ea776fe1a47c29d505a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^azHG>!3-pCZQt7qq!^2X+?^QKos)S93kCRuxXzzHf7!BSjvd+ue;ds_F9H;HRZvU-Qfwtbe!>4ifMN6gCHsLQ zoCO|{#S9F5he4R}c>anMpkS@1i(`mJ@Y)H1d<_ab&Z1BLg>Q@9e&Ea(=h}gjE$ zrMtLq_Vb|0Dlz3n6QX(BHB1lsO>$A0_TuQ1UcdcMCt2OkUMgO9g;k=zkjY<`+w1Kw Skx-yR7(8A5T-G@yGywo)XJ@+r diff --git a/src/assets/images/avatareditor/ea-icon.png b/src/assets/images/avatareditor/ea-icon.png deleted file mode 100644 index c227ae10719909356e47d91a1e909c2cbeb4f16f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^%0Mi@!3-oNn{1`*#dk*TvxAN4P<&NW+VbBrjj7P;QtIyw;Ol?d7K3vk;M!Qe1}1p@p%4< z6rf;%r;B5VMsR7LHy?u{kJItr@l_3%`rYm?V)g2|ZzR9bE{5xkV7rX@dY?&sNwHeW zSN4QiJ*xQj|&KtsII?S=#xz@NXRLSDxzI>gztmzv^kx13es6AH78|{>K_<6k* o^!+p0h3^gHS)UcX!YUeGT0cbaar>mdKI;Vst0AOQM?*IS* diff --git a/src/assets/images/avatareditor/ea-selected-icon.png b/src/assets/images/avatareditor/ea-selected-icon.png deleted file mode 100644 index e7678c4a6e23d14dce0ebe95250d35b4a9d2878a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^%0Mi@!3-oNn{1`g#vs+T!FNUtKIw~m;V3%zvsa_AlGRJgD{X{D+%%o1`7WF&#-y_lKnst z&H|6fVg?4j!ywFfJby(BP_W(fgu4wvK>mrA%^C$L3{&Ts;&@aBEh~;MRnH|2FRjvt zdO!6#|KFAsu|6LAln$Ix(La>LSFVdQ&MBb@00~QN0RR91 diff --git a/src/assets/images/avatareditor/fa-icon.png b/src/assets/images/avatareditor/fa-icon.png deleted file mode 100644 index 9b72ff5e388aab53852cf97e5cf7e0ddc54e8172..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^(m*W2!3-q5W43JqQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`*#dk*TvxAN4N|U{kqD%iN`m}?|1&(@Zr}yvaTa()7BevL9R^{>I6wS1U2bcM<}RJzH-BHSlk)88@eo+xZ`JbACQvcx@2m8x z>hj+b1??}UvYcGIY07rVBwe;SGc!LOx$d{SCG}YHh98TgE6YD#o0^k#=Ka~ch-a*q X?lT^D)k}>9TE*b$>gTe~DWM4fpL|kq diff --git a/src/assets/images/avatareditor/fa-selected-icon.png b/src/assets/images/avatareditor/fa-selected-icon.png deleted file mode 100644 index a1d26b61c58fa6c489d55f6f26d790f9af6a9ad0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^(m*W2!3-q5W43JqQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1``2&1HTvb(7gMxxeN=i0v+z1q#rQ&x2NU@d#`33(60*2q)_=14~oCO|{ z#S9F5he4R}c>anMpkTYFi(`mJaPNd@K2}8zXU3cVXDxqf*m%-(=ih)+fdWTe=LoI3 z_QgbU)y!2I+Y4tXPEgX{$i|ZtGvSfw!_*a@3z>}+*mJs>FP=PS>7o&8$bDG&&^O^J zYIkmLyJsDnUiUKo+SVxLbBgJU$~5es9$Ud3>{Gka)8bJ3`31=5EbxddW?978mMmrn2&YB1n%zIgBdxk=Nn_{Z)rI44jetFe?#Ys#DeX`_&g z4U5~{L=`$iJEB^@vM=m3p6{r}+&bg0i+A;$m9`Hp!|m70ukz7Yld6=G_R)Ltfo#i7 zZT+IBVqL6i9cMYTZjXzyExt2B-)HUN-2wk<7u$p;_b|`aWIpWb+{zAg27{-opUXO@ GgeCy3+F73f diff --git a/src/assets/images/avatareditor/ha-icon.png b/src/assets/images/avatareditor/ha-icon.png deleted file mode 100644 index f0a819181a29792921dad2a3f95d3c8ff3d10ee4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 241 zcmeAS@N?(olHy`uVBq!ia0vp^l0YoR!3-ps5|6h4DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheYymzYuB%tC1~R=BGZKLmQ%R6t@PCG<+YP*cJkA1-$YKTtzQZ8Qcszea z3Q#c3)5S4FBY18er|(%y z{=_9$w%KyEub0!G5_Va3d5?Ed=dBWH?j1)iL|EQ>YM3Q*n0sTPNV)N)-v4J4t3UFb euC6ot?y~2F5aTSBDtA7hjSQZyelF{r5}E*2KvHM` diff --git a/src/assets/images/avatareditor/ha-selected-icon.png b/src/assets/images/avatareditor/ha-selected-icon.png deleted file mode 100644 index 4c81ece52017e6bc405c53de21fe9909f3681724..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 285 zcmeAS@N?(olHy`uVBq!ia0vp^l0YoR!3-ps5|6h4DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(ehe`~f~8u1;o}{~sN?wxe@FaT-u;r|NotAjMh|*Eat0&tY{yy{OV_~cAMCEyDJ73ob_9aCrs(XlKibbR-`ORD7 zH&N?w+(geuf`L!GJ1jnZF@MOPe(dg?;O=UZj+U=t(l3%ftG4I8UZPNWT>kIm%?;89 X>seNroV%kAbPvjzBsxUOEk8p!lk%t!=MOeH~n!T%YaZa44(@;D1TB8wRq_zr_Gpyr+tv%qUoUrjoH&hw1Q2zL$r9Zej3r^>bP0 Hl+XkKr9@%l diff --git a/src/assets/images/avatareditor/he-selected-icon.png b/src/assets/images/avatareditor/he-selected-icon.png deleted file mode 100644 index 32633559b9cba03803a5ac7f0b9d669bd521393f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^@<1%j!3-ofKU^XUq!^2X+?^QKos)S9G*n&l!lGtJnsL;GUC&%xhDGtY}W+}ig4<_4gA5tn-+km4)}@(cbC z1q{Ld6+$4v0*}aI1_r*vAk26?e?hZT5S0u5P8{tNGp?zmVn zd%uUEoL;g(?#XHXi_AngqZbMCPM;!EB~>h^xBOk5(Qe&_*-_3!?UI-f1Z6iZRpzl znW47qnD)CqRy*t0IqSsDUFttxZ~9szu_w%&&+mAXRrHSCk9yklZ02a&{68Ne|6&eb V`=SVwe?Vt5c)I$ztaD0e0st?%gCYO` diff --git a/src/assets/images/avatareditor/hr-icon.png b/src/assets/images/avatareditor/hr-icon.png deleted file mode 100644 index de299902af5abc9ea6f8cebf1174138a5d050cd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^vOp}!!3-pS-MOj_q!^2X+?^QKos)S9vjzBsxUOEk8p!lk%t!=MOeH~n!T%YaZa44(@;D1TB8wRq_zr_G- x=A1mb%3EuL{k@dTcOIu%uNZE!IDFVpzlM`3y6(@BdY}s!JYD@<);T3K0RY~WTu}f3 diff --git a/src/assets/images/avatareditor/hr-selected-icon.png b/src/assets/images/avatareditor/hr-selected-icon.png deleted file mode 100644 index c694b82a5097b6f2ff485fe696db74429cb2b0e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 348 zcmeAS@N?(olHy`uVBq!ia0vp^vOp}!!3-pS-MOj_q!^2X+?^QKos)S9^9T5ZxB}_6wziOvkfYny0@;58Eam|z){-E<;Qv6t@Ov9yFi?QAz$3Dl zfr0NZ2s0kfUy%Y7JnHG<7@`rJJBd-KMS+J|`^SItcr)Lp?~e6wz1`Muao6Ha=Wd+j zDP0)4Rc!JHoAtR>2M@_-?O3$8b^A2V+#hYT`Q99L4LNixhPl_~(w?h#t^_>gRp%-# zdcc46>6(Q#A9l4TIXEjH^!sqiu=CW9D^K^R{5Dg&xr_bTnS1B%MJ#g&b_#dnD=m;x zw>isMzT%O%)!z40ek@E+4zv@tKM-)nVDc(W;E lm6K|w6kqZ?yWiv5U&gxMY-$PxpFttQ;OXk;vd$@?2>^AXjfwyO diff --git a/src/assets/images/avatareditor/lg-icon.png b/src/assets/images/avatareditor/lg-icon.png deleted file mode 100644 index 0bdd750e4ec304e7725bcef1891d2957e09f4d77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv-!3-oLy1%&rDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheYymzYuB%tC1~R=BGZKLmQ%R6t@PCG<+YP*cJkA1-$YKTtzQZ8Qcszea z3Q*9})5S4FBRDxBCB=c&fl#~JO0!)j<&Nw|?%yjAKhD{IF iNiroFFeDorFfbf?$;hl_Ccq6egu&C*&t;ucLK6Unk}_KW diff --git a/src/assets/images/avatareditor/lg-selected-icon.png b/src/assets/images/avatareditor/lg-selected-icon.png deleted file mode 100644 index 7a2853b0272603ea329037f4fbe060b4b8ab4ca9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv-!3-oLy1%&rDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(ehe`~f~8u0T4fXM|AsWF)Cq{A|P~c%rKKu9ln>{)a3orP)d(3;>v|#6L&O^C2 zJ+THFLM4)KQX@l@A1s>Qt+ZU(C-_<9(dOy1uhz%h)7p0Vv36`paLej1Z)g2u-puNK Xk8$b8p!dx{3m80I{an^LB{Ts5YVA@) diff --git a/src/assets/images/avatareditor/loading-icon.png b/src/assets/images/avatareditor/loading-icon.png deleted file mode 100644 index 50d132b3e4e950ee4f6ab1622d9ebcb51fc157b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^qChOk!3HGnT}^!pq-s1}978-h-%hp`YB1n%xw!G` zKlY~#7Gi}mEjpYfX{S>@A1W6X46^#_=zopr0597~LjV8( diff --git a/src/assets/images/avatareditor/male-icon.png b/src/assets/images/avatareditor/male-icon.png deleted file mode 100644 index 95a1b35267aeeba204ae4c2076fe2c26a0daa767..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{3?%2B3|#`G7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%xu3o(w$n;jsNCZ+$B|(0{{~4ZcH}C@TI14-?iy0XB4ude`@%$Aj zK*2~)7sn8d;I)0;d<=>l&JX`h5BtrSbnLE) diff --git a/src/assets/images/avatareditor/male-selected-icon.png b/src/assets/images/avatareditor/male-selected-icon.png deleted file mode 100644 index 85debbb3ef2634ce46e8790558cc1c98c4b66ff9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{3?%2B3|#`G7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`211o(uw0_jCh{s--N4Pah(T>d>cMXHD{tH>YCql~P|BA!Aznz{IpcBNkeQjEnx?oJHr&dIz4iKRRGIx;Y9 z?C1WI$O`1M1^9%xu3o(w$n;jsNCZ+$B|(0{{~4ZcH}C@TI14-?iy0XB4ude`@%$Aj zKtWee7sn8d;HiC#Tnq|4OxOS0-(6BNRj@=ypmcGDlA3DE>72lh`(jh0+_(K-6eapZ vT6tR7A(?xdS=l!io9=M@Gi@!Sv9i^fe+(Z@mIyBd8pz=3>gTe~DWM4fPHa9M diff --git a/src/assets/images/avatareditor/sh-selected-icon.png b/src/assets/images/avatareditor/sh-selected-icon.png deleted file mode 100644 index 12c6deb1fb8d7e519e7cb0a09125ddaf7d5b599e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^szA)e!3-o>cBNkeQjEnx?oJHr&dIz4iKRRGIx;Y9 z?C1WI$O`0(2Ka=yP8JZq;x7Fu(+((b`SRue|NjFSD_<0e0x9;AAirRs2uM)Mo7oL0 z#981GSYvNhADcs zKkBpUxMa1kV$FfIJg)AN%YCwAWYrn=9V)v%P0IgfE_d288PDjtjN+il6TB3syJiFm y|FHTS%qeDMS=Xw#_C`)dYSE%4Uk}%RW~gaA#WF34(QN_HS_V&7KbLh*2~7a2cUs5* diff --git a/src/assets/images/avatareditor/spotlight-icon.png b/src/assets/images/avatareditor/spotlight-icon.png deleted file mode 100644 index 8755373c5083cd5c8956dc4279b0d608c46e6d16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11373 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 diff --git a/src/assets/images/campaign/available.png b/src/assets/images/campaign/available.png deleted file mode 100644 index 1cc8fa6219b2b4ff56e4c8885a945087f240321b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1118 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�k3-p>X_y`} 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 VBLJ_-_G175002ovPDHLkV1hQ-?a2TD diff --git a/src/assets/images/campaign/campaign_opened.png b/src/assets/images/campaign/campaign_opened.png deleted file mode 100644 index 9ec1bb30bed39dec6fee41a5bdec960426270574..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 744 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 diff --git a/src/assets/images/campaign/locked.png b/src/assets/images/campaign/locked.png deleted file mode 100644 index 3805e50234425d507d37f332ebdfac58893849d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+97JIrlhE&{od-EXg0Rj_^|XUoodbBOldh^Av|0UeLaAs?KfJs}@0v!#O1sw06wfaxt-!-|7FE-m&Qu2iZyVZp!msfIR zF{e7NHM~-OSl{CHTAu2!`dgd@6&t6lDp}%XwDMNqsuNRJ9a}0V{bXMLDY+wY!f))> Un*QSa2Xrojr>mdKI;Vst04zgSJpcdz diff --git a/src/assets/images/campaign/locked_bg.png b/src/assets/images/campaign/locked_bg.png deleted file mode 100644 index 93927dd5a877ab6ca31bfd8d289da1a252a39180..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5414 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 diff --git a/src/assets/images/campaign/unavailable.png b/src/assets/images/campaign/unavailable.png deleted file mode 100644 index dc134c3f12faa3d00aa4302bfa0ec7a5ca81608e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 448 zcmV;x0YCnUP)KNfDQ5dg1UGAYMfQUf;Uh)ngA-7Z1vq1^sisOZ0IbmyeMagsll2%NTpG!d;~iY!UQuJ;u6dX5T{`FFs4Erdhm98 zd&pnWSs3a`rOPPMJHIsJJ`u!aDPjtUXKN3lXl+514Uq02>IR4yr3{E^m97hj^`w>s zQEd-M=WiMH?KTEviGi8&^*jz_$#0nsS4IhtijzcbK*moYW{or2gQU&80|H2|p?msb z6(E50T)6`T5I_I{1Q0*~0R#|+?jInOWqy@qQn(Y&t|07)h{-GJL5OgffFj1rw576&cr68X_~ttRzGv$XS^2Nq0wK qQXw)y{>6S}9#bmFPwGU0V|fCdK~2vw4K_dk0000 diff --git a/src/assets/images/campaign/unlocked_bg.png b/src/assets/images/campaign/unlocked_bg.png deleted file mode 100644 index 31c35ba172146dd1af89db8539d582b033c9dde9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8798 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 UIckVaaR2}S07*qoM6N<$f)^J^t^fc4 diff --git a/src/assets/images/catalog/diamond_info_illustration.gif b/src/assets/images/catalog/diamond_info_illustration.gif deleted file mode 100644 index d082ef4d7bab28c5ba2721c86b3420873483fcb7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3883 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 BUg7`% diff --git a/src/assets/images/catalog/target-price.png b/src/assets/images/catalog/target-price.png deleted file mode 100644 index 8639afd55a62dac6f6cafdd4c33c4195fcefa083..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3562 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 LNkvXXu0mjfkP_;u diff --git a/src/assets/images/chat/chatbubbles/bubble_0.png b/src/assets/images/chat/chatbubbles/bubble_0.png deleted file mode 100644 index da685365b15b4c8852768fa83a4c7f4032ae3a9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5025 zcmeAS@N?(olHy`uVBq!ia0vp^#y~8=!3HG5PaVAvq*#ibJVQ8upoSx*1IXtr@Q5r1 z(hx8=NzI6XLD<>T#W5s;lhH!>_!~x;92)%}jXxN<7;Z-w0DI!hnKLwT{H$5C7)nb^ zsbaROsw&JJxF6sQpv-@eC;0jKVT!0qcXxL)%$zxss%GA~bB6)yDX>47pr+H*BUJSP zl3^+;Dh#)8-v)_*QxwcINJ@q-6XY3itbn}m@#DuK(?1BDdGL$JmrJv>BH&wxC1_Uu`>hd_K<0-AdU zfqcsik45NvO39ap+srj%D8a!s+zkg3t3+Z7vtU1Hz>gxJ`_wL;^ zwe#)Uw^TRZ!omV%Cb-*-JO%&~1b07a;VD5uL2w%_DJcnL55)lL36ME(KfoDirVq)X Yrp?c?G=9fdCW8Fp>FVdQ&MBb@02Mod761SM diff --git a/src/assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png b/src/assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png deleted file mode 100644 index e7a4740b2fc72549fb992a49db54d7400815a3fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&q})7R978x}mY&_nd%%Ii`C|Re zM!`M*9poC@cs(Y&2<|HGod1F8mYK1jW13PYx5FjDKbOxRU$<)8-S@eAH3dyu8<)T1 bVBEpjTdy4PmwjbC&_o7LS3j3^P6RK!t$(9Kxk3Z#ij#>vjomg=2SD-+MU_3W!Fse%V)p&7bo8_m{BWa ze8$*vIp-N^mQ#TShHjJ28JHPwH#*(COk7HA-K@O%o3HfE@Hu@4=z0cES3j3^P6X1^@s6oR$`P0004qNkl9C6o)^eNI3vfwnVK&PQa22bclKdW?Ct0bBit=klM_VdV}T=t!FC1MyDv*ySWQa zA^ed^K#(Y(U2q4a=qCJzMEoZCJBaRBdX0vJ6 zn~JFYs-kmP0FD+^W~b6uE#4GbX?8AL#dMX-o+%>?Lw>(s_Rl~4do0V^ABt_GE#~>* zF{k$fAw-StoQ9T|vbWxah$ytg2qAcSd*$xt7Sl9=^tai3KJSF6YXMMP3qXThQ~|iC zJ<|h>yg$ivVltTk7?lb@*HFiUB6*`C9mi>GVc+-hJg@e7r_(9KI+BqwR;!f+s9Tip r`?VK}SOg>jQgqj)b5GVb8Q=c^ylJe^;k}b200000NkvXXu0mjfu9C`- diff --git a/src/assets/images/chat/chatbubbles/bubble_10.png b/src/assets/images/chat/chatbubbles/bubble_10.png deleted file mode 100644 index cbf25a8346f14473a170a7591d20270290883291..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 778 zcmV+l1NHogP)~_9m zGUQ>78PM0~$29$XPp{8U6OM50QNT{`Z!a@I$ov_{<=W_A&t4Qz03N;z-VGA2jSBYa zNdn5i3ET{JR2oMQveyEbAmN-TjnAV2Jtv%N>?K|!&m~?T8Yt5fSvN^ee+RPgkhDdj z;cUy`*pnmI(-@BdEYlash_3^51z29wYMkyyjR}Sm5QC1*LtQP6*;>y%V%&FI#$~Wx zg-S|lZLXF&W7Sgwo>V1a0Jnl9%mNs)R}JJ1DE?xqCd% zh~5TJqOe8fNwY0mUE>5L25V{*E`jl^KO7DTQvfjPY1DW#-D`QBJJxg!igBP(6}TOMHjl1=!U+s6|}{$O)*$bG;K3>re%>6r=3zt*Pk& z$n2>Cnu}4DwKi`{Pv-8`@IW#u0bRr>YSUUDYyIed)z2<5S_AOjq$x&616oU6bANd6 z;5={n(up1&C?!3W^Y+G8Gs62(^x|t1$z)u@%{$l2H7c`ms;F+5ZO+Pryy_d zbe!sy+-Ae^#$cCh!+H*|dEV4v%D&LEd4RpaKVw&5dBnE(I)07*qo IM6N<$f)hh)u>b%7 diff --git a/src/assets/images/chat/chatbubbles/bubble_10_pointer.png b/src/assets/images/chat/chatbubbles/bubble_10_pointer.png deleted file mode 100644 index f7bd858733761b97ed9e75816a7a4ff468bdd513..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZKu;IPkcwN$2?+^5=1-c`)adw# z=fC~kKmF?%j<9#%x7hj1eiPFM7J-H%l49Sd{dEsxn9R^=+`y8+m6gOaLG{3-0#*gj k63!h=6I9HAWC|ZcVRzDUt0TEzfrc}9y85}Sb4q9e0Qzq%wg3PC diff --git a/src/assets/images/chat/chatbubbles/bubble_11.png b/src/assets/images/chat/chatbubbles/bubble_11.png deleted file mode 100644 index a8026d6708200ddce03e38dbfe0c12de677e81ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 242 zcmV3XOoGqgNJy9|#UK-A3qcnXA3&x~BpfIKoRJOlCs$PQY1gf5<;mq%#s8G3qz z=AMCNdRpfdx+Sx)r}Xm>T?zntd1$nr8TAYuJwtO3(b_W@{TZjDuZE3h;2xp{hE<|H skN;C0;~fW}m8YofA(BUFhT2dQ0F4642Q+|LZU6uP07*qoM6N<$f+4bHaR2}S diff --git a/src/assets/images/chat/chatbubbles/bubble_11_pointer.png b/src/assets/images/chat/chatbubbles/bubble_11_pointer.png deleted file mode 100644 index d6c4482a78ccdaa019d7a008eef931d52fe29636..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&r1U*q978H@B_|{#{IGxjvz}+q zcjXqglg195HCzX}0z@7KH7pdE&LqN0ogggbd@TS`mnqaU;uD+ozMtF*T9-*0MaCm6g zcm^e154B{5mWODU;gJJ~nwcL@fiUWsk?R?dM}~!GK%M~EK}(O&#WVEs2+ci1Pmj>t zGq6lg>%2m@WcE5@E8RRqmjZxZ9vZD@Mm#*?*+(Wd$uuAmD s+Ur!uc*g-~+dM6aWAK diff --git a/src/assets/images/chat/chatbubbles/bubble_12_pointer.png b/src/assets/images/chat/chatbubbles/bubble_12_pointer.png deleted file mode 100644 index 309a55063678d9809a728aed7d9dbf5fa64d62cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&r1U*q978H@B_|{#{PgT4u0(fDMN#c4}d+Whb%O~SK#qcMj)rA;XSC!ZHJBE{Nv#@+cF`*GW=s>rZPKR)U8JIjX2zxw z5Hw@k2nd?-+!mFcT@HL#N}_<6nIs+2+3x^YGbCCwVSixNkoeUc_6K-wOIil_|7gxG z4xlb?4$I!hpU@Aq&&)i(yq32cL+IZbbsIIZDi@++k7;5&=JClE}b4UMX6-qgnW rDnZ=lv~g`DUTy-WG&H_4m#wCEIpAYN*DL<700000NkvXXu0mjf>%yyr diff --git a/src/assets/images/chat/chatbubbles/bubble_13_pointer.png b/src/assets/images/chat/chatbubbles/bubble_13_pointer.png deleted file mode 100644 index 65be4f232033e08ba2a912bb5830a50835d05d83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&qzpV=978H@B_|{#{McWAEuN<) z^SitO@1*nwp&ud*q6;;SEM;(3)MM4)`l#s;*1^PJd&T_*r_AK$2IP@p;Te!8Kz7j5BXsc$y*xs5&(PB&w2zq? z^vNsq%QLI!=OOx(W~+u#X*ODEj(P@H%Xx@-2BSZ7I)3w})-i%#NHCz)!7cnqgl(N|xDxx39 zxI8p$JcE+1hgvd2%R{uw@W=rK@(eXHK7j&Z)H5U3Ga!!)3(tT&0kVUZ9-)h8=;aZb zdxoAKp}A*ZnV!~pg>K1=o*tr00U)>a^6)9mkUcb7X^v#i(A-0`_6$aUMkl3q*mwr+ xAzEN~CEB}y`WW9h0IfVlbq|p`N;A}kngIBu)OI9?ObY-2002ovPDHLkV1m|oWk~=4 diff --git a/src/assets/images/chat/chatbubbles/bubble_15_pointer.png b/src/assets/images/chat/chatbubbles/bubble_15_pointer.png deleted file mode 100644 index b4a69e1d03724598b4e63f46ee475c8771bcf868..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&qzpV=978H@B_|{#{5Wq`Zp$Wi zyIRnv`HAEL7CY7iR}HR0%>w})-i%#NHCz)!7cnsO#F&5Gt!h>X)XU)M>gTe~DWM4f DHq9K> diff --git a/src/assets/images/chat/chatbubbles/bubble_16.png b/src/assets/images/chat/chatbubbles/bubble_16.png deleted file mode 100644 index ae0a23eb5d0cb11cc10a0af1eb2541890a755010..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 716 zcmV;-0yF)IP)>slBFTvp$#Eec7^HjR-Tm*LPp20nfHEn|xnAcY zcAb4*i2E7Kq%0-7c4;_1wAQ(Z1=*txavBz{8br{UB*Pb30F>;SZQp!p+cHU)eYPP_ z#y3L%v<4*jE^b|!0mvjVcfSCzO4@qGUjRPwDEue`sL}E4j$lCmt%2u0(K;4ll$}k6 zi%X#DmCqE8K29CHA5u=Xz%9%r$k{&T@u4>(J`5L^0Bm971ItO@ z=l8ZhP&lnl8Fnz$(>ipzNIBVZL@j_Vq)f`nmkgAhO~4k_?)SX2WRkQ`&Rr%)*hGE~ zu7Bn>q!+0kRahl$0W3H|t_G*b8jWV1cE9KTot)EX)=^}Q166m;eW2=MLGBAt?Vv~Fj;MPR)9C_;EXCKkh?P~{%9jlH)){RPMbH7bR@!fsCsnPRjL#BL<(#0*?cI9|CJa39p?O;E+u&(^{&yY( z%{vc*rp2rjUGK4|ncQvP5wlVh9l5FMJc-iTh{!WE-hJdt24?R1F8(ge9IP&?Df{l}^Uxgw yeEs!hW|NjlE{{N4bI%r~M=OXCApjB~QTfVhFfaMbB(F9kI8WHV_ tsux8UXtX5ea0Q4w3O>;Aq*jE1q4RXgr=;*7{6HfaJYD@<);T3K0RRIhFVz45 diff --git a/src/assets/images/chat/chatbubbles/bubble_17.png b/src/assets/images/chat/chatbubbles/bubble_17.png deleted file mode 100644 index 51930255e8d9c2a90105793072468de7db6bff7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 806 zcmV+>1KIqEP)sqXSx0D^S31m!R z?8VkNb#9n&)VJ9z=-0u47rsB**a%|)_hvM5U-xHTAMYN_FyR0JAUOD9Z7t|CfG$bMBCG>e`$B)DK z)7@R)vdElIr?!$7s_Un>qeYduuFAQG76PPJPJT}j>`M`74sP;l%RPHHofFQze7xdr zuC5xX-#W&QWj|E;5`g5PwWRKYX%McmUdW*S{N)fW{%=8rthThXBb?RX96! z2w=EzfDvwQ^1zG0>L|jMIoUR3VbWGeP8SM?K6CQ$wwM5naQs^cL5h$R!?a1b6kw== zoS+Fw2esf3j-eVWAQp_Rb+ZjPlaqJVk0o9KH7|9^rf_=GF+eK|*i?~86rH~gV$M3A zO#J-CB^O=c~K`P2`}?mu=@^DFqYN-9PlYbY5rjmR5wDsxh`y5|dQ_jU+mGA)h_R%$9W>+!_qw7lRg5M8KoWGREQq8_UT*GElsoki^;K8S@m68$=}r-EDfOIf*Ai zQpx4=43*=-C*%$l=-Aom8AerfP1yUQX2x=lZ8-~UTyk`JdH5f8$5mB#%*ZjA^`vc0 zyPNmUiz?<(r+TLqEna#jL(`p2?Ks~Y-Ml27#Y>l;Fr1%I-x2WTkj_$3HB;$?w_Ew9 st}{2B=P0QnnIxxJ_a$9}FPV`cR_aIaUcDF%praW)UHx3vIVCg!01iP`tN;K2 diff --git a/src/assets/images/chat/chatbubbles/bubble_18_pointer.png b/src/assets/images/chat/chatbubbles/bubble_18_pointer.png deleted file mode 100644 index f36452570096924bd08dfba4df72e6224c0cee73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRM!3HF?&tBaMr0hIh978H@B_|wU`7g=Q@L#>B z_y6PIAOH7HzyAOK>*@m%vz<0@p6GJODQV?!^^jPuB*2^ec#BZmM=Lqb!;B0XZSFl@ T-JElQCNX%r`njxgN@xNAsvaof diff --git a/src/assets/images/chat/chatbubbles/bubble_19.png b/src/assets/images/chat/chatbubbles/bubble_19.png deleted file mode 100644 index c0dfb4120d82925391dc392e7d580d48441fd57c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 688 zcmV;h0#E&kP)8nu5XXNEG&oEB2GY(>jc2bx0HK;Z)^h+ofya(|0=m6s#*qF@*v)QnZVkmXeOH(V`$1$@s9l}$ML$n?e!8#1>$>&8;A?D6+cRQ9@X4lMP|9sTc^05Q2 zCNMe(0DFy)s|c@Nc}@~U&zRvt$QT1ppr*=j;&9fcm>0#H8@;#QD?ZrUVW4^k%{mOx zLBPe;6;LLDIwVQlZ@1)!1IsKM)JuSP2|#(STr!&wsmIAW3|WY7N7CpWPvw_+G^nXE zUVUAz(=1JSP7=OcU)!~pJm-A1k~-DcbPQ<3kkpuU7&6fs6-5B3C}N^D>oBb7jSVg# zC0T5irZ#ogv6#Gg32RKP;YzWO){4B?cqGX8?7H9}ZkNdiUGyKR5P0{P^`c_9&ZD^ZD`;C=H%P5i+mi=6GZoMfNIw zeR$y8-5uY5n##s~;?u{{JJ6ElZjQ&wysM|H>kWYu5pbI9$`jlfD`(!NGX^yN#`+C# W!WowT+TcO}0000_FCyg68N?K2F9q4jkh*S(?HE38Pu$rl))k0K3+eMt2fj=Nf)Nz^hZ=eATp00i_ I>zopr04rS|IRF3v diff --git a/src/assets/images/chat/chatbubbles/bubble_2.png b/src/assets/images/chat/chatbubbles/bubble_2.png deleted file mode 100644 index dc33507bbabd7f4e1d9ee674d535fc21ef661c7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 436 zcmV;l0ZaagP)?lxHA|@+u)7s+r&iE>6My_qVTE(;iB30LS0B;K7UXXp|UJ< zQ4lV?dw*6JVHS&}nh2HWxr@SBfLOsmcy3iyZZKCYVd##ppAaSl0u>cbehFitRv0Ayvf2KCU`}@cLzn8J1Res$*G(IY6rJi4rGuk@ zq0%&UtH&qDeHGVDQ91~n{4X(_w;EE zWC;V1vMdkJGkt5})G)Kz-62ePY-W*b3NTn)OMrkH{{vY6&|nhB3U2Hjm)ri*XbyB6 e>e%Phx$y3Z6x!)`r^%~g1Fib%91O&wNAJ61c5Iz)%8VF%!AT~D`d%{z!*F6yD zi2<-j7$}F?7{o(dqPbx3dKe&0b`{nM0i>HN7YX%L2p~Rys_=R^APqgfI)nq_;|~iq z*04ajk^X_4fQmd>0@Tw63!tJ$uoS2#Z)G4HLbb~2$)UB5L#sDX5pHahbaa}+K>TNT z!Po)0y0vmxwHhMYW6*ExN4;dOVNzZ6^m?xS2Z%GsS8cQuM5^%u)!+_Y892Xh00000 LNkvXXu0mjfh_0006HNkleNl21;g&?%+(G{Xy>H~qFtK+?oG%A>DEaeGpZrX6TyuMDmYj^Zb)z{3sN;PFMHaiI3gY1Zi0J_+&{ge#lq`7E=2p62>NDp-O%{2)SwOX*yd6u7 zx_W-AQTK@laHFB&9h}@ZiIOK?Gyr-{JWhau5d=R7JD|MV^*Xp+>Zfjx8Fn*Mput!| zluQWH;1I?dNJr($dntg42IR7G1aZx?9ZuU9mv?4jHcB#tSy?|4WlgLDku4A*TnB_1 z@|cIV(d!;e?k$CSdTDXvC>T52ifCI>UCVEbsu$X|6U6(W4*spdR1|l?0Y(ELt_;9W z70?!jby4t+LX;GKB2rrlEPdEu%I2EKN-zUe;E9!g9FQq4vryIxjw=Zj<+@#i!Zi2O zZ4JkuuVMx&h9V%Y&juwh2625hC@%k~v*>;?P3dD3MF)ncn5T3Vh0CNEU%nlbj48LE z9b3SbKe)EQGARhdab^mkw-!M$SQ_dML*UPTo;crSRVD`U+tW^8K|GZ)78&q Iol`;+0P&9>W&i*H diff --git a/src/assets/images/chat/chatbubbles/bubble_22.png b/src/assets/images/chat/chatbubbles/bubble_22.png deleted file mode 100644 index a77a733da9ba31cf2a56f899597fdebbd775c9a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 650 zcmV;50(Jd~P)NmL_GO6U;>xKJ#JaP|LGq;@2YmsZzzuoTp`t{|hTiLLq zS3m$KU|c8iG@I4(ama5Va2MklzYDR){`~?lXhu?Vk94%HG>I-2PzhWi^7WR#<&lFxCcr>2g}2e0mDTZ z48VZlvIy>5-`}(*9|3e{I}V_d4<$u_u$JVj#!Y$RVGCaYSb`~ljuW>@D!ojg*Te+`-o$u668+t@ksFOFJ?zO%z2I$)&_&dF1}b(k$ZG^d`i zU^5TR(YOzTa!f~FsAD_PkjEy3!yvk!g78NaR7dduOVF(d-H?H+K7p+4XaPV`wt~rj k5rXU!k}M8HPvIxe7pdX}6WVxd7ytkO07*qoM6N<$f}=|+q29rTOXGgRss^2!PN6U%CBg)fA1BHrynt>APH1 z$)m{ra}1V35m;97m|$9kBT`J}eatNw7tMpe(K#)^3~kK(s7csnU~~~!@hB>{Z&d|D zoEoYonAqdi08>qeby$aWScg>rD~~G-i(M7yHsp$6M!Kca2;O&`?+^7Xy*YzYKy6&^ ebs#hlZ@dBj4K0^#>o*|)0000}BG8YA+ zx$CcB+XmilcEr4HTVVrwS|6#;tpT%t-he(=E3$LM@G2EqChsSD&@tfi;W~ugU%uXV zKf`?|M}*+3Q09JnWDg6z9IWoDLo-z(0qp~aE`XT>cD8|sg?YCF3K{}GrnH3GOpgbL z8ngY z16`ZSgE5JjzH?QUR@`!XScPqy$=#ET)RWmsK+cc-fT4h=97U7Ik1r`^!G^Y;p?lRF a{=Wc}RcuTGPz2Th00007nRr@vh%C@JvYa7O5opx3S|dg_38_awy$qhNelF{r5}E){ CXB>wB diff --git a/src/assets/images/chat/chatbubbles/bubble_25.png b/src/assets/images/chat/chatbubbles/bubble_25.png deleted file mode 100644 index 60dcaad550d550390c9826820ca5f228152e8887..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^#y~8`!3HE7C#xL-QujSw978H@y`7QBcSwP!wOk?Z zq2LbgixtXWndAjxR|9Y{V>4-ztrKd*{C6<0u^|F?H!`L?O+-=e3rc17SR~bCH(Ixg( z`;dYM$H5pwx65AzGHMMr>|7e;m6mPUbJzlg*6=Rtl=poxyYhU<@5XO}Vc3bL)g zvE|2($G7sI_5Kxp#_4jH>7p|Vd&u=w- amcH>PZF9iPCmBGmGI+ZBxvX1|%O$WD@{VUY;(FAr-fh6B?SXPUZQ3(U93_ zMOoU9`a<5r|Nl=9H1wFG;`)E1*01ft%Q)5uoN)+b31L{2SX6M?L1I1=PwNhm1sX?| dGejx^Ex93|{m1(6w^*R544$rjF6*2UngHzNE3p6o diff --git a/src/assets/images/chat/chatbubbles/bubble_26.png b/src/assets/images/chat/chatbubbles/bubble_26.png deleted file mode 100644 index 0b43dec579f989b8977501ff4d3fb33db664cb74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 557 zcmV+|0@D47P)NklXEJ#i43_IteJZ)(pH}sHYh!JYx5wk^>SQ~Vwq7Fi!%4h9Uli$Z zx)S<9`E)l8F$)w1J>9I!^POQ38l$|~U#qUi!zPY8r7^T)opHp_Kl%a`$`S$M<$e~* zhs$vQ6Q^nz9f)+mI~`!lS#G|3XVX0o(R<3TBR=N z?|r~f)*W5h8fQvfh+P1Cn|Z*{o!E-jz?8c1-7|v~2V;1_(48chTo>&BEC{ZsH%x13 zR+thORDFUZ!IZdQLF{tu36czxtmR#~A=if<(^&Y@Y6sv$G%euVQjF vPq8xqK=43=FXN>=YT|)L*HP2II0XCvN!!F>HoWUJ00000NkvXXu0mjfJZ$}W diff --git a/src/assets/images/chat/chatbubbles/bubble_26_pointer.png b/src/assets/images/chat/chatbubbles/bubble_26_pointer.png deleted file mode 100644 index d97093f43ef7fd1245ee3304bd1a776c6bb41709..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRQ!3HGLSWET+sTfZe$B>F!$rGkd_~FlC+|Usm z%=7R1agTrh|L>CSNvsjz4gd1D#56*{<*>-19~x>0GbXSY$*<#B!tHk0$5rfj0824{ xmy!m9VSvcNBN7)FVifgQHMl-%I)rsFF~q0T_4n`p+yk_S!PC{xWt~$(696E{Ft`8! diff --git a/src/assets/images/chat/chatbubbles/bubble_27.png b/src/assets/images/chat/chatbubbles/bubble_27.png deleted file mode 100644 index 57de9a9ceec777bfaa4e79d8d171b12d337a49ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 632 zcmV-;0*C#HP)S@VkzVrKd)76fW%Qy8joulE9cf5)qF-}NQU$|vWD6;v4``fv&tB2_-t+{2-*)i zZ?$PfbvXnJ1YQ%=vE8($MFN;Z{@lEcmDdTAD(;&a=l&`4FczPLl!D^#1xg_E*wEO;q*{LEg^i{ZS%^tT}a6 z&4wBLE29AM^kpcJ99*}$2?1KF5oMZFm_fPO+%^!Q_q;&L%>yWpHBw-cLNQQR{03l3 z^4hA=Kr#SOoyo`7w@IMUM&8137B!fWjKE{QX04xNLjBT`LPhK7p$X|sS{X}W1t@>B zCNkN1bztxYf-`SHQ!uX2v5?uR%gYH5{iy~WHigrTX9}bVO?|ND3}Q0?q{igxQ8%F4 zwK+JWdb%Qua-+P2q%zkEHd&*{oc_4Rn}JhsRvk~#b*-;B{WR4(p8p~>c5G+_uYsFt zXOxB3z_kdij;#$n=Bt%z)3!BeRI4Qe8;Ip{Sv*etF4@%rm&TU*pN~6(h{hM`B};&A zu0CkuF^|#fK`=vD%OZj4OgybSL>6cqS7UFN3G6pUXO@geCxK C79C&! diff --git a/src/assets/images/chat/chatbubbles/bubble_28.png b/src/assets/images/chat/chatbubbles/bubble_28.png deleted file mode 100644 index 3337b797ba1d578960c8ef1954a65980a9958fbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 758 zcmVE@3hzA)9txK_Ej3sn(Y%(cG zRtF~ob*n?EPze+=TnjO2p2PLspZvRql0SZyd++5P@Au8`{eJIvPtc3(Gd7EeumLF} zCTzBYqn3_nHZY%k8*RAx)`6f4_o#E6I%c?258xlZn#~@)lBh?s{oadyZW;lX& zt|sWloqHUA$g{HZ{@R8Q;^_E9i4p)hAUhXr#EuydBCXtR4bL9YEf1BMvUTQ;i{OHew}1`o(j1s}(=)vV;>m0Q?xf&?&zH z3r+$ZxQrJND*#U1$n6+nPItH4(yJ^<&7jh0Q8uEaO7YRN+n8~K#SsGb>oQ+Y4-nZr z0GUjNvJrKKsOKyqxJ=9HUv89~c-UXtAoXwyk+qQ#Gaw}SPK2I4=YLB4{ajT0dF<2^ z%T5C5HfVosgH$fh-cQpV^LqwMhs`!JV!Gn}Oj?LS^LHAhII;$*Tpp@1p6>p}UlF)l zY_mO3(6oerFJ=@fcEF~)wDCMcP>^LJN^#~_(^C@yU7k_ft!zXo8&OY)0eG1zy%Voq@Bjb+07*qoM6N<$f}K!Qk^lez diff --git a/src/assets/images/chat/chatbubbles/bubble_28_pointer.png b/src/assets/images/chat/chatbubbles/bubble_28_pointer.png deleted file mode 100644 index 850b99e4cdd0afea8496aa778aad81d92d0ab176..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&qzpV=978H@B_|{#{LsHv$Id+a z-Y>3Yj-Pk}nC3HWP!eg~A(EhRWGREIq8;lAu0RHcS(?@Y{~rYB0rfI?y85}Sb4q9e E0Bk}X;Q#;t diff --git a/src/assets/images/chat/chatbubbles/bubble_29.png b/src/assets/images/chat/chatbubbles/bubble_29.png deleted file mode 100644 index 9eb5aecb27e30bf89f6976d0362f6e07136248de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 476 zcmV<20VDp2P){Myvujl*EHqr13O8@=}9}g75+oEe%XNSRn^r$!x!@OS80O;xN;#cC|Xqx8h zlcdmyiMD&>q*mR{ANu=xBb6u`z7$yK2AHX)WTF>|nhV%wP-K%_TxvPN08$`YPS zLRHKs(p&FbbC60M5zzgnj3S3Hd%2YBczOz2hdG5{(x*y)tqR9(^PDHv9>gaV5!OZo ST8Li&0000B~5+2h_;m>FVdQ&MBb@00(y* ANdN!< diff --git a/src/assets/images/chat/chatbubbles/bubble_2_31_pointer.png b/src/assets/images/chat/chatbubbles/bubble_2_31_pointer.png deleted file mode 100644 index ad9db877d2d2273810fee85242f3d13020b09341..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRZ!3HF6%}!4MQk9-Ajv*3LbI)z$YH{FUxzK5^ z5HmSxHS@+#;%nZ&-oE+PH|$CdqyFVDb79-V&N;?jkr%G+ zS~P|A_{RH9QQ;*F0*NfQzx@lJykuseY2m#15Z{vWUDp2gE-&8Yto_^Il947NSo6K) duxQ+7{v~fh&ZyZ6bO9Z~;OXk;vd$@?2>^bAM8p69 diff --git a/src/assets/images/chat/chatbubbles/bubble_3.png b/src/assets/images/chat/chatbubbles/bubble_3.png deleted file mode 100644 index 62988096471082bc942fccd97e7e154521e667a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^#y~8=!3HG5PaVAvq&9oHIEGZ*N=`Vy_m7{^N1#D; z-4ekvrbqAF{R3HrKZ)EpwD;5>lY-PNmf<0Je${;TDAP4 zfU!c&L8rbvxkcWL4*LAP*Nhj>TevtqA%FYb)g!A%GR&q<{JVvfX-*|boFyt=akR{040%KaR2}S diff --git a/src/assets/images/chat/chatbubbles/bubble_30.png b/src/assets/images/chat/chatbubbles/bubble_30.png deleted file mode 100644 index 581fc7092383b74d88163b4b78e33fd44149d569..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 427 zcmV;c0aX5pP)7xV6os?*HM-NO572>uArHjJ-Zx-C-8!-`^8hS}rBYccRY-k=kRPLCbkM~(B%#+K zk+5`h9Vv?M$MLnXqsY@t4_Z{!_~LXJ1<~`%tD3SbvnmDQpvm${T}WWDTC0grNs<^Z z2nXK(e5i{s-@89G5h_hnnxR-b=))l-O}EhZ#kQTP zRWn@8_)9ZU*>__nYX-?lxrx?U$vUw#%X*OuKri;jRW#* Vl)PsvQPltd002ovPDHLkV1jXT!b$)D diff --git a/src/assets/images/chat/chatbubbles/bubble_30_pointer.png b/src/assets/images/chat/chatbubbles/bubble_30_pointer.png deleted file mode 100644 index 8660de9cd45074fe049ddbafea51560f98f53e27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRZ!3HF6%}!4MQemDhjv*Ddk^>A4e#dY9`00Oc zy56D(x6j8l9d-P~^S_ZHR&f)P0E4zuSjUQjGLS$ sJehA_A0T>w!9%c1bO(cn;w}k>4_%!)PtTkb1=_&i>FVdQ&MBb@0PjgM$N&HU diff --git a/src/assets/images/chat/chatbubbles/bubble_32.png b/src/assets/images/chat/chatbubbles/bubble_32.png deleted file mode 100644 index 598d8c8513310d3bd8b7bcc7b20f6d1d88dcde78..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 399 zcmV;A0dW3_P)H7IBada()*2_C%*RuP%NgUw`iHjrJ%fPu&4v$L5u zpZ#T-eAOdB@M;=fj=LnFzHj#`3PPmn^=gT0d?eq1H3Wrpi$hpWH;OFi$ z$tGf_LkF&|52?ub2-WlH#0wB9tFi+S@Mf z1up`4hS9!zNssp#tN4`xp-sk3DWp&zGLqg;kl`uRC(R^16Ebe0`;09%tL9#knx08y zLc=c%=49Lyll08e3BXEvhUhU z(=#EH3V$*~<{3b$i%~^}Zvps%aR|Oi#=8Ze$Z)AG^Q|J&+0VrAz6F`>^`Y-JW7iAF t(2rw7JqM8Hm6&xCnMD6nnz0=IZ&sk_7Z@~Zn002ovPDHLkV1n#8vIqbG diff --git a/src/assets/images/chat/chatbubbles/bubble_32_pointer.png b/src/assets/images/chat/chatbubbles/bubble_32_pointer.png deleted file mode 100644 index a68ddfbe095a8612e48973355c343d966c9b9447..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&5-9M9EM{Qf76M_$OLy!300o^q zT^vIyZY2j88vKsm`tj5M+;qJ~4{o22YdY%qiO1oCe5~TErvE(u|1Z{Z31^tbF8G3L oqUZt*r?8GS49hM;}y6Jju*Duek{8O*23U_MneKy~ydfcXW!8ga-iPr6|M0000aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00C-AL_t(Ijg{2BO2beT!14b{ty>YXP*9gn(V?R+(5~*?i(7n$pl=|U zp-{T_1$1g(!l7i!qJq%Qg^C`Bc+*xnF{#B$2PKwr&thU45mpjC6yz z-0noB)KPOC0hrL?lOF&SC1mXc#RX01ASfUF+JUA+$f_3f_CcDxO;l1Ks~H_tS|B47 z5H4x(&JU7N7o{P&In_ovsz=(i@NzStoZ!*Qo;$wKw|h=+UwL|2GairGY&IlGvipsJ zs>QR38Ay81^!t5=!y&WT3=zT3nSqvU>$0we3}C(%vq_^Y+1jljSxk9oFc_qLRqb~^ zpOZvB0_X#0#C#Xl>6&BCY1Bq!pv7VV>^5@kYF^RIK|vv+I>eMhWB@)*Le^;tQ;<>h zXJsUhk%DbPRu7j@mVf84dec5^J5xBvhE07*qoM6N<$g2Ia9i~s-t diff --git a/src/assets/images/chat/chatbubbles/bubble_34_extra.png b/src/assets/images/chat/chatbubbles/bubble_34_extra.png deleted file mode 100644 index 9a67674fce00d69741e1e7031faaddef61fb2cff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 310 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S1|*9D%+3HQmSQK*5Dp-y;YjHK^5d&QB1(c1 z%M}WW^3yVNQWZ)n3sMyv0|E>g7&vA=_VPdLt$WHROhe<8|LHTHPlFhklZEw!y@kCO zyD&2|b2D=om>3wCu}pGv*k&1`agl*_#*EoZ85i!1+%!|O<2);a|1QxCY26z=K&zTO zT^vI!df!etDcGRE3xhPe)qf|JEWaW9`t#|y%L|!B7G$c2 zoQbnl+bW#CKCU5T>#3l(|6g1WXt?HLl*6JGbDH(^5z~Wd-Vb*JUBlq%>gTe~DWM4f DYME^R diff --git a/src/assets/images/chat/chatbubbles/bubble_35.png b/src/assets/images/chat/chatbubbles/bubble_35.png deleted file mode 100644 index e4e7ea6535c74e7ad017aaea1a9d75b3ab17896d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 869 zcmV-r1DgDaP)`$6J?D4M?)l#D@BVi0bZ8S% z9P2g^&p29}hFvUB5JPwd=e@f}4(wA%8bh_}%hQI2^Vosrt|BGuS7v^aLJAp&2G zO%AvNLA;Ge0Pxt2v=2@J@bLMtYF;Y%hr%q~>08$tEke~+AxLI~Ds_A{Hpq!~+?_!H zMtfQ~?!3ilPYcg_d#Q3bWdFGH763k1a#8;NF#Dgp+Y%vyZc0GLgAguhGz zF#PHjT_cOM-7ZM~u2V#ha0Os))s_4b7aqHjvMV>a(E1oa3ducomiECZJa!}bB`&_c z=-d`}zD-U8NOv@y5tN;CrZfh?oW_^rs860Ql8R|_90pcX%xub&WApRB)4I9!qE~j@ zfoO^We0|X=%do&~%2V~*2d5b5XkdK&V>HzQ+fxVx`n3ivmICriTv$!nTr`<-(;fd%nD^g* zZrP7zBI2A8uEY|2bY1nSM9Uo^}T#=C!gCwPScIgkfhFy5_*v?;|ZCG3IZ@RS8QUNsgckb;Yy-=CMh!_<QHkAAx$an|5ie-cndOC*?c2>}7+XCQ_l&No?@i=x#R=8C z;M-4p`22&bb*FH5zeE{N6pLk#$mTK4DH|r_jel*1s34m9-l!%&f301G62+7(FRW01 v(v0E3)|Kaw*QyetI*4J-zjAgMaeMy@0)1*9_Y&f#00000NkvXXu0mjf0pXw& diff --git a/src/assets/images/chat/chatbubbles/bubble_35_pointer.png b/src/assets/images/chat/chatbubbles/bubble_35_pointer.png deleted file mode 100644 index a8e8c32b3cbd81cb63f1ee2d88c844e52de043c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&5-9M9EM{Qf76M_$OLy!300j*^ zT^vIyZY3uqB>Y&v_nQRUH>1&`=Y2gl8IVVYg=avX zh!mr(N9a-j(90tzd18p zJcHZ?7^07*qoM6N<$f*2ZWEC2ui diff --git a/src/assets/images/chat/chatbubbles/bubble_36_extra.png b/src/assets/images/chat/chatbubbles/bubble_36_extra.png deleted file mode 100644 index 8e72fe4473385f4b1c57f61067dbbff079746133..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 239 zcmVi-k002ovPDHLkV1h^rVyplF diff --git a/src/assets/images/chat/chatbubbles/bubble_36_pointer.png b/src/assets/images/chat/chatbubbles/bubble_36_pointer.png deleted file mode 100644 index caa9e3c073c3510bf9d1e6c6922878bc078d7ddb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&qzpV=978H@B_|{#{LsH!!NELx z%^v<`j-Pk}nC3HWP!eg~A(EhRWGREIq8;lAu0RF`l}L-5ht@U60QE9>y85}Sb4q9e E09p(krvLx| diff --git a/src/assets/images/chat/chatbubbles/bubble_37.png b/src/assets/images/chat/chatbubbles/bubble_37.png deleted file mode 100644 index 43e609e069808b308c1343069d7da426e0ee1525..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 376 zcmV-;0f+vHP)tmq+O1dy$3fm5=&mWIrv^NjpM^+k{vY;q`DNUELd_TcvWEI#Nh%=ndd~w(0#}9bQaIAw`kfHP#X8|Ew%O_FXaKn WJ|gYeFWUG30000(h5RHqw>?<52n)~bj>C@dI2U~1dw|#haZl}pXh5kRkzRg=D zaWeSJXO6Wt&8M9YA2Zf?S+zpdc#Dn8Zk~P_hbw3PRB*Kfp6`h{-(X{;W5fK3FVdQ&MBb@0M{{bYybcN diff --git a/src/assets/images/chat/chatbubbles/bubble_38_extra.png b/src/assets/images/chat/chatbubbles/bubble_38_extra.png deleted file mode 100644 index 73cfcafb14687a81d3bea369138cf03398bedabd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S1|*9D%+3HQ&H|6fVg?3oArNM~bhqvgP;i>3 zi(^Q|tz-*@cgGuenGe>-NGz9&Y4drL@oRtK%^Dsaq2s9 X)4ly}b1z5)x{$%s)z4*}Q$iB}Ub9r% diff --git a/src/assets/images/chat/chatbubbles/bubble_38_pointer.png b/src/assets/images/chat/chatbubbles/bubble_38_pointer.png deleted file mode 100644 index 402e543ca69d975be80de75f43d6fe44fd0a7dfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&qzpV=978H@B_|{#{P_R$sVmQ) z$B%;zcqgSd2>lRg5M8KoWGREQq8_UT*GEllRg5M8KoWGREQq8_UT*GEl6ro(FDslh5nB_^Pei1kf*>FDi=?u2?lv&;=}(`#Ymo_pGRor8C)J3 zHl9IA*F!Ctq2(dkWq9NOqGsmDQy`3bX5@MXkxvEtwg&E}@%;=u!aC%R{5}%&2GR=oy-Oh}NFL=+8)ol?@xuz&%6@468)_ s_PwV%#ybu`D^F3|LnM#V47H&q0J+T?s)~cAk^lez07*qoM6N<$f}_f2xc~qF diff --git a/src/assets/images/chat/chatbubbles/bubble_4_pointer.png b/src/assets/images/chat/chatbubbles/bubble_4_pointer.png deleted file mode 100644 index beb69192f4597350c940b0b6bb9f4ca288e89903..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&r1U*q978H@B_|{#{E#nyX3sY7 zhk#S_6UhZEcB~1m8eD~%2Ld|08M~ZnxF(1$VqmECb9HZ?a0FxmgQu&X%Q~loCIBb4 B9F710 diff --git a/src/assets/images/chat/chatbubbles/bubble_5.png b/src/assets/images/chat/chatbubbles/bubble_5.png deleted file mode 100644 index fa33a77638e162f486fee5a7b86a78369d2fbab0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 372 zcmV-)0gL{LP)Zi8ts2v=2~qWZ(s`oV{XTth#h7OE)%lUVu&+vXg-!65Y&D zC#@PNs^l{S^_wi~beCUuKF6onk3Fz|PN-uW7QoJ9k?1K_Ra@(Rp#OPjOR}*j*75#4AEF#LR0IW~?Eq|xT0IKY?Y6cR5 z%JOx=rMS2U0000~Gj=)Ea7_?h#K3S&+hg)Rmpk8qS{XcD{an^LB{Ts5 Dd-oqc diff --git a/src/assets/images/chat/chatbubbles/bubble_6.png b/src/assets/images/chat/chatbubbles/bubble_6.png deleted file mode 100644 index ad6a0f2e94cfa710cb3834199355687365ccdda5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 402 zcmV;D0d4+?P)r}X{V1+Kq zfrIoa*0C;4k^3cLUh4ImLJ05WBWcn+i_v6b`u`KwPaPRRyW@yt54@1I{Y@>gPMasH zX$>`itle>#Tc~SEHi+-~?4BKIjT!YKC1nBB@_tbfDH@9n4!g&Y@2J}3;nPKpd{qF_ zI4O5Fza;8K0LALe3=WVGQrlN0m!fjptTGsp@m=3U8hM$(3+Y}zX}c^ZAu6Lp^3z5f zF&Wb$ASh!yHqEUi?k{eoQVby`lg0_QV*?ly68&bMKh2&WUkV{9RK5-*p4F$In9Ol7I*3tJIq>(t{b*8l(j07*qoM6N<$f@T)4gTe~DWM4f DB4QmO diff --git a/src/assets/images/chat/chatbubbles/bubble_7.png b/src/assets/images/chat/chatbubbles/bubble_7.png deleted file mode 100644 index 8ced1de793b0861d31d192023cda8d8c535264c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 231 zcmVsp zq>?w(vZ41L5`pBLRa2pO5ESMP)D31=*R7S=p@(n{U;iM@=6^U42IjvQfpmcpgzSNY zP%tbA9K(dbF>BMKdxchJAp{zTasaSE2BG z`8b~e@1*nwp&ud*q6;;SEM;(3)MM4)`l#s;*1^QE__=+(P}793K)no}u6{1-oD!M< DO`jdm diff --git a/src/assets/images/chat/chatbubbles/bubble_8.png b/src/assets/images/chat/chatbubbles/bubble_8.png deleted file mode 100644 index 2d370694a46d13c645bb7f7c89847f5f82f025e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1206 zcmV;n1WEgeP)sTQo$P%|HSs;=%q?SNj!3;)%>_`ayW}5UK8Ft{0rgj5R4jF+-u9+aNU#%r4%%$9(z0+NAy=Bsu5gIp>$> zI9ll=`W45pQ5IDk(w7F(K1ULtBZ*1(v3T#Z`0+WC^jZA!xD%m+VA4KE61XTD z!qMNvXLG%gz@z(^>y7f569H5VCIccV@aR4OeU<_2lQzzu`2c`Fe(vVBu|Lx%JXFqC zfllXxz(oPzbIf9&w1H&+bG;F>V-|q#CbT>mwKC`aoe$Fwp$#Mt{fI53rMl&*Ft}ZL z9RNeyUa|TAw+8)PGLXpG?Bq>L07(e|$s1BAfql}3N%s~2HCOfo$dgek0I#^_m{L5% z>UEJAj|-#C;TW3tKBwhu&2xnTSl;}LL4TLvki#t9xuXW8u<|)(@i}Jk_=m7h+6q7b z0W#+v1rSg&h{~yc?u*Y?%h?(}vwRB~M~E=nzS9nj3LuceEMIoFjgG}r0wn!a8pRa_ zRKfa3+DVMZMKvq6iiR2NCw_K` z2H-Ai+;cKr6{q9oIVwMT%+*RC?AV#EinH#nL*-mxZCnGyij1D%Ruhhnu=35zVvHf!MC;qH0nl;t900-9tpdZct+IPYmR!-KB2Zkx)h&Xn zTWl^|V5WD8;OZ7Ly-V0a+Oq8WhpE6b09LOHTS!aijv8A?i~jOI0KEC{I{<7hTp)CJ z7=W4HC3O0B*4=d|^#K~Z8|7Sojzl%f{#PZaI?=AvOP{~^#G4th#Fsz44@h|I3|Gxt7Kr9kt!_ zyxMxT6dVAIMBIWS{{k-!(&_hEC5M-Mp`kJS`OG%6m4Sc*E;O=rBJRPCP{G>&1GpLT U?-Q;uMgRZ+07*qoM6N<$g3`uASO5S3 diff --git a/src/assets/images/chat/chatbubbles/bubble_8_pointer.png b/src/assets/images/chat/chatbubbles/bubble_8_pointer.png deleted file mode 100644 index f786e7e1828fa6aa1b00e71b242b6d579c8342b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&qzpV=978H@B_|{#{D^RxhFxRFUQg|N}VS`L!*z(J`R0&bFlp|W{rRPmy-WpobC_m z5WhDW`f~5M*YnYBKLLQ3k4U|Q0HNDF5mTUhZ~+zpp26kACBY&1r1;eo(Itt zl8mJ@;I-LjJFi;7yUog5TR|jd?*n%z?@te2@m|N#@UptAMtaZ7GXy;V|5<-*C9vGK zz)Lx|kkjLK?93j3YhbiBcuB9Gswg-B$C&yYz*D^WDCgD^c?x0)wFfhVV> zErIW3amoAK2R;X{j$p>h$D=`v?;Njr#WlEo#$C2n9s3W1M3&%L?0rCPwXvVs`j)l-eq p@UgTs`?9fC5%A>ub2mc;%P;tSVBrZLF8u%i002ovPDHLkV1iZB?2!Nf diff --git a/src/assets/images/chat/chatbubbles/bubble_9_pointer.png b/src/assets/images/chat/chatbubbles/bubble_9_pointer.png deleted file mode 100644 index 9bc5919bc9be443ebb40c9e8de396111547e482b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)L!3HEN&baUbsYp*3$B>F!$r(1Wf8<-t@2+D^ zmXL3ew3(Irzqz1t+PQi*Hnt5+GbCb!R6hO}WuC#7xI)5-L8Ws|10(OB|NB{+HhM35 umDV85d%0DIQ=B2$MEN4C;oC!M91PMkvwk0$apf)05(ZCKKbLh*2~7aBJuf5x diff --git a/src/assets/images/chat/styles-icon.png b/src/assets/images/chat/styles-icon.png deleted file mode 100644 index 74cd9ecda07ae47f809a664c9e240418e1d74d5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 314 zcmV-A0mc4_P)kV|=VV8AbheR-L z@-oZ7K4yoHVdw)Iq6_+_3E42#!2IjDAi)SiIl&%qu?EJpc7I7f-Q2XJ=+HunV7)5#a2r~n0+t4fMvvYD2U za2ZEdqTq>0N{Txd`)&KO$>ecr0HlnAh^ffkR*V?n`T_G~Rj)N8;ed#_Bnud!1}#a- z%p5M`l0cLFuM%9K3Za-=M%?TPjYs9XE?S3n9Yf>z^afhwvUZ#c>eB;^(as{jB1 M07*qoM6N<$g67DBaR2}S diff --git a/src/assets/images/floorplaneditor/door-direction-0.png b/src/assets/images/floorplaneditor/door-direction-0.png deleted file mode 100644 index 8c272a0a97a0d985431a751038632ad75d1602fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 742 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0((hBK~!i%?T|Ze z+fWciwSjENdvKR7fVYs|Wr{2yND~)s)3|k!b!7p{jH0oh=N^7VihL9=Z~zG;XYQQC zigQft>6t7pv!@{<>(}3}C+L~6=Nyp};xhEEakCK_B#oeNjhl%aPm&(~+f}L$!ddU&@Q9e$T4&@$r%F8q}@g}k@9pT$+!gCL0yd1M#|Dr zbo`XiPU>c?CQ^=$pkwERI#5?*u}B#zO~-XXbB540i@FhctwiU6b60%2W(=X+6_6|A{SSRa!UAxU&<7D=5i6_+C~lSHQ`k<@W&aXIoaNp#jMk~+;T zE=PuuL}yJRsl&C!<;ZZ7=qxFcb}lV0N0yO9=b9pE$J)f@$a0eC%qfy)u3cP?lp%@E zlp<+HZQ^pI97%L85lP?FE-pvPl0;{SNP1^$;&P-sNp#vo5?dFSBgc?Lr%U9miOZ4W zNTQQP-nzIPIhG_kySVnq@g(ub^UE%-BO;?oAiZnsIY;D#Kze5EX$Z+G+0!!>h&vqq Y0T^NF8ouP(KmY&$07*qoM6N<$f}nd)!~g&Q diff --git a/src/assets/images/floorplaneditor/door-direction-1.png b/src/assets/images/floorplaneditor/door-direction-1.png deleted file mode 100644 index 52e488f68b7ca09a5af96a5550bc83ae327df9df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 738 zcmV<80v-K{P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0(VJ7K~!i%?T|52 z<3JEaeSy6Yci3z*s<;9<;RbtvEfNSwNk|FyTpWPyHZ-*RKS>5#(#Y1YdR2C5rswzD zG@RGMnmtp+Rn~MwWZk`7Z=r9-n)isD5LcnI#@R+>kTins8fOz(o+MrUyV!xw&@AI* zBg>MMDy~9zXtr@Ok>yAN$?Ah<&|Ai0Bg@dzBft=4Hs0 z@%e`?)xoV2eMwdq`|O#|1lgJK_T&EX`Ss_o%Pn+?hPOoYBvC}(&FPw#2|qW#|FFPd zi6WyP$;#wi0-BS_;(}g*OB5NsNSc$o2XsF};yML7B+*%d$mlb+I43(ZcK&Q3iB8KR zqsN5ef{(~YlIXN3lDY&#=MEKDBZo<%(~`)c4)p!l;%ekFNpxBfNpI#Z!Pw$zWEe?w zS`q0`hpENY$Z(SA%qf!IoLgLtJVp|oDMiv7t%<9V$4R0yrbwFEy0{uCLlT{1iliA! z6IUbUNTPFyNV>ChaWztwBsyOaNoP(?T#b|`iB6wL;?%{}$TB3+84`JJ;%a0$lIT>C z=Ps^BmL-YKDy~1WJW2ff@U)5>h{)&?NN0^T?-4m6kiHpfIzqBCYxc|n#BDbJ0qsxk UxMV#=Pyhe`07*qoM6N<$f}g=q2LJ#7 diff --git a/src/assets/images/floorplaneditor/door-direction-2.png b/src/assets/images/floorplaneditor/door-direction-2.png deleted file mode 100644 index da1a1cb52a0f309307d4ccb9b335b0496ad0c88d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 750 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 diff --git a/src/assets/images/floorplaneditor/door-direction-6.png b/src/assets/images/floorplaneditor/door-direction-6.png deleted file mode 100644 index fda613acc0bb4344cb77de60b9a7b7e649caa7e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 747 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0)RkJA9#QbasSM` zUBh`vY^h8Zm)X)0k@f5U_dWERvE@A?C&XpwTjOdYGDsRhZ;h*o98Z$&{@orx-%yva z+Q_jaC5y|@8|pSz6FH6~kgPtagJv0vjT}Qqlbj(?C(Sk%6Iq^)BpG9%8MKShY-CwF zijJQWnn}AE%|w=?Bk0&Up&e*f<6@CzXz61|4WaC+g?ear<7|=Pv}Da8r;vMVp)R_` zm@P7lmZIgI_tUV(Fo9Q%Gw%H0AI*D25;iO$p_ zTY_%t6X%r9jDvsnkVI!qBI$;K;)0LJk0jAqvPjx_thgNcm?Sz&5=lEwEiOkMlSHRw zk+jp?;&P;nBswjLq#e#JE=S5qqH{@+H1pEpa%31ubj~S~X0#?QM~0I`XHJpS*}AwK zS%xG!Q;MXHrHRXtSIi4gwJpb9m9f`>35=h?~TizpbLLmKSZ0QKeD%nz* d1&G`2UIAD*=^CG#rx5@E002ovPDHLkV1iyePc;Al diff --git a/src/assets/images/floorplaneditor/door-direction-7.png b/src/assets/images/floorplaneditor/door-direction-7.png deleted file mode 100644 index 96fa8e483b9a17d70c89a2ea3ee67262033a1e95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 698 zcmV;r0!96aP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0#8XqK~!i%?U1oi z!$1&4-2e^I0~r}Jv_MWsKmiO11f(RS1k^@$?-v4xxZQ0hH^k?1-Mt6Jr-)h2H z2bK&>6c<_25s~%seb+$Wj3t|hoFpznXN}oLWRNt1?i#a+lqX5IUzc0Z8JcBO8!1at zNE-dG4b3*HiIgJ=eUhBMGxU~GY@`g8&PiE4Uo^!3=k7T4woy!Ec`BKcki#jFt|UnsLY$L(!=YV`vqhGnrQ4-qIg+vuL*8mb zyBjBqJWfkenM686GWKDYH``Db<7kn`XenAgLifgi-ipvY>Sl}<8BR;kvN>qRA?o6&E9iNupDdNZN61aWQh4 zBsx^yaz6#mHkM(K)3^dShzhV&rj>=p0id z&78Wp7+HoSI%A5Y8KsGfk>yCDbBIW~Q@XeqS(YR^yNIMSwTX+7HG6G_xAE=J0b zM5j;W+{DF5Ig;o^k#iRpBV|dVvxv(_%9F&Ww~s|!PeewSKsswI*+k?df%MH-(h-u? gX34-5Aa1q#0oVTQcxWGecK`qY07*qoM6N<$f{}SLG5`Po diff --git a/src/assets/images/floorplaneditor/icon-door.png b/src/assets/images/floorplaneditor/icon-door.png deleted file mode 100644 index 1b56bb2b56619b00671d9a8db92c13152961597b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 806 zcmV+>1KIqEP)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00MGJL_t(oh3%I=Xj4HP$G;~op~Rt3uuq?qKspE^kU(l(MXZxhaOe`n zf`W8#bLrT@ZVqX|!GJCfg@RK9rK>i96iPtBKoI*ULLo{Y!Oe5XyYt=U-o3lzIr+ZJ zyWhRv-TQF&yWjmDkSI~2ME|$QnB!?I6dI0k0O?{ei)?0Qj46P2=PS0G?NAm~=g6zF z@$in7|6Z$uY-R@QTf1Q_xTxxUe*d;L-1^oo_F5gQF}HFVeCz+#`X~XfOL1e@uV_iV`jN&02zT#OS+Y+sCbcV=n{|1P3sx<19^`P{lR*2J zFG(=wWXbR3nA8HM%Abb%qS6gLJOFWAt&fegfQ{8O0HCzyS>-|93AU9Mu(amc&E|vA z;*EjrUup8T#gb-L7Upnz*0V}Asyp`eyElTpy!0T_#|Y3=q1BA9#^WD?y}T6d6I3iW ziCoRF(@X(=v0yhg=cP_Y*aBwqlXzQS$RW_6%0-jwqx`r`W6 kwbi))=!p^~N;Hc80F`vvfW6oebpQYW07*qoM6N<$f-F>ep8x;= diff --git a/src/assets/images/floorplaneditor/icon-tile-down.png b/src/assets/images/floorplaneditor/icon-tile-down.png deleted file mode 100644 index 352c48dffb33a7eafce5ade65e44fbb469a859d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 609 zcmV-n0-pVeP)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00FH@L_t(oh3(fdOT$1I2H-d1-l339=u($fLc6(}-PuiW@(*+ohv3pb zkV)t!bko`HZY`nhlBtkQaPSv=4kqcPNiLWB4ytf3lqQ$E?;b9>&;m9#Ha7n%lzxoG zF;s^DV7s0I00tKmWA(WO2mm(gDV($t5q^)!3{-buH7u=|Bh&UF1KM_g6jtbE2&&pq z4OTUZ32o}IfA}j_NEya}N~hUwrX`R#NfSuCPAHBO>kNjITFa>fh>zC@0C0Kjm5LUi zPT^~RAi(mbbe!Yt>&v2ai=Urv)S$vB*@|VbyN8!XN2^WJ8p?pR1u8*_2u_7k2c`>@ zLPabW#s%gcpbRwuV-FOP|9Z)w0*pO}5uh7{0D#ZOdjP<}`SF2%5@WYq;XC>Q0Cc=A zdgBq^&(7I%NMF=Vu)~Iq*Om3tf@<$#KZ)~`-Evjx&>N2m=enzT(wdegnk@iSaB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00CJ^L_t(oh3%F-PQySDM&BS>3eEu$U8HadT4*Rh(9)%$q;W?Jf`SIx zoB~Vfq9o^_-~dCBO|stg`Y%R8XkL?*cRcg7{$vLX!!QiPFe;E9dugJlhJ|hB?|0S- z1eWs*fTO`U5`Frs7eNJB%rnHPsKRoQffhso_{^u9_33EXct{t)QZWHU z+*($ms&G6QcNo!4uu^PIOQA5IQ6`%RHWKqG%UoSeDw9=$+we>AYD&z<&s^PJRVGt{ zx?E(QrdyWDDIkfx9@tB5+!z zXJ3M~q9SRrHo1$2?Z`^>;Q}a#t$XY6`7pZ4J>uH=fBx^5VHk#C{BwQ)UCESH8~f0n P00000NkvXXu0mjftU=#n diff --git a/src/assets/images/floorplaneditor/icon-tile-unset.png b/src/assets/images/floorplaneditor/icon-tile-unset.png deleted file mode 100644 index 3f5e21817a80ef76a79f15eb063775a3c71bfc42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 544 zcmV+*0^j|KP)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00C@CL_t(oh3%FxZi6rshJSZ$B@P0pYkG^$j8QI-iKQb8Q!aoqcFrxr z8YLVgQaZm57-}3p;{a8q>U|Ot{223L{J?-92!bF8{{hn5Ser+30Kn5EonhzHoJ%z4 zvOjjUqwUru!{t3{h8QmA5=wP|6d!72_CB_b%xk}VKD=eRtyiXRd+ zWr21M1Hk6vb0}#@aJlU?>sM!snqo%()X7*9T)rp-fT|*+s>r&9f^)HOiz3%KE?=Bq iTW$%0AP9o+w|oP&*#(U`6+X}a0000aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00DPNL_t(oh3(hBPQx$|2Jr6?uTiN}7gC{i;{m#NX67BbFtX$wkl2{n z%gzR>nk=1=`XI-EZR{lY?=c|xlcK7L&-YWEI4V$6Q&aP=!s-wU3C_iv^9ca3pDo1Z zmICtTe8T7Z2LNEcUWp+kfDTSa3Rw!A#OX*NOMqUSPAM`MXdVcisU^0Pi@Z#xeTVk5 zh1pJq*a6DacHdHM_~8{@4Pf##(jF(u@!G4-H_uk#p8p zsjeH?@OuK(+otc@5y);50@>FYZk;`kT7gN6_a1zEIRF4|w%4Oc9Vj^;&IY7m=9H=< z`kCLCs3m@UxQ&BaRlZ+L!|v{%gN~$!BpF%&O9e(jnHe;p%z@H7cx diff --git a/src/assets/images/floorplaneditor/preview_tile.png b/src/assets/images/floorplaneditor/preview_tile.png deleted file mode 100644 index 607f450134966c1af638374d5da5a42ddeeeadbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@RheNKY5XkcwN$2@zopr0NjHuCIA2c diff --git a/src/assets/images/floorplaneditor/selected_height_icon.png b/src/assets/images/floorplaneditor/selected_height_icon.png deleted file mode 100644 index f763fde5aa1e825a263cbdc303cf66fd666a780c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eK!3HFi66di4Db50q$YKTtzQZ8Qcszea3Q#c7 z)5S5Q;?~{?2YC-Da4^ig&40P1+3s$`!kjA(7Zyx7_G1VC&Ta(}j|-J7E;^#N$q9U` zJY0CSrI>WrD{<=F?24)EbK2DR#C^}y8TICOxXb2nI%z-sW45QkmU9u0{+opN%vTmY VXpCB}y9sC+gQu&X%Q~loCICHTJ3{~f diff --git a/src/assets/images/friends/friends-spritesheet.png b/src/assets/images/friends/friends-spritesheet.png deleted file mode 100644 index aa72325dbd012f8af61c098fd6cb3f0dd0fcd1fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3494 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 U=O{OcDF6Tf07*qoM6N<$f)M<&NB{r; diff --git a/src/assets/images/friends/icon-accept.png b/src/assets/images/friends/icon-accept.png deleted file mode 100644 index da56941a0d624f6c76fae89e559ad24824207984..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmeAS@N?(olHy`uVBq!ia0vp@K+MO%1|+}KPrC%9I14-?iy0WWg+Q3`(%rg0K*0o0 z7srr_TggBE|F>u6IPSv!SG^@M>!DQKz8VjK!zPO|JZ`LP5?0P`$v(84F;e;BEQbaa zUxS8VVIQGbW=CHG))!J7S%;P}uAg6!d0a|ZZ?xB_YE8$f~~_`5!cVlD~t3;zF~;rc0Fpjrmb0*}aI1_r*vAk26? ze??0#jxr!{#lz+A1LHJYD@<);T3K0RY{KI$!_* diff --git a/src/assets/images/friends/icon-bobba.png b/src/assets/images/friends/icon-bobba.png deleted file mode 100644 index eaea89573d4520b0e2f808d522f2653d64305969..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|sRBF!TQ4PYH5hQPCiw5( z{U$_iZPi8Qi=Dp~vj^$?oRzGkc3t67vukK>xPwiDYJ9H3>|;ur0kW(Ug&u74f3LaW zdmiHpZiWzUgFmxn8Efz7DLb@0{-Iv|kG12+ru*ItRx#K_PF~$pXPLtL>MZZA1-ESs TnliG1b~AXo`njxgN@xNA$niZ) diff --git a/src/assets/images/friends/icon-chat.png b/src/assets/images/friends/icon-chat.png deleted file mode 100644 index 631b7bc268fac863d11e8332e45bb0331cd47cfa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^fS;1Lc4Vf}1jF6+9%+|7FRXt$`9q0~)K!E2WxhMrGtIA6 vTTfmbvwv>n_sX4CKQr27%`y+_f6L!laH5pg?A1!3BN#kg{an^LB{Ts5z3)i! diff --git a/src/assets/images/friends/icon-deny.png b/src/assets/images/friends/icon-deny.png deleted file mode 100644 index c74e5c067c071acdd2203781c6eb45028f1088ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmeAS@N?(olHy`uVBq!ia0vp@K+MO%1|+}KPrC%9I14-?iy0WWg+Q3`(%rg0K*4xV z7srr_TggBE|F>u6IPSv!SG^@M>!DQKz8VjK!zPO|cBHKA6;{q}$!79Az_2MP#cY}D z;uunKEBVKH2MMNw^(j3{?Y@R~XJ52E*wU-Syd+;iM9_p`w#o^H8Hz5F43`^tgL4?n zoG?AKu zvOBX2J=jvQ&_mTr(IN;v)XNGAB6v`2Q7`r)J$R5_JoKbq1nHsmW&T;DUFKpS$;->{ z`+dLfPrh8NFCE*z@7aAE$L+6GE6ePDkeyFYPO$6Z?OWH`?TM&*GU2$X1KGKY`|#=v z$L+o4H&)YC=M5XtK!ljOMC=9;Lv!4bxo!l}8cBgmntoW~|M>bF9{9M#zgci(Cn}Sc zU)_qy%GOc?ZLJ{-^K-9(BVC&j1SEx^8??j3?w0r-ug%ukw#0)TBwZ`<^O-}i>eNA* z#sm~ZLqLjN1g0e_hAwNyt3Z_%OOlI{q6xBM%Z6Pr!QkMTw-|f&a%FMgi#?V2R+>h( zBy~C+v7?DJZc2(}F%DHyRe>RdWHU@*R|u0sLxu`TQ0zykPeYI~LYJB0u{GSK@-;-s+|5owtubUj97VS|L}p`kO3 zMz+y<-0nq+kwn@gV6cP!RYj0ZLDm|oY%7MX>VmA>vfPI{tP?Oy;do$*eQ$FdsN>kR zFiByENUc)hnJCfsvF#GelTBg>1>#wPjtpIJ*@l2L=*kAtRa}HUUCh2h(R!A^%)Z~a zm?Fk8%8^|(O|{@+B$x&vg6!#v;9|m}b&FVcvE>;A57~~#KKpiH`(f5h6=sZ{Yie#$ zHw6fFPtX<35{e$t1k*JUhB9Vibsk`3do&Ip>l8nLO(I2MlL!B*DbqHM9g11bwXB~R zJBy;~C#-mzgD+%-oEfazKIpZb4N=zZB_3sE&h+-T{YPYPJe_^}PKz+o9g5$FCDcnh zFedX&mgzCtOM0CA1a9mse!SBEui^)(MJ*UM2^*ghpM@i3gQi~?>AyAWy?baV4dHCk zWy{fsWe=kvO+rQ;vk|Q2FTcme_qAGOzEOM%{r%vNW8}% z9|ZZyW9_4-uY7WF7T@`EX7BmiD>uN^iTBs?Cvq2+9|5#x4(Rz`<+iwcc2DlB=?nKR z?-Ds}`Xl%A>6_0iy)=9Mw=2ib=H|Pt=cDrT@y?ytuJ=^!r)z9w!j@!QT;u&e>_nX=OrnazD*?#@> GxqkpM;wUZv diff --git a/src/assets/images/friends/icon-friendbar-visit.png b/src/assets/images/friends/icon-friendbar-visit.png deleted file mode 100644 index fac57d9a67b21a01f5bf9cf9efb4f2cb72f014b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2150 zcmcIleQXnD9KO+fK=zMKu6^%) zpZEDazu)`3zqXc@u1KEo#0&&Ml5JLt1OBGU&$J}?-TnBU4g^tHxT2!6g7W9e(dVsN zoxzGAndfMiE5(+bIRJpmHE?EW)(j!yXldE(aJ@3vced|z-`6|7MBnSIth}5y=d#k- zkL+$kGL$DjtwP%ye?F)l=(*6i-Z;FrXK3B=-vX7lI_~JkP3g(S@iYF79bBY7sr4J{g;gsfvgr3E!f%yZUE0~!ouWHH}*9HZ1 zQEXn>5#9tuya$}fo)TjhYM^k6;E#opC$HY53W3yxhjnR4R2#3bThEQ=VM2qtl5MuH4_%Sn&3? zMsRay(-*remRSvSR;kX=)LZvKT3W^Id(r5PJf(8|6y?cFVl*1N!d`|J@dAtHs0}!+(VI|Xu3BTzlR85- zswFkK1Zg5PI-Jx{q=CvYqOlJKqX~?Ma#%`YvEZ8-^GQ;OB8W&NqK@d)yx=7?xw()- zOK7z?MBrjwPy)4hP|O%-u&^R6a3P7~gQ(01+#-P%%6at|*ZBUGr2^Nf~1tCJC zCgqgIfp+_&p@BdgElR~<7$v6nfyAP-F2oWJR^)30nk^2qK`CQA7(>VRhH3==Xr>HJ zuzofGVImZ!iH8dLc!?K%{6q4HFUPY9QAGj^Bwldxynp! zrq~wN0wmUqX-TaHCyh9%b81OSW2EGs9C!eO>x>4ImNWsk5rEMwA=|S82k#E>Ph^!UkEcs%T8b! zEH=$Opum$$WsElBVsK!xaSU#GXKVe?Q`j#*maIu)*|NbSCHqDk?QL^c=Y8X7IDAT+-THm^mGoYz zeqDKWhWV!-#A?f8!=B3K%dPgTra$iA>caY^yYy3SCYA0PLXW;{X5v diff --git a/src/assets/images/friends/icon-heart.png b/src/assets/images/friends/icon-heart.png deleted file mode 100644 index 5dd1015e96c2e0e20406db65649298b01fb76c0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|sR^Dgjv*DdrcOG@+n~VXI`gQZ zMP-oyzsek$Lz9gyT9hrCltb+{ZftZq=#q#xy}p!CWwZ!9j>-L8zQ9Xa5|$l zyy4TVG^O{(FLoZAqZ-SoAJDU3=c>*YZjoJ0$v0Q2d;H+E2V+CI%iulfD9T@GFn zJ9C6QJa^`ZZE%@An^jlK(M#gz)WUn3oXk)5)Eo4QcnHPs0=kXC)78&qol`;+00&4& Ad;kCd diff --git a/src/assets/images/friends/icon-new-message.png b/src/assets/images/friends/icon-new-message.png deleted file mode 100644 index 46d23f5a29640cf90cb3a5a5436ed9eda89d8be8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh3?wzC-F*zC7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0(2Ka=yT3A^82Lfxuo3cV%C51kI{0NkpI*mUGNU@g$`2~Yy|Nm!@@@94e z3UL;AL>2=rISj&#$MaXD00nJ4T^vIs!l(8*@-ZlI91ckMU%x52<;dc14wsKMv+Yh; z!>#w}-lZkGzf2Rnl(Ov0&mI4d?rdQ6xwmXmHnU9Z6Go?wV|Lqt<}i4=`njxgN@xNA D{W(nH diff --git a/src/assets/images/friends/icon-none.png b/src/assets/images/friends/icon-none.png deleted file mode 100644 index ececd9ee44c9653be780ff796ece6214d652e479..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|Db50q$YKTtZXpn6ymYtj4^S}K z)5S5Q;#TsH|Nrfoc~+O?{q@&rd+B&lC){Le29I&d1nC0|Q`!^hz%PYfeXVxrZ rzWnU|gPgu(Esw_zU;e~z`O3IxDN|Ep+QDx?gBd(s{an^LB{Ts57UODL diff --git a/src/assets/images/friends/icon-profile-sm.png b/src/assets/images/friends/icon-profile-sm.png deleted file mode 100644 index 60107e1e19380fdb9d104d71a27f97ceedcec6ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 257 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mg-3?wJ#d=CavjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCilo1AIbUfwWWiCX4b}_gu}Jo16dt|NrvkLxz$}>+^fhpFhqpx1Y%eq^3k+ z=_w$^TN30K3{(RL47M+n+JF+A1s;*b3=DjSL74G){)!Z!pqHnMV~9k!Z(lUu0R;}0 z?b|*@?EPQ4dsf6Ql>-L$35yo}UG?IE-#fLcDN=WNB4)%gZIXOWLz*d$m2*bjS5{b?!r-B+uQ2US3Sn z-dz_`oR{)aDvu#TJ5OFEEQ!U6gSz1Q-=t`WPY%ylg&jix9hbnU?J? zn9+O395^u6pH#<&RZ%0_AI0195+X352k^X+HC-tmA&R^bn)|OQ0xv?m;Rw;;8^j0Y zINoJB5a$B|sWMy`4~YRr;OL<62+q=sNYP=636eA;(SpQ>@bX0q1Go@y!uv(P{=7YSpkrtFO6S#HL8Ilf>bTG-%5+g_)Ptu%3(sGzD-X2}Ok^xs=F|fD4C6HYlJCJ|wWBQq+ac zM=f>451@a(RJfX@B93Z|B%TX19LKOED~1@72b@BR3L@u2v>Jwx5n$O%#J1DX(YFJ# zH?sPwG{hL6i(nhYtSAjt_Sg#>CCAbnwlr$t_50Y~7PDy1yP0H{)Q1Ee8kn`r|7 zS523dwH(>fP|SmVJtKBxw^w&j@(SfIWB@*0o@I5sSauRn{c4X8s-I@45#`tVO`^9t zoh8~_1|rfGl3#+kR?5o(2X>@Uq*qa1)UD*ZV02~it4sa=D!v?AH3Q5vMD3Fze0M0n z(UcNH{WoXDy&IZR1&%tMKdrV{w5T>|Xd-F{wczEogS%1tz7mUeB*QO%@G8^rDZQcF zZAb}1V@qv|d7|OPp$piCzRhd)kMB4(_x{!9+MerQFU~bTuzhNF`iZ}<8Apse$AAC$ z;;yAata0IunX8ktQ-`*^_QLjewwx+VIGyp?&+hR0&Yc5iwS~`zUq3!S|K-S;jryMZ z-(J2x0Z#}=4kzwCc^W&P=f7H;KJPXT)qV5K`atLSn-6bhzi^-0H@Bnax04&+{dL=9 z!{lDR{-y8sCcZs-y#41*coPEXK`DfeZ_=ks|C7Rmme!PH>pP9aIchi!1 z`Jr`Pzbx)M)pOvF$6J@bpFTFQ=cD~j@gp!kV%&ra@yj%_jTnX1ehmKc1}R`$2&Vm|ka!T55^XP{05H diff --git a/src/assets/images/friends/icon-warning.png b/src/assets/images/friends/icon-warning.png deleted file mode 100644 index 3a3ffcf9efa03104936b6823bd7435cff4b4a610..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^;y^6Q!3HGPJ}O-eq&N#aB8wRq_zr_GLB zeq{8kw;XW)eZ?&6#hu4Hmp!{Cm!HhG?puX)X7n1Ls;kD~hxUIs<=V=BrCNP;;4|i) Xl&z_ce_Xf+bRL7JtDnm{r-UW|QKMd} diff --git a/src/assets/images/friends/messenger_notification_icon.png b/src/assets/images/friends/messenger_notification_icon.png deleted file mode 100644 index 73f7e5eabaef31fc17d4dab783300e28b09d93bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1|*NXY)uAI*`6+rAr-fh6BZc%@MrGHV$@~W zrI$AR7}vN>aw>aI)zvhq34a(g6oSLL(`1YY^C zzUz?FHkPvtm$dYfbQT_AY6>-;rtri6>#zCO#0&zYc%DQUSuiq8J*zZTT`2Mf&{_sh LS3j3^P6~)y}OaO!GOor@%?@i zo`wxM$y^uqnyp;tF;jkG$%~*8=WQ)rnVcf$g5mCD! zsd6Uw%ohjS6T6)kl%Du>{ChyV-88M9))^ZOH!TtQ$g-yI?|<(#stT>=ufZ^fSX*kAhak>iK zg$)%#&eZYFyzi+{dcuW=LvnMz^S0U}Ej&f-K0q=EOulM8v)CFazekR(#peWrqOg&G z5rkkKT6{sEdyfF!ZwPWfkU-%Z3m6#!<<9`+flM#~;}1>$t`OODHS_XPmfov@tDh^>v^wuqH3KrktPi4*GZ& VyPaJ09GK`CJYD@<);T3K0RS|c?-c+5 diff --git a/src/assets/images/gift/incognito.png b/src/assets/images/gift/incognito.png deleted file mode 100644 index 304c30c253c0f8849f38538918c2f703476f1b57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1057 zcmV++1m63JP)3ZiR{oJKZ4@ zqqSxg*aQF^OE8Mx<*EC1Rd_h5oc`Pto1NFeheZ1Jzzad8xjx-^0ih?`pw6BDb>n{)!7*5ZAiEwdno??{OSYekJYk?6qKb1 z{i|MH2rylnthB+d zwZ*7o5~vQX;xV364HRYtf?x;?$^lI08P1W!G63Wi+K&&P7XgTbi$Zy|+F-@53Wk!C z0G8?X4gkT80kj|Q*Jr_durzL;f})YY=ot1%#puWAnzn_(lp0Wq6&p%)4JCuX00gxf z&{Yls#rkiMC5k} z>=hEd%Pl?oQpdX6l*v8`ssk~g#}0EAKQ&$>j{i*jbSF6}?(or~HiY>kRPs1%JsCt4Q4CRCONKyjaxsOY`s zZ){Hau`B{BvCL>FX#lj~0_)Aymdttd@A9atOra$Jf$6K#f!-e~ahpIi8I|DT-q%lLUL|Y&s^~e*rQE b?4Z{_#gM&@7i`=H00000NkvXXu0mjfW9Rn- diff --git a/src/assets/images/groups/creator_images.png b/src/assets/images/groups/creator_images.png deleted file mode 100644 index b39b0d7b83eddbaac0371d61c975412730c6c32b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7966 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 diff --git a/src/assets/images/groups/creator_tabs.png b/src/assets/images/groups/creator_tabs.png deleted file mode 100644 index e95b9f0cb0eae57a2178cd5b3efa87c58f61e30c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1215 zcmeAS@N?(olHy`uVBq!ia0vp^tw6k#gAGU)mDzzLI14-?iy0XB4ude`@%$Aj3=AxV zo-U3d6}R5rHO#x>Aj0-wuTxaj5y4AAi=MD?a27I1NkuIY;pm*aq|rlUPQ$d>6WZ!d zu9=aN(|^3otmW&z{H67iGw$a6IVo5D>}T%0eO3FXmgU9G_PA+N`LXKvr%%gGgm{nf z9sPVhe#yiPg9QxCTv&)M4$uGI8c)pBm#6#57tK*vz`(?XPVn)${<>r|ufY3Heq3~> zx(e6wjs8uY>DHR(z$}u`5a`OtCJ_o_ES7H&+_5p{wX;E!*|gcW79KUOyW5%V>w6&Xwsl!#Hf#a4Q7l%UHLI$OZ-5LrF z8H*U0I{3I08eRZHq~l;#9*A{8+2_B(Q3tL@n=Xg{8*Bqsuw7Qm3P|8#leoI7*xy|Sx_iVhVE-_L1w5gtVm4Bx-yRuc6 z5Su{ZulBR6ejAtzt**bZMwwM$0B)Xqf7cU5e@~NJ6G*}geCqS zUU0#lhYL*k++48fpu5}0w@I5tH8=nK@{H~H*VYqyCl9|Xm{|AoZ*0ou+VX8Xt@|4k zfuZIh$|~{t?3K_faT*6A)Z5;cS{E1gEMiEuRrut$zv{MM=i_@o3HFXXm)Eb~rP(j^ z^1YBd_c0YN13q~dw+ZFHZl{-PTzYS*+9%c%2~^16^(pPtadH2vjDoH)$JfdeH=gR1Ihv~5zmqC)4gg;PmT;oR_5mSkuiEGL(d=!;9?-qE7 z;n5E69`S`I3>qxnF+D!&&ZW?||3JmX8B84#tj9L5w`=GKPOy1x2TUDYJ?if>m;~1! z*kSpd(d7)&mvEdUJ2kWs{b}3S=9>u2HkMN2xwK^#NULc_P anf+4U-PY;(L8`zKiNVv=&t;ucLK6Vt7V4P* diff --git a/src/assets/images/groups/icons/group_decorate_icon.png b/src/assets/images/groups/icons/group_decorate_icon.png deleted file mode 100644 index 3a395fbb7b095a1379f03fa047855f35df7293e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^{2t3o15f)dLW3X1a6 zGILTDN-7Id6&wQs3>g?WWb8KQBKfpx}=*-IH0?u^_tQ?uhdD}(m@Vi`p&+~s~n}gjr(`b_1=KrRvAYM`S#bp zbP0l+XkK D3FK$` diff --git a/src/assets/images/groups/icons/group_favorite.png b/src/assets/images/groups/icons/group_favorite.png deleted file mode 100644 index 4cd734d12d6c5bbd6335c579f32e7dab3fac4ea4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa&H|6fVg?3oArNM~bhqvgP_V+& z#WAGf*3?TEIU5XkST3x2(4MT}alAlyd8v} zlUY3Vpwo=Rg1pzpaUXcTvlgFF-I|}UzGp7iCxf8>GiBa4pHxbdT*~DpQO+@Y{i?td tpHz>u2-ypC-k)$JKCt=!0j1DaTa()76ZkFK$!8;-MT+O!CFrj z$B>F!y@3aL4=8Xvxp;8K!uw^)<%QGpF7ak8SkPfI^@-0Ond6-do^y};Z3xm?QoVR7 zo8aZI`eusO%Xxh&TsFFw8*jMqpkj8@w-x#;1RVRfFFYjB{NAraOtyWGUR(Lx?F;gZ yRBwBoj`aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z008+(L_t(Ijm46&4#FT1hQFHbK8gdbET(n$HH?pAd<@;&#-*zrd=uSG za6no>XlP^NpIk_Q`}w##_=n0us-K!EbyumTi;4bX2GbxzXCj4iDk03Jbm$&=GG#ue zgRz{tX|o)ls*myPrx?~{7rnbJ4*()FFIM|jpKS7U)ay%|og{VBt^qRt8%f5N5zw0f zoqtu7g;eT{ZbU53nC1v8fbX%NibvCjy&oB&c%i&H0aOI*D}sbQ z-G`$u{!T`Nm^%Mj%mha?aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z009e0L_t(Ijm49}ZG$ivMjsV3aA}oO7D!-%4pOo}n~oBa1qy>?0-P+6 zOQPgJmT(X7JH`ZLP^Eqn7h8V3?>E4IWc~S}{}iUR*1ph}k^Fdq(<5Rh@v$6h2vaR> zyQ(^STZU6^u_|`Zo7Ay@24`%2D%RT=8qn{CehelcrOPa>m;q8Z;` zsWdYQc@i5UbAo!lx9iEBZ)_VHpx7M``xeNVQ)z=Y+Z>>@En9}i!@dusnl*EAPAOyA p0`}dU6Ey(tBxd~2Kjn;negTP?;AQIgxq|=z002ovPDHLkV1hKJt!n@P diff --git a/src/assets/images/groups/icons/group_icon_big_owner.png b/src/assets/images/groups/icons/group_icon_big_owner.png deleted file mode 100644 index 52b8361e5922b4346349dfb6e55dfd61bb100a50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 460 zcmV;-0WaB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z009_DL_t(Ijonf^4uU`seVV<6H7D4bhOqV?z#G_c4XGp^zym<92`A9P z+QKV9Pcjxb3;P32tej-SGH>47H?s@;O{g@cpNbLP>1$CRfyJmqP}F-+$c0MdUMvAo z3C86lZ%ncY8aFX%W23_?Amp+UL3be|wtZ=k8sQw~sh3MR`s&@_d2uVcU0zn+cTuij2~DO(5S5_)HuC1}%Wzu;kXKQ^X(dp1 z$g2q1=F#WtPR~u(&9=;r8qt4~;b9y3PaUEdw%Or{d=+U&+2QG}`^cqU?C3o=UcL(v zLDkLO_{~n7A0>}F-rZ&e*J>AnCSx&y%|GfPw8IxY`Y)3B<^Ko(0000j1DaTa()76ZkFK$!8;-MT+O!3s|o z$B>F!y%R2S9#G(MF?OH!R*ZGKM#-W&tJbGo%fo$FvIp|$pOoC}ka@prEl0w+@JKBN zmcNHsE?Vk1I3>53MwxRdI3LwK=U?l}diT{wkvZ;FHxEQREH4e;pXI#UFFL{e&cm=5 sk;k(RvTXnQWuo1a*)@M$rtD{oJR diff --git a/src/assets/images/groups/icons/group_icon_small_owner.png b/src/assets/images/groups/icons/group_icon_small_owner.png deleted file mode 100644 index 7230ecc590749527ebcf0e647d7bac6b6b287536..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 215 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uAB#T}@sR2@)1s;*b3=G^tAk28_ZrvZCV5g^x zV@SoVBX z7?*wA#m_v0E!*KyayOF;!-E4mlx{IT%gm8DESAz+VIaf6u*T`D{kiw?(m+Qsc)I$z JtaD0e0sz9@Ok@B6 diff --git a/src/assets/images/groups/icons/group_notfavorite.png b/src/assets/images/groups/icons/group_notfavorite.png deleted file mode 100644 index 835d8eb7e4aaa03b8a858581fa5cef4dfca55243..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa&H|6fVg?3oArNM~bhqvgP%zQc z#WAGfR&v4uwhLFU&gMLHr0cNi`+IwT%ePDveJFH%0t@2|r5P4JJkG|Om?Rv`I3jtL zyOkV0k;F2$dyQlyPd39r6FG|l23NyP5(g)+YPuY&FnxH*XNuaQM}2ofObQqnTD*Vd Un$!dz0b0i3>FVdQ&MBb@0OD>qrT_o{ diff --git a/src/assets/images/groups/icons/grouptype_icon_0.png b/src/assets/images/groups/icons/grouptype_icon_0.png deleted file mode 100644 index 9dc4191d5930a80ac818a4e5391f44c25b5b1020..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 542 zcmV+(0^$9MP)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00C-AL_t(IjfIjyO9D|8g})g~W>o}Y1?3_vNg7&+?IkcG692RU7H zO{W<5%QGz0?!;RDkH_nFEkEba4RUnJ{TXC!Pu8^1dUusFh9ey%3$HRyIi+ zI*+`IyxVQP)KgS|-Nkc3%8q`JI~nT0b@w`YFUwu3UNUXyw5<*RZL2dByC!l63c$(! zic_6=8*xlq$-qD7NjaT1_T%~FmTL#?B##fTlbVtn1;qF|I=qYp9V27CkyKddkcFn zc41~_=4R$FFflMNW0~aUu+1_=<01p=j2W|+GA`U1xoM_m$9Yx;|6QUP(z-W#fL5*a zba4!^=sg-_$#+D7M<(E&%iEGa9equG@;gi3`fohjv}0257FRc?2OA}h-8gXDfWg5f z)vu$YQmH^7@Z-J1me)N(SsOmN9AT2sd;ch!J)HBsErZU|uL6RXSwck5?c8?#D|2eW zhqZr=?j5}5T)VcuwCvECglCPL_ug72Y;k^b?7Q7TmCi1z$96<`YwFJFm{FJ3=6@&A toZYxQWVd3A+p{_EOW6O|o_hb7SKP)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z006;BL_t(Ijg^zJ3BxcDMZYwJLEs?*u3csV^~nTTzyo-JOyKmIAf;+U zh6o5UM4Tc>Sf@ML{@s1Uvz8B?p5b90jNcz#|5Bo$j>38JL1 z83w@GREMr(A*wdn%yU+A5M4|a0vr$kG61ZtPUWOI^9Y0mh!E%MfUP@+apVD}?_~&i zSlX}R>R#*(!TX|_3qRZ)z<;&VBJF|DFhEv0La;hwlJ`Y81FRu6iJxf?g!|4vQhj2V TPA~^R00000NkvXXu0mjfrTmLT diff --git a/src/assets/images/groups/no-group-1.png b/src/assets/images/groups/no-group-1.png deleted file mode 100644 index caf0182de3d431cbed221d3ed663a458ca9f4d33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5007 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 diff --git a/src/assets/images/groups/no-group-2.png b/src/assets/images/groups/no-group-2.png deleted file mode 100644 index 797c946800de6e8f40e72da9a1beac732e6e0445..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4401 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 diff --git a/src/assets/images/groups/no-group-spritesheet.png b/src/assets/images/groups/no-group-spritesheet.png deleted file mode 100644 index 3eed4b97d09288588d38528eec838cd259d5d529..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29386 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 Z;?L|^6!j} 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 bnUa10rA77?wG|{O00000NkvXXu0mjf-iqfB diff --git a/src/assets/images/guide-tool/guide_tool_info_icon.png b/src/assets/images/guide-tool/guide_tool_info_icon.png deleted file mode 100644 index 32c4a3531d85f39e7dcc6eaa55cff6eda3aa1568..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^;y^6H!3HD+Ytl-ARK2H*V@SoVw^JRt4k+-je4erA z?En7@mbQu=bSuw!vy%JXBOj#|Y0XoDwq@MRsk)HK*{F0uhN+H`mzuPg-fE_e+;I-~V k{Ys^S7d$>qxp+^uaJkH_!>z3>K&LQxy85}Sb4q9e0GcOBdH?_b diff --git a/src/assets/images/hc-center/benefits.png b/src/assets/images/hc-center/benefits.png deleted file mode 100644 index 508ecc823cc7ce4e3a715392a6cd4c014787efd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14475 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 diff --git a/src/assets/images/hc-center/clock.png b/src/assets/images/hc-center/clock.png deleted file mode 100644 index 4c37e957de4bc5aad6c1e967934451a71ab17c86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 267 zcmV+m0rdWfP)&58pud$4f02g_0f4z|VP6tBFiWg_H3)xMsSo{f3L^vqIv*4P%fuKpm6jWfslY%BO1#Xf8`kVikppL%5-B&px5F0NoKsY7Iz<(%~YSu=BShmchlqYE!)0d!)ISx1pw&ui;|UO zjgfhRo{)+KjER?_n5d?!maUwlj-ZkQ2Db(Sum!fbx`(~E!o#_{!NkPBwaCoMoX5<* zt*Xz_$;QIU)V$f)(!kck+O-Ge#lYnU=j7?_?&{9G@AL4+^zZA>_wMW41N-gr$up-d z54(Ek2-*XvFwjAP{~8_y2$7*geHJTbEGTE}tCJgB>9Y~n>`aP6+G3S9B0g0AFlXT%yq&}6FgDSD-MyLI7vivEPY1C;$ zO(9U}^Z*?-Uw0ZfTOjR2wr)w9)$ziu)v1u;y3E>9(yJw!qlEfMXFdrFX01 zMU8zvW?aZ?0Vlcf?rhj~I<#Eqcg=ss1#B8mjphgn9;g(Ozc?#;4qT(FLNJgThJJ zSAYCDcHnpd4p`t&Pqeo~Q-4uK6K&JcchiL*J~QAY-c5KSg(Gsf7cnG0gkyWd@UxhX z!uV*%c@QEf5{q#iFwt^@>UE(QT zRb{rq#tdXOIpd~RiUi^(E#~wh49Okfl{r7kb*eh4N~)rTfVQ~Dk{EuMUs(Z<5 zvjN}w1qTH$JSnvWM*Npp2+s?jy#IBJ=f`}Zs}L6*>%!oeWR-U7Y7fgQ+PpIhqvCPdic=H^w4LoZ(E0;=^d8u=+eG-;e5TWl(!B3Kq>9Cmwj) zMiD+Z;CJb?IOBgCex~D;4k3Q`*`3mf`Q(&pD!J#MlWsZa7{6$Y>cC{(?2E6%KFaE@ z&)$0NTKE00)w0Bnd+xQ!4!n!MS916fV;~QP@+%*>{2!$}|A!sWM^8=l)MKAK^x04E z(3s#i!JPQjV_Lo<<74ly66e!!KKkva&%G8b)NlX&_=8|j{`~jvK_~zWpa2I*zyccZ NfCx;W0tpxa06QD@YUBU_ diff --git a/src/assets/images/hc-center/payday.png b/src/assets/images/hc-center/payday.png deleted file mode 100644 index c9bd80ba0406cd713215b03afd0ae1c19b70a051..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 721 zcmeAS@N?(olHy`uVBq!ia0vp^_kegB2OE&wm}9n$fq`j;r;B4q#hkZy4EruSNHhd` zn*;;~6m#jFlKiHyCFF{XqNzHEmrGdR$F?J7Uvh7J_xAUib#cd!DHGjK8SosI+tJ;< z`Tl=~Z7Mb#9Q;g&nj1bSC=3+ygZduLhX-wCch5Rwvae?Hhy9i%Uu(a=hH!4}DG1qf z^SS@~`S$*gPsdOhH#(l}}7|%@+~5o}R_Of4zNv@i_ncFll+yR(9d# zAN(%L?zh)9F0NIunNi%8oLh3JS$dDey+d1D*uy2-zsub3+IsAw>@{JzGZO!`dgIrv z*?Zc0t*Xt8&nEKs#g<*<KtTiE-(D+C1OSX$T_A38b^%WQmo z==Kl!X%E&4ld6*xTgX(~xcU(DyGO5nGU;rqc-4DYIojsyv4<0N=T$xaa6-&~Z(&7B b`1yRLqq?egzhAcklPZI!tDnm{r-UW|2B#3q diff --git a/src/assets/images/help/help_index.png b/src/assets/images/help/help_index.png deleted file mode 100644 index 2844f41e11f70f4f07c486f4221b242c15aac4bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2569 zcmV+k3ikDhP)waCoe|^~H>Kcaijw@mPIPh@?`TBTiT>uA$K7oGm*3#wz z=*KCbBLQ^yM+5%`?CtICvZ+V4zQaFQZHLfrK6o(dwGRGB%{&17)7uY5z23ne419t+ z*8b6+K7Bf?>Eqv{b?^rQpWu$bheyxuEH(f5^$z|d;L{kOgFi6%u_;eYJ?!gY7tq0P z5aeJBxrzfj*uTTqhaT457IX-TaKEmaQ9TBpv+mb#1U%)Q5dxUm6sUPj*LDed2fsC+ z97Ws4zoix-y$AQ}5^yK7dOD{pbQ9{cLi8hx>X5d{1H5a_1}pJfZ;D zAj<->Mid3$bA=cQT|3q|vH)h#sqii9=NpXzZz;Um;5{O62w=zXoy|Q2Zz-@y_*$3E zB7i-^=bQUL_!fVDE8w*PI0yW~KHdwy6n^Qoa{|~ad~r6d7=8ixpI`nq+4%WCKl0i5 zS$M7p0eEHxcLSdlffhdU5IqQFZxs|6knUMqms z;70~6;V+<5rUh@gSuOBd;Bx|K1%55~cNa|kp!Y^SD%S$94W1K#wmeG9B9+I;pjDIq zzsl~dC3p;lOS9ko5eKHTY^vUt@lv^9ggf<)%r#3*b6?L$1_va z0=fmhb}|X)2POfO%pSJL++6_hz=yy~rYW}q-UFQyfERl0>05Hj)6%!WmLf7YEeCyY zE|ko{w=AmA+^0EN^d^-5Ew5|3u!$G>Z4sCt(vML>@P9+4?bl|2Fe8Zv^1 zCxz~u1m2Q16_uWh3u`ERAVO5jTtJ^xA9aa^R^cV z2R_%-k8H!hPc{C-Pf1@gViAJZ-D&mkqgvoK`Gc_RArH2;fA)18c&fRNScI^~Qs_0; z*LfC)%$j)t{8ZZ|@Da^@=^}(Pg7;($Ynpk;^#1*qWx(c*A}rw31)={~l8b&u@ZMB$ z98XEFQQ(m~$AfqG^$zej9BdWA9>GiZZU(RD+a>73{fq8e55J7|MyLb=&w|7~fcM;c zuA<vxtiXL8UjHC+q;0^wT(Fsu1Q)6dOmQ&YZC>*AsTN3E};GG}s6>E_B;3te05FVh8) z05tGn)1SU14DsR{!~>pI3nHV;3m)ai&B`T}A61qf=vMeM0p#GrY?WLg!PzEQ5N87q z%Rrip!M^)g)*kRy`05cqm9E4MV7Qc_mP?>VhyaoO=;@6y1N?4TOw*rrwRjT`G0bYVGC5o0pw}Kx^ zz)M{K9{jZc&pbb_33xnslbZBhfzQFm0w`(jy`U%$BfZuFJQwlQR21)sUXzJa3|<2t zdjU98v<7&bJw&-so^zUNJBqq-HGCNO$HJAsw}N+F#Ik6?Tk|!ba;*zj3!|aqYe?lm zJ^XRn0i*za6YyU6*0_HTI1YkPt|h*{luT*?&&AhsWs!E@g!}ML+rT)%ODS04;N9?* zv41fM5k?P%SwwEkLFF50p-Z7wO*y1(*5Q`xc%NNYZD%rZs(`ol`#AI~#r`Rqg*#EG zlj{Pg_rT9X0cZ?*EAZUvvCpGtQ|%sqroZ9N+OFEZ26*eJKNtHa{|9o=B*5A+0d-FD znwi+T20C=NM#yl>)$#AK=9hp6&@Zci_X?miEbFz>>sx@Q{vGeIonGUbddcl0YWuq2 zJ$}E%BG<>)xc(xQjd+STh7U*evtShSY~T{;ru6F;4q`6+3Inl?I`MjUU|5-Rak7vjjc?m`38@ zclE<3a?tVri7`Ob)303V*JlKu3LXYs((jai4Q;CJiY?l58#_gUXVb5{2p+&E&{WtJ z4wNTX3z`%? z`r{(GpJqexa}hoxh=LJ!hh11;McxCs9l8`o<}4PFugVYU72e$)|w3}4aY zckuf>7D1R^<2!s+Ki|RcyQ`4l=b`t}_?}%vD*jIS@N0)u`%x)A&_k-{^$dDQwY!Er f%GO1&Vc7ox%|VtsUkD)j00000NkvXXu0mjfTyEtL diff --git a/src/assets/images/icons/arrows.png b/src/assets/images/icons/arrows.png deleted file mode 100644 index 47a833ce7ac60dea4318cfe4659d7876fec1db7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^fanMpx^{g z7srr_TgeqaKPfVEFdwX!kd}Qsnfdf#5z8-Y{`dPD+F7cY3b=OOewUN+=Futz1o_Bvo~F!n_MR`C%BSmPI_b=T zsfSiRWLUIGO|M&{l;Pr6ZaeQ6VaG3T-pkIgUipN5^?}w6K$kFhy85}Sb4q9e0EszC As{jB1 diff --git a/src/assets/images/icons/camera-small.png b/src/assets/images/icons/camera-small.png deleted file mode 100644 index 1c0563eeb7250785f78d68eed59df0a606a43884..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^fanMpx`Y} z7srr_TggApf0*Cc*!a@E?o3ZG-y-=F6<=NmdP=O|>^%ELe!b!eGbQN-nK_*19Lp77 zNL@U-VHb;Rvx>M*Y?Bh(qr*pRn4K?tVc=YUAYcc}CdRONj{kLSnGc$nH4C&k@;-bj z&cdzJqP6J@$DjM=x!3;RTWS2ze*;i#dn0VMaPS0RS zX1J-~(KF$J&4{_+Xc+UuoWirlCoaA^TiDwDlYVQe#Ra=yn3rDO;IKro? qDYjcGKy4921FxcS->P)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00D|gL_t(Ijh&OtYQjJe$A4RVfj}_$0TOQ>^x(x85X8q22?ZZQLLVX^ zQu+!#RfIy%z4Xu?;;E&Owj>1d2-`!lYd&mK`-8BP$?Sh-XEuT&l6u5%4(WNDT7}i> zvLd8jq~~pjq7e7-6TUv6)k#-HtAjgf(`;H5p@uS|ClrxHqk@r7j?>cd$_sbHCg zBptB?bW+>2jPmHm|YT%kYl4I*Bye1B5GVE_OC M07*qoM6N<$g4q4?u>b%7 diff --git a/src/assets/images/icons/close.png b/src/assets/images/icons/close.png deleted file mode 100644 index a723b3eac2c27b2fee149515c421619c3de11fe2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1163 zcmV;61a$j}P)q-fI4Nv=jka4qIH!l_dHX@P_hjw6G%f$+P2ZmLe*F4> zp7YTM$jUH`m#CdKswW>apip$6jata4zCzU6n8{*fD1W5Zl#E1>j6A^j$ftKA!h(UI% z6|Gx5sD#F^-#|*&MgPd9%V>C^QS@!O0T=uO87P|-9ow6+`Hk063Ax6`@atdGNNGBy z&@ehiMpuGyC|NC=J$SaxiS+$NR6@_y)`~sHX8&7}*EX}khNj`+KS5Me8&n2cx9x!C z>1UuSF|V#(X->&tHSK#)H+TxpBVMIV>|O7Od5)vqP*F)>w)T$v!nW4e;5^Y=$~4sM z-493C;Y@$`9woSvNQI*2c+YAXol9hgtCAcOEDxq8>R*Skj}B2&i8xsZt^FGj`MM~(hKv5 zp9&y-Z3bll6L8B*wCEtTt5>9R?3|NBP0rP1Lsb~|Jk(GC#=-(hmD24ZL2$Y$+)m25 zfqbGDD&zPFIW-FvDS`1O{L9U9j>9UAC#RPCKY~7W1*%d46Pr<36Q7SjyL@rYacN5Q z<)MJGQ#skN4zY8|ufO6qOmXWlJ0Bk!MEdqT)+-4tMbF7-B3X3erhRXjLa{9ME;x>P z5k2z-;^AiZm{N|} z8XC~leVp36(z%3*Gn?Alv6bFRd7i42z&r;JlUp)Wj9!th_Vr+KVgfSUZfqMKRfa1W ztjTNcR4f=o(ASS8f}8rV2Y1e&lg2#t@+$;)8f68`h0k+He)w|k{5$-Ka4h#dNI7-q z{BMxqUR83gD46TTts;D@7v!9pqVPSKoRDCH^#8#;tnHKzWqP|{H*TH%N!t9+?qgV- zoG_gu;7-cUaoFd7`59#a%Q^7>ci)QdiJM`J?|akqDlAmS(GPGp3l|GcWAadE(Rn$Q zeCMB`T+*Tu+UQ)-`%aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z009h1L_t(IjkT3M4#F@Dg0Ewj&cYq}vh%RsfBvc8h3lhCX z*G@e~7-%BLb($1`r~Eiy96u*fNHas)D&`z@0ASjtcAZVRkFHwj!Z|$(Qfw zq8cMY+tePg$TM$Fik?CZ2c#O=NCE8l-vFg`ljB!awHT_k_E_tbMXzV$+S^?j^|y2b zOhvK4)A8W?=gV~hrs4rm3PkY`kgFd81D{H8LWM-)<0*bp@jJWSAB)DVc{%0E+g#Cc zt+kl@u>ycGr_?4T#YC6`hD)l*GjCDX51xs{r{T&%7QtyiJyC=n6LOsIWU_u qTz#;r;T-Air~C%9zNvskf7Bbt`jlP>L(ee)0000&H|6fVg?3oArNM~bhqvgP;j=V zi(^Q|t)r6;@-`^&xZa#3dgtK98wZ+&3m%=j+r9Ey#H9;juE{x{k`~ylwBKRr9==&z zAS+(jiDN>L)x235TrFy5tllF33tFx28CgXnYCO0lvp%}YM6R{r$sE=zzXPj8E$e2A zuhUn4KWT&ET$lIUTh!NG%6r{zrx=#}5uIDXfYrZ(Vnp9otvurQ11q dS0npYM)wnXq8m%KWP#3P@O1TaS?83{1OQ*^RXzX! diff --git a/src/assets/images/icons/house-small.png b/src/assets/images/icons/house-small.png deleted file mode 100644 index e106a4560351a8123ecbe7b17caaca61f5b76562..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 361 zcmV-v0ha!WP)pG8%ab#RCwB*l1~o7KorJ%50urP_03t*v%M6j@s zXhi2_X+HZj)0tS<40t3`I`Xwi8yqf-H27P&1ajGlb+57&h;CN(~)7YwlwK z7`EK*U@#u(gg689pf74E>>3xqRtapfSwM8YSi6T^4|)ppygC$rhGq3I$83-+XGO<6 z=;|ekjrf@8j_)ZVCggc}Bk(i*DvY(#saI1SZM?A1lDDwH<@65j> zQbLYwowon>POc|T#*;XIo^6^CFB<3;?=jU^!0~0No%4$RiJbRd+Fc1>8Z!04q0NG^ ztD3kyU(K4F6=L=L&8k9=m~$Vq886A)WQbpT{an;()(3GxH{QLPzyC4YZinwb_J*)s Q0lJI9)78&qol`;+0BV3)7XSbN diff --git a/src/assets/images/icons/like-room.png b/src/assets/images/icons/like-room.png deleted file mode 100644 index 1c13cd8512e1a04df173511aefc4ea102ebd39e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 481 zcmV<70UrK|P)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00AvYL_t(IjkT5CO~Wu0g+EtWfDuYusU4szK#(Y}Wd%Ay2VjKm&{ue9 zVFjM8A~k^#xN!d> zJRU0E-?ltI-aw@FB*U`Y1EBL^bZ?qr^%>T?^#XcQdce^ebnS+elle;4Hw^7=y|1yN%b3A$Ve9M2vP@1O7 z7=tkes0UlkmYcxQGaOHg-jrR3W`1!FM{m~d3a|ZZ?xYpO#pFVvW$ZPMP(Ey~FOM?7@|Nm#Weu@{UmVvXtBeIx*f$uN~ zGak=hkpdL-_jGX#(FpGCxlq$-qD7NjaT1_T%~FmTL#?B##fTlbVtn1;qF|I=qYp9V27CkyKddkcFn zc41~_=4R$FFflMNW0~aUu+1_=<01p=j2W|+GA`U1xoM_m$9Yx;|6QUP(z-W#fL8T+ zx;Tbd^lqK7QLsUQ$8~>RQg))}+|WCR6kkX-pS$HcM^#KtYlh37%Xb3zmg_SV@HxwO zFZ31qx#FalwUUqBqSx#kn~uJ_eMh8XPPm%ngkL8G#=G>*h QK$kIiy85}Sb4q9e03xJp%K!iX diff --git a/src/assets/images/icons/sign-exclamation.png b/src/assets/images/icons/sign-exclamation.png deleted file mode 100644 index 7db61fb02baa72a4398f188e736e56ac28e57bbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^>_9BY!3HAlZVLrcjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enu+h`SF+?LcImMyje}ELrfk!?GY5|YV{$I`0 z{y*IKN}L$;XGa!~Pxc-UtPUHs#fGOD+wA^4@!;M*(KQUqgta9!JddT_4Hu9Td6V;t zcag+HtHgU1MgQbOSfqpk8U&px7z-1*xvoF?`sTv|W#KJ#0rJ?C>)zkkAeGCfrT=5Lx^J!3# z-Bjb?V_{*C%N-$TXW6o38H>xaU)&tLEDElClYNn{1`ISV`@iy0XB4uLSEsD@VqQ1GUwi(`m||J2DFc@G%~xaxBRUbuLW!^Gqx zpAXYXj~1Upe1@#N$`0=CjT3tQKiqt-Q~BWJHP*NP?~}c)sd2P*#^MV}o> zmsOtFPqesy?ehe_$k_S+Ez^%qKd#;B6t*YwOhm^D$|XIE_Qb5c4czPMM>{dr6| z$4Yq<)35p*)0sA2f4fhaD|ox7qeyo61rzsGw~Jr6{>V+4Yn{Dv)weyW{Q1+bYx;Hy zG;Y?sYH@VgHBIYny_L!!z0VXvbx*%2&}f*x!>iia4o}kL$9yv Tl%{!lvI6;>1s;*b3=DjSL74G){)!Z!V2r1WV~9rZ+)0642NZamZ_f?zx5}R}a}uxG zCKA0+HGE&&O;-H^t)x;__b8w}44$rjF6*2UngH9-Ki2>N diff --git a/src/assets/images/icons/sign-smile.png b/src/assets/images/icons/sign-smile.png deleted file mode 100644 index 1a1721cd0ff64fb22f340ec9755104051ff93b98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)N!3HEB$FfNSDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#Xt>*L74G){)!Z!;8sr;#}JL+)CsYC2OUIO*XMOEsGaQbrs+qe z=trGLb0gTp9BgKH=3Zg53M)9Xb8aS&`p&=0if{c^XP9(icW(c$ITE|y9%GJJKg}iU z-16kON1;H5QBP$B!h8FMg>;Qe*K$hx;?5USHt&np72fx_#Nt ziE(K)N2)?DzJBrZ?VJ-&Yc7d23Z-2M`t^MK7Vq`Tw|Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0v1U`K~y+Tg_O@r z8$lGu->S41LD4`jZIq;F&RVKcZ<<_0+LKZ|RS$xaix-<)JVkFxP!QCdL;?z>l1ma1 z)F@I*>5oIy95l%>`4<}Z`!+AmW+(cA;mw=L`^@g_WQ=< zK_i(C7Gi_(gsM#9bKK`IYzwmRI(g1Xy$rDtvhSN;cWvLG**uI(@B0VCUayDBGIQT|tvq6aZ@_qEc`^k4qn-cB3`+i2meinUUVXxhrLrziwx zSNpXyhp~URX?{BFz50YKgc)b(b8vzuvl;uvfa3PH_G)J3s!Y8kY_|=h_#3%=9pvhC z(fmS)i~pSF=pu2+$LCx8kbkR_0qyk#sT2&24X{jowMH`VNn{1`ISV`@iy0XB4uLSEsD@VqQ1Gayi(`m||J=!rLWdN1T$>+Xn!JOxT3Oe9 z(^EImm@1*~Gx`rW_@-YmcNTu|nR99A72)D30c$Pvyw9<;HD*lzy#B?U$HwVQuRbi^ ztg+Abmqw#e*5kuvwP*6J=J(A%_g`LsIU`!+xx`=7zopr04MrxEdT%j diff --git a/src/assets/images/icons/small-room.png b/src/assets/images/icons/small-room.png deleted file mode 100644 index c8bbbccc0b9d5fb2912bfdbfdfc0eafb8e5482d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 413 zcmV;O0b>4%P)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z008MpL_t(Ijg^zJ4godHgW=rl|B-u##d`X==W>fbp9+6a{?}&YvgF2qsfzAOUaJVc106XSNH{t*Q diff --git a/src/assets/images/icons/user.png b/src/assets/images/icons/user.png deleted file mode 100644 index c4155a2c232767fef9552f29f6cf1e20922db787..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 881 zcmV-%1CIQOP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TiTL0%yHZsWLHH5nLnA?TH~0gBBGD2Ol@@Ea zto(eN3RI^FO0A zpHnKHjq~}unvH-=I@j^5S{E0@^|asEyrB)A=b@W<+MMt6h`?%Hxtv_zSl7P>;?LZMNOb|Caqc342zCg1{YW+;vj-aMXu{Y@tv8m5cvV@tevP6GAB|P zt-Qho66u9PK@zTxTkI}AUaW-cYLh!~v^9Ux;%YcoO` zEs_<p6k)*cALIjv2Ewx6@vqpaP;^YY~9|$?ja>e z?+Q^TI$tPiPs-2X%{CItmMntBdAu@}keHFnLz*^&K3?qUgso zlqkQ@QApwA&%1L-mE|>i=00000NkvXX Hu0mjfjA@BU diff --git a/src/assets/images/icons/zoom-less.png b/src/assets/images/icons/zoom-less.png deleted file mode 100644 index 36423da8e9e577b191089f8199b12d2aca77646e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 252 zcmeAS@N?(olHy`uVBq!ia0vp@KrF_=1|+3_iKzf7&H|6fVg?3oArNM~bhqvgP;i~6 zi(^Q|t>lCQEdMtq?0Hb1G2#9H$H)5*8+P>jD@R=1Q~5a{hw-E1qZ=lRX5FggX`Gnj zevLz{<#xjwMo(oAxtl9Ff*rV=stpZ8lsDyS%=-6#PkSS0meMV?Nq<%Jlzz;ga-n%u zy2Hf|{do_h5*U^VJ`0g(yV~fxTiOmx#(4cCFjYNER1cwE}63gmVEmEdeWQ! x?WfaB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00AdSL_t(Ijm?t3N&`U<#=i@`z`?Dt5R0$4UASezwnRo{ItOR!z1dd#A>~X)+y>}E!o^z+7r%FVD(@m zow|bVmIDB;^(k(3A1_yD*{WISQ2Ybv?fnC)~Z!5>(R-dA0R R=d1t#002ovPDHLkV1m)8!`T1; diff --git a/src/assets/images/infostand/bot_background.png b/src/assets/images/infostand/bot_background.png deleted file mode 100644 index cd460bbbf42c0d5bc4663e9d472cccb8bdcc74a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 811 zcmV+`1JwM9P)*MPiXaH_(6^RbIGMVZ>+ROHg{fEEbE!f|d9C{qz5)bDXC!ve&Qv zd2}L(ah}G=UO&EpzrI(F^E5{GyJ19NSWRp|&z7iycVk^Q48tgbaig2JdOQlojn$4= z_>nN4Cj80$8OCN9>(wL*WR(Gp09or=m4L{=PyiwYqZ^1Ej7}huFuH)q!sq}Z4Wkms zO(55rfwO^}MynDqPVICKQd&gjHZp1wshgIj4Au7HrlLNrWC;cGbs+wlz{!MuTg6Zi zUCk=D_6q5xs0I`@v8d;x#`~;V#BH9D{hO6AsOm9EO-ewp4QRwOtaF*DiL3$96-1?1 zIkKx4nS!G`jHv@ejUY=kXpQttcgouH7zN`dV{Hi&s?_8ZNP9Cs+ki$=_}8~dRMox) zNIQ(~Z33C?3Y8m?xR0)_0)(4}ukuYWTH_2gHG!-ym3>xJfhp~#H~4qhD&G?9tUK3= z_K=2A0VBI>R$<6XV03H;$iuj;Y~2KOjEa|GSWUn%SjRF)8PF(@m9BLYkd~vIT}^S> zWnkWOI8PG^XxiW>%gxKnpt~5o4J5@We0EL0@ zGLklp(VxLe%}Z35@z~1fk#42c))FIh)jcGGrLKxtnHt?Rp^Sl%ITvzz(__>G)$569 zs;`b)V83vA^396d7K_CKkbl)340;)h^B({J002ovPDHLkV1f*GbVmRH diff --git a/src/assets/images/infostand/countown-timer.png b/src/assets/images/infostand/countown-timer.png deleted file mode 100644 index ebfe62911d9265e43efe5527abe3d7fa44633f0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^DnKm5!3-qrzQ4@^QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`g#vs+T!FMD5Lj6T1qCT7DFL}WP4hvj*-C=^g8zd6!{+@<_5(#Y3p^r= z85sBugD~Uq{1qucK?hG4#}Etu2z1%?K#2uTS}h6O@RSq-aJtn1+PNn+?Q_`3Em zcSF|<&Za=uE1^f61bE6_*RX^#P8B%!Y|R=5)svi!+4Ej$0?lIZboFyt=akR{02b3g Ai2wiq diff --git a/src/assets/images/infostand/disk-creator.png b/src/assets/images/infostand/disk-creator.png deleted file mode 100644 index c4e95c9dd0e0e6ccbce503f80ff5b65d8c975dff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0y_7Ec$)kcwN$2@*OF?4{KFg3IST z`hR@$or4lb)Z9M*e;0A|f9yuC1gRyQZo-#%LRK(@{rI0^D`4(mBD_@a)tUdxr4G!9 zc-}OZ?Hb1x-jvsmBjpmp1)lnQ9H{tHZzJ8*c`0S@Gh>NnQzqUGjh{YdvS~MHwj`$5 n>7A93y1;udTbt3xl7Zot{2H_QZ`1b!-NWGN>gTe~DWM4fAVx-@ diff --git a/src/assets/images/infostand/disk-icon.png b/src/assets/images/infostand/disk-icon.png deleted file mode 100644 index 9ee4ed83d0bc6b952e9ebfad35387592209da1fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 240 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 Hu0mjfRv(4b diff --git a/src/assets/images/inventory/trading/unlocked-icon.png b/src/assets/images/inventory/trading/unlocked-icon.png deleted file mode 100644 index d6362c4524949693bed0d263b96fb4a47e816f1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 332 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 PfIn9?^wld=@e%(IBrHKV diff --git a/src/assets/images/loading/connecting_duck_01.png b/src/assets/images/loading/connecting_duck_01.png deleted file mode 100644 index e3772c8b4e3910d9c52f7865d8058c3e5c86d41c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3985 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 RxzL7}n4_)B;YvaP^}pt-O8Wo+ diff --git a/src/assets/images/loading/connecting_duck_03.png b/src/assets/images/loading/connecting_duck_03.png deleted file mode 100644 index 15a2bb9f4b69d21f1dfb005e2c0bf785f9d16617..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5842 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 Bc3=Pi diff --git a/src/assets/images/loading/connecting_duck_06.png b/src/assets/images/loading/connecting_duck_06.png deleted file mode 100644 index 0e51a51d7bceb555184e53fdc51325904a2e5edc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5290 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 diff --git a/src/assets/images/loading/progress_habbos.gif b/src/assets/images/loading/progress_habbos.gif deleted file mode 100644 index 2224994d32c823d84cadebc244e18259e884561a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11805 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 diff --git a/src/assets/images/modtool/key.gif b/src/assets/images/modtool/key.gif deleted file mode 100644 index 578ee6507d3d681dd51216bf946ddf15ef1ed575..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmV;{04e`RNk%w1VHW@w0CxZYA^8LW000F5EC2ui02crk0D=Gj0A@1)mSX_SnE>Un z75@PL|I9Q0|7HlA01F5lNN^y4g9Q^RECAqu!-D`8Dr{)LfWwCp2~xBuU_iwK5i>Tt z2=d^^kP{D7TnUn)MU)9gl6(kYK+AEak-;lKB?wNQfskAtH?&w;=E zIdvK{5}y7zHt~U&i9{549f!8llJGA{e1+aOw{Rb0*|w%_GN)egtFjw;k4tmR81B6= zkd!@WE!iXZDvS5mqnY0pUi4-=&Sa~7xX$R$F=^Sf+0tjOt-T=G-xa01O>5h}-TCEp eKi6+5V{-q(nRP&T@d}_j7(8A5T-G@yGywpMymChX diff --git a/src/assets/images/modtool/reports.png b/src/assets/images/modtool/reports.png deleted file mode 100644 index 4731fed34a3c9aec2e0a6f073737e36138b8ccac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3551 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 Z0RS~29jz9?DDnUR002ovPDHLkV1h+zz(N23 diff --git a/src/assets/images/modtool/room.gif b/src/assets/images/modtool/room.gif deleted file mode 100644 index 94e77dd9e877f93611d8dee8e36d188f8b7a0cfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169 zcmZ?wbhEHb6krfw*v!E2|NsA+H*fxD`2XRw(#1_mHFvEOcB-_;>X;SsF<=9VKUp|A z7?>DzK$0Lc7+AsrPH3K6SP^BEGfny+@7<-cEDQQlG*=ijG33^sut+*%S}A?tL0{Ts z&PLX_*I^lEyeDra&YbMZ*x0Z%_-NwhNNyk1-%W?7Iy02<&31UT?Rj!xy+N@L3xhQP D`wBV) diff --git a/src/assets/images/modtool/room.png b/src/assets/images/modtool/room.png deleted file mode 100644 index 2ce5efa4e580b5eadd99de481fa5eadc922f9a80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3102 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 P00000NkvXXu0mjf#8I%7 diff --git a/src/assets/images/mysterybox/key_overlay.png b/src/assets/images/mysterybox/key_overlay.png deleted file mode 100644 index 8f8c2a5bed7d0d06872c2e34613899589a16abcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 260 zcmV+f0sH=mP)HY@RK!QR(ACl#y%OXjCs>k(Wv|#qW8y#SP z+3V(TG=L7amF}8DGC0`4)&}$}lY41^4pxEouRDfk08InzvF;9bV2GH)L5z5uy>tg7 z;wZ-yab`(+#5jlbe7MFD@m37i%h=*{2YvRUAmA8H#BKi8^A=|o1ZNPz_!c#~2T=9Q z5pe}P*38sms))ZVYMK|!co*|Lui_SA0y~RXKQ@viNs=TH$6>u0ZYXe|37>7?3_7sPMkQgW57>A> z76qQ8Tvis%_x|tseMzjPe{GjXP}d6EY>A0~J3bz<*dSuQ%q)*}gE`}(tBc#d9SbZv z_V4WTiMNhi`mDM^>*SBhy|O%;U&XdrT=UZm{k+HKa$5TH%?1;lKNz)6v|PdQE^xc* zo};fh*Ol=kpB1;|ZB#mZ;QJ%LwJ)j~GF{d!^Qr3ERD1ZuD>IFN=Y~A(flR+V?_HU` zFmU;r=865w`rlvXV@s;l3I5)#^!WGIXEuC+bEntt*WSME+2x;q*{(~MFkCTxe@tG& zSLJ@0xi4#}>drI9_kH%PzNRnV*l*WxZ*I%I(lV~+CBN9`x)(l;Dz2M&I-@8jlH*X$ z-L)z4O?)=Kaj6+hvWs@g24t>lTPR`j>F{OsQ0>Qjv;Onxx0h=idf_ShV8!}uDe13& yJFBI-TKC!XF5-=Qaq4b^e#vu*eJ>=>e`enxD!^x~!@~v)YX(nOKbLh*2~7ZPWa%0J diff --git a/src/assets/images/mysterybox/mystery_box_key.png b/src/assets/images/mysterybox/mystery_box_key.png deleted file mode 100644 index 79b43deee659e915eed87ae86ce3c6acb712c490..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 487 zcmeAS@N?(olHy`uVBq!ia0vp^>LAR)3?z5gE@TH%jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCf`V@Ck7R(*OVbJA3wQVPWC2Wy^kk|M~Ly%LNM-96We%_wL>6)~(yRbt_Pf zb^G!6K#I2{$S?Rm5@4`>q0|PH;4JWnEM{QfI}E~%$MaXD04+E0ba4!^@bA4GIq9$h z4@*GDWW~PP|DXNJxi_v-yDWdNLN$@=(q2`?uN&2WOq%GMr}vcIY2}smvxTiyM5lLe z&hmHSUc&q0mFLf|hXWnAKJ!(UTE8)iC&6#&l=j0HD@~tOu8?{7s>-zOL*3#z2j8Wo zeW+b7v~#nRtEhAN8-o(nrpi*)mKkT?m>iUSB(#I~QEWkJ;OnD_Z898D>wg=zrQV3+ z3e#%&VPmz)pXK1OuZOE&epvNML|S$h)3*KF=IC#Hw&A+P&QnpZqt;rQoL%$$OjP{z z&98Fu?p;|EWnH|SwXjWkm9UwaReFSuoZ`HD$6i##{koHLCL_Jz7pqTxij?Ck<)+Ct ze-8yDb?M%|W5V_Qzx|Az?|u4m;#zI3PR6gkc(wSWx$*b4nuh|{y{HMecIUf3`#$x# Um)HD@1_mgDr>mdKI;Vst0L75q*8l(j diff --git a/src/assets/images/mysterytrophy/frank_mystery_trophy.png b/src/assets/images/mysterytrophy/frank_mystery_trophy.png deleted file mode 100644 index 67bfeba771e24e4245a29e41e3a2e0b6eecc5c3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1653 zcmV-*28#KKP)Px#1ZP1_K>z@;j|==^1poj5fly3TMF0Q*_Q{j~=d`eTS+ILqy_tR2x1Q;%Z-Z4j z>8fwMg;0@aIaoI%D;^o3b5q@)b39)FQ-c5`kJ|GwhN>NgbjDTusTslBNCMqgdUtn5TN_Tf^Y;<-2003l9 z{e}Pl04sD-PE-H?|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0|NsC0 z03*q#&;S4c32;bRa{vGi!vFvd!vV){sAK>D1x86kK~z{rm6nTQ+BgtJC6Hoa#u zU5sHllX38Im0zYYAuVGy1M%VFR&`2g34%fdSaO?|(}=;tRrQ(x-n$fm6E`WR=`217 zXQ!(~Z6I?lFjHnAih~m8y~J081sLU_d0e)h zu#|VoAS|kt+W7|}9v*huVnElt}Z-gB0ataItX9zr; zSp`N*L5R-96nx_BAFkiwFUP=)c#jhJewLY~0LD2Ev8N!{Tvj?m>wALeQ(CUlGA5NJ{<$6O#5W5hvz8 zKYVfb_k}<>o5bQys|pL0qbY+@;;ISm?kvH5{rv3<2!-$6x={x*h!UbKDq5+yv$D?G z*RS8d2_e|tu`e(Wv??k{4B|tkN_T^&RYTe z_~D+P9;E}INIdgeX@FqQU93K&KKcceicBuH3GWPzy=r)5dOJDczXJ68T4jiCM`*tk+Mn%h|ML! zuYX^D9{?W&7`AJ2Sf#9PESd$9Eu{c~H$V#x;K(MILt{CSW13V;4fRTnXWs;LH&tFk+9-96Fy~j|d84Oi?06n#wDcTnLJ|bQ}>h5SrWi zAp;@aMvxG>)^^Ws#Waglp%yX1tSb64Fo_uZ%_i*K`+Eyyx7%!#QL(qT?R>)C z?Zi+Xn?IXBudkcU+Z#wD{Jd%(gl;EBw>3T5_FY%o-L#T&Fan6eXm#$|_pPyRs6yj8 zFckY%;q5%+3d9;jy7{qH>Kx%AuTl2hRBB%*C ziW(g+=IsR_Q!2glSyL{<>j_f`Qd$WEg0!w7O46vW5#*14hG4J)QA+J~0$wV-D5+8) z(3Ay3ysoBlkZGNw5DCJ(P*++ck^sIc1WJA|C`115B%mRnA9T+gyRM}E3j@zWFagMa zXKGxJF9c&q24!tJD2@*Cj)!u>JmjQWF=5Q_O*W00000NkvXXu0mjfcBS(| diff --git a/src/assets/images/navigator/icons/info.png b/src/assets/images/navigator/icons/info.png deleted file mode 100644 index b32d14d9e83a5da12570c44f26073045b0c19135..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmV+b0ssDqP)bOdq`Z>$L@^!AudELF>kLDn4 zKqe-3uNm0uY~{Q_ENtJvfDb#j0H}=#a>z`{=mAYuCVk^A?hZT}jx#J>DX{nmN*tJa zhuuEQEA+@K3kJf#!d-}3k3203eA&WTWEmmAK#nvZFPbCfNqL?Mw05<1AIJd!+fZs? z)DS41x8MKlSQ<7aSsncdWC2UI0is{dgP5+7s8s$Ir}sA#glM-wukU^U00002>834t)1fP(R!E{-7;w~{&jo^R-Rzz{3rJ2ByXG>22L*CHzmhp_fH3@a9G zZxR(?3FK1wpWCL?5v21wh)HEBMjl6>z{e1un7IM7nXFK%KWsU?Vx9e h)q=!=NsSc@4CmFRq~;%T&;we<;OXk;vd$@?2>>tiJCy(c diff --git a/src/assets/images/navigator/icons/room_invisible.png b/src/assets/images/navigator/icons/room_invisible.png deleted file mode 100644 index 976fe8b41e044364f798fea9c9a06051ef084964..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmeAS@N?(olHy`uVBq!ia0vp@KrFz)1|-ie{%Q%NN<3X0Ln>}1Cmdk;zcFFYga0#) z)BhFVdQ&MBb@08jNof&c&j diff --git a/src/assets/images/navigator/icons/room_locked.png b/src/assets/images/navigator/icons/room_locked.png deleted file mode 100644 index f46843c890b3b9be1b7ee732a68437564ef44e3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 221 zcmeAS@N?(olHy`uVBq!ia0vp@KrFz)1|-ie{%Q%NI14-?iy0XB4ude`@%$AjK*4@b z7srr_TfLLIc@HRXxXj&Fyo0THM_aZ9yQnC0c+Qm=j`{6gK6C!O>kgbR#ger)XZjD0 zwgzie2H7PH^ZE+E^S$lZ^f7e)j8|`_6sLU+m548RukwB0m9}~J4xNg7JE8l2!g8?; zv6XkWOgmb`vGv-Vy-i-4%mUS{nG3!C2ux}b70gY{bFde-`p*~lVC|BBtTj7s==yjm Rt_3=c!PC{xWt~$(699PlRXhLy diff --git a/src/assets/images/navigator/icons/room_password.png b/src/assets/images/navigator/icons/room_password.png deleted file mode 100644 index 9fa392f8e0d8f8b26de41e8c21221679afd32a31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 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 diff --git a/src/assets/images/navigator/models/model_2.png b/src/assets/images/navigator/models/model_2.png deleted file mode 100644 index 921d6f1da2ad412a1663bda19e36a5e69258860d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 920 zcmV;J184k+P)33LB5+kg$VD79I|*ThV> z-%zGf2?6aZ4`v4cLQB<+UqGgn>h^J8vP>)0%N1o>ss3C+rj_dUxvpNaOiNWF0`da4 zRSC(f+*<|m8n;tBd8Iq4jm-OX%2akWJ%1wkIOUIfE;f}VVw1^=e7MKgOl67KO#>{S z?yJE4CE_rLfL!H1i8xI_UU$AvHf=1--g!5bxQ!~flgw8OC~!C3?PUISk3#o2aRy65 z-|28~@G|%K&d~W@BDXy&@BTi7?-j=G@w0uq%eqfCnJ!=M@RupK&8F6s8tb{rdxhI) zQ{!IOj=0MIyJI%p*VVIE%vFxNb2f?1!dT^~D`gXC7V0X8-A!^)_TyD9akVK6R=LJi zWW*M@RdhkSc4-c09&Q#nw;yiWtVPWt<6isK=Uy_qRNZAB0jpayvZ`usb0_KV zH0Or3RqVEj7&+g$S%h2wbnz_C+PPWyU3R$QtYu~6nC|(%HC%btDzRv~-~Fn(c-Fev z{kk2cala}qoVAQoQMmrj+ff?#D|B%h`d9hc;xz78iH{! z0|O#6YmpjpGqV<{`yO%QvlgjQH#%#P8h6oMd`!)_@?CsP&AI1><$u)V`I2YW>cuDF zvS-#>bt~iAIboN)#PyuouYbE{8v6>Z>f$2xr>eS%BIPdc*i95EzY5(%k&39mRf`mx zs%In%ZlXv@zY<;Nc#(o_Aaq?tixm8ERi-&7LPbhbHJM@$YB;81nL-b0rU#I&gZ-|f zNO@KHgvtG&Cap$YrAQ6kKdc%qC{kl0DwjWgZ$z7WVv(A27+!=*aF8R;YUzvSR&b}_XD9HX^#ixa?n}2d`0)Lla z=aUX{OrKbT@f~E&y%p;BJqmr+FHrCIHxzk=+PpVn$hB(szDh3O|95i%U*To~zQ&CQ ue3csw_&PTh@Re>P;A>rfz$cHl00RIKHG1v!+AuBv0000)cCqTEd8e;g#fq2b9gAiYRjCG!&@TmMAi>5S-Z?*(?ou4$7SA}B64&q$~-+>Bx!QgzF??G)*Ds&kYOT4 zOI7WAhKQidf73*$%(qiSXw2`!Md`_1tF_9egop)@*# TY0?d~00000NkvXXu0mjfE4CK$ diff --git a/src/assets/images/navigator/models/model_4.png b/src/assets/images/navigator/models/model_4.png deleted file mode 100644 index e3714753ad9bc5c91b18b4ac563c9048da050b32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 709 zcmV;$0y_PPP);0RR90`zJ>s z00005bW%=J|NsC00QF5LDw&a6AL>~yZEpG%W`armz{1V9M1L6AezraQx2)8HSjg3AK zZdGpEAl$m#vO%~b^4SLAj>$(GgqxNhfAo83gK(3w8GzUZ;ilx(MZyN*CghJB+hE{G z-no%2luvHo*2yimV+&=tr)f`kX2({_oGp|W&Q{6`Wou=|R?B%?FK6v*Wc1H!U-7mP zpNFmghaq=N9aU-9v|kd!Rc1-fmC3X#k_)axF1e9>9Fw&2Y|ZV`j- zWXa}cgw4p3&Q^w9pC#Rm5WCdv?p750V!;kgu`iZv@09vt+1?P{7Ylc#$i7&*A4c`X r;+;66FP85Cn%1RuAEoZH{0T4s?0s7GOWxKt00000NkvXXu0mjf9Zg#6 diff --git a/src/assets/images/navigator/models/model_5.png b/src/assets/images/navigator/models/model_5.png deleted file mode 100644 index 4036e1d3177b4b23d4adc619e04b81f88ff8282d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1730 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 P{_UrV(uGcb=B|GOej7t3 diff --git a/src/assets/images/navigator/models/model_7.png b/src/assets/images/navigator/models/model_7.png deleted file mode 100644 index 031751ed4b1a0be57d6cfb40b0c65726c79221a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2368 zcmbVOc~nzZ8V|CFkRT#rgs5o%jYyLBLK2eHh}j5KBQatD$0d*C0a20{k|1GG5M);o zI@G%3I;g0i(z+Ct21P_$1cpUKRNOj(P)A}1Da?zCGk zr4pQzrxON)!G(s1erp^ZtP=0`CUlu$6h|7DBQeG#NDpK9DkK^vhH9W#SPny~ z%PujHsmK?{isOk9*e0~;ZtNfWO%a7{eYdtNTOw~A>b z;(Hb2dLHS6Q;|{`QHbbaB9j_GQ34=HWU;6qgUMon{zN(e(rEztvM3;f%Vcrsfy9pw z3ALtI#c<`K;E%S@6OR;UH0roCT2fLHH7S6K=woRhhr_XQ(CHLZgJMY58X*%!Yw#Xt z5WxneUad2#5iQZm2t^}_Mji?E^g{?5omBdXSZny0C^Tg>6QrYoRDh<@SmS!HZ7|B= z|G4p4Z9{mn4yMUr1Cpp$qVM>UcCWU1?v$F@qLE5>d$z<0{&OzAF!(bCu=m+8Je{{{;OTa zMQ9INx1X9HJ$xD;Sc}e#9vzNbStJbxW3LSr@xx8``nq`=S^-y#;w5kB$Rp3=Wj?uO z*?Zy_YXys4Yfe6UVeQCw>gC*-?zFH?-&4F`Pgv4nob0$`PQaM8M_14VDU+L47L z?(PIo=MPsaTnQDjEkl3!xtZs}w0EjqbXi?X#Mx&nT-`JIGDin~ z!UXKAUA-M zl|buc`}aZf!oHi9>w(Se4JQ-9+gs5DEZnxdA=%Fzj~BSo)AkawCJWr8wLtfd+FAC~ zu&;i%RBtq&i#n9;fvpF&l;%Eh&*IBw%#pLBfwqA?(;2_`zn=Uxvdfg7?CCjAfc@cZ z>-}L@^CR#RsQW~hcaqyxfzeHXY=n#Zt z+|*PiRPOunUgPNEuOuh%dUJPO7~WT2 zd~Nj`0P3sm8i|YUbeBxXWpCDWybhBi?!L<3$%Lu~riEMpQrp{0?i@|O)o+p{=*+H`&S!4UW|oRy;UVdx&bQ&)+s3+@Wq*B~2RQ~Lt;5IU zyTp<8Y|E9fnOTir#9%h(L=QYR+?*kw@^dgF-+f<#?)t;4`)wQwdAlt>J!?mZ-IqD#xG{0eHSw-W1tO(lJ^<{nuP#CH)>&y+_+ddk+^YrhdjpUTM@OFcby>)erS ze4pE3e}K8f9P*E)GZ(b$vhThI+!6^dQW@QwGP))_paneA^y~J8_vS>ue3{oA|7~|m zb$`oFr0nX|zZ_C0aPT#OX2+Z=-1%X4fe=`dmzk=bLw0=Vie;>9w=c~(m6$p)Xp0TW nduIsf3TFsOwwoF>zKCq}IbIkPYYRi~`Ec z`AZZ)rx8%nIC7@kB!aa%S)m!;QJA7q7wXkK4J9rXh_Ui90t1XffYp#^wD7G0$_rjT zw)Th_6ySvlsuxgRI<-@-07Qrx1~~LcnwrUC0bDMf6~*ClS(^bilf`B*v6o9@Me#XY zK6?xB>Y-rP%$gj&QY?LC3)=}OS`;<$8H|F00(wCt9Wm!JSUeuj!@*|LFb$f;W<((? z&1eZ08x@PFKRqqaq5GrgERsgw)ym{DTh78aMq zl0(KOw;7@;H2KbotQXe}$ zWo~176YN;tc~x$2sQoZL(O>wj-u{;R&x+IvFp%Yxwy!Tr8`?eJG4Q)1)b^*7f4hBV z!g=+MJwCa2+hD+C#+2MQv0`dIeh#EBsDl^YFOC{HP*^}J`FL%#KDuzGzoW~m?e1sK zewuR~UD|1zf8KQ`E;h#Zz$d8(!Es+j214yT8N_m&^NqhU0QvbSg0gW=e??xOJJSDc zVmGvQ$tuUkCTmvk7uUhx=K>cdsM5Ll8Fgy(?1On|m19nY9@>s%W;7Iiwe{(Hq!V-E zaqGhLk@>B{8nX8qXPJz&A=Ly`Hs_KCsaLjL8VMU+m(_Ym{S9<|MPBWIJIwzq^?26( zWfea7v4HA?w;XFRQ#gMX^;A}CW$(70fQBxIcq4ur*mZD#xuJ06$63<1!JEfsX)LWV z@Nm9IcYjcKQ&`23QgYWQAMXdoZ1ghKx!ecG+fJ{Wk#L+SX|THF>$J%tq)1;v=KM&z zI`rsb3z(3+ic?c-d9=GUf#xu^<;{<<{}7ONM|(Mcpd(yzX30TsBDo$4H4n%C+%-32 zO_qc7#!uG}B7&7m4>iO@=MYkfqCjU3^*AIuTLbooE_6JLRpzS_$;*1vhh@dqCiI-s|xX+EbfrOyj@hohLMAKY23vLxZzSo|W-Yd*g44u9cK@8aD4fPrWdj z%51N+(H6+x-9YvjS6(kKIcd0Q3_tewbY+B0aq6M>JNSY2WqZ2!-jag%8e58|BMux3 zrVdFbo}2{1VcC>z{pp}x&aT4-^}~fKp5pAVZ(kQzAI1rv{AbTdy{hm_IU(`$n!EPB zD>`N_YU0u!-UyWk)(>;rM{Q?szIX4+MxBI1`A1rw%5^R2env}EdTgESFFQBKQ%rFR;K06gO z_!B*o%w^Knh+DJ46SK;Q`>B`1Gn5H>lgS$}5^M=B{vsU}Kq!PZ+DKb*;w6Y8MY1D}=H l)-!cKH+vJ8Pke&&!sX5uMikq}AA5f9Ns<)t7YSLV{|1ZhH~jzr diff --git a/src/assets/images/navigator/models/model_9.png b/src/assets/images/navigator/models/model_9.png deleted file mode 100644 index 0f36c7ca95f5e8f830927516a32e2ea0dda8f585..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1739 zcmbVNc~BE)6km=|3L#=ARD^U~f>p4R-3=rxD+wkWq6`KCq$66RALKZIf}^<6gz(^&v^1OpUkh;1$SzV@#b5TBgnd%)3Qp&ivS|<(mV{Ph`G05G+i9(9N8=~0Bf=!`nbR1o4W9)o^P9+5^G7D=V z6necDgpA8G<){+JFkCLzX!NL7qs-T2k!1c9#&ouNy%Nts6nM?+2HXE6YMk|DAE6le8Sf9f3k)EXOK{N{Ht81ra%pbx(|vU z3?3XG#tzPmGjuq5n3E6`{(FH=V{%`(F^Ii<4i$fT+j{j0C%HKJPP`T{ z#){aPO`>1^YCqrR%M!6&@{^mlKhkyU$O}HPh!r$lKBuz*h#{jS`}LNJ6=4zhz3!vK z4#ikYHu6TGGd|b6^QYc?+)kZ;I(@&e)+7QN?`p%m1fcSlhy{r?L-DAGZYBMTy#Ply zpg7v0_M4M~^JGJKdxBk1TPT+d?O8fk@TQ|MxsU+YKIeAW(li&qm992@7%PNr-l>AQgPSN z==PM@m;<=~aCpp9xZeoncL5pJw$kD8X~p{-o&ePLA&_v}D%{@>wV8l~+xFr9A?Va9 ziTTVcodfrZd(utk2I>^Y+!0sr&}BQcGmeK#f(OpNBiy$@aC=AW#~x3kr?KPBAHs!D Xdbwep;donj==V~PU!;3aYi|4-nQv%q diff --git a/src/assets/images/navigator/models/model_a.png b/src/assets/images/navigator/models/model_a.png deleted file mode 100644 index cc4a072b971ce241da3bf619ee8568962d889ad8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3279 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 diff --git a/src/assets/images/navigator/models/model_c.png b/src/assets/images/navigator/models/model_c.png deleted file mode 100644 index 2ce5efa4e580b5eadd99de481fa5eadc922f9a80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3102 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 bj_&~gM8om;uFF_m00000NkvXXu0mjfg8?4Z diff --git a/src/assets/images/navigator/models/model_e.png b/src/assets/images/navigator/models/model_e.png deleted file mode 100644 index 039b9276047bdbedc52c91bf7e655c2f9c314f75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3267 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 B2E_mX diff --git a/src/assets/images/navigator/models/model_f.png b/src/assets/images/navigator/models/model_f.png deleted file mode 100644 index 4b4fadb805a0abf03b278143dfadda55021bc102..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3294 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 diff --git a/src/assets/images/navigator/models/model_g.png b/src/assets/images/navigator/models/model_g.png deleted file mode 100644 index 26d03724ca129ef9f820b139c13c5f6b98b0c8a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3395 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 Z1^|?liOZTpSYrSH002ovPDHLkV1nu8uS5U< diff --git a/src/assets/images/navigator/models/model_k.png b/src/assets/images/navigator/models/model_k.png deleted file mode 100644 index 96fcc8b15631b3f0fa7476bdf5670a810cbbe586..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3785 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 diff --git a/src/assets/images/navigator/models/model_l.png b/src/assets/images/navigator/models/model_l.png deleted file mode 100644 index f479323b7e9ad93fc49571ad4f25efaa510c326a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3717 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 diff --git a/src/assets/images/navigator/models/model_m.png b/src/assets/images/navigator/models/model_m.png deleted file mode 100644 index d1d8dd76e6d69a7d372a1ba32abbf964516af455..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3559 zcmVKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0009LNklP)`G09AyHwi23f5@qQF`YvRZ?*3X2kCwF+qk7A?qX9kLZHYLFELvKB0QkQEKG z6f8@SRYYP40S+=3EL)Hjv6&pOsF3ISO&cDo7Z%d`q~(io3M<2I2Mc7Dg@pteV+^AU z1#!pj_6LfumTaK64_3 z=x%>FyW4^qT)&^vD zP={Rx`SN%dL_~f)y^3j2hn)wR3I?=y*lUompuNG)g@gy~6}B7D-X6WQkKEq>IimTe z$bY_^hlTsu;*ghNVHOq~vJGtZr9X#k3!80m-XU$kZr(m~NL#S0H@F?rChX!PC=O{G zcJ?7Lhs1!rdW_Q{v0x_;TKma)OxXWMA(&@d#>Lua=mj#Zo!&pcQEuPSg3jGwW`RBJ zmu8%B=}7@}SlV&IwUDT=wBv-iAW>jx#|cY8T7{(@C#(f&1(tT4uoYx0SlV$yE0DEd zX~zkzLY9K19VbMA%mqt3PKXM*7M6CLkOgusEbTZUE95oUseX%r7OdFtvn^D-)Nl41 h$x36rR&LO*0RZGa%;#)K7b5@w002ovPDHLkV1mo3mxTZT diff --git a/src/assets/images/navigator/models/model_n.png b/src/assets/images/navigator/models/model_n.png deleted file mode 100644 index 6e023a1bb12ec994049526a6324b27a4817f629e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3778 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 UH@4=RyZ`_I07*qoM6N<$g0Xn3xc~qF diff --git a/src/assets/images/navigator/models/model_p.png b/src/assets/images/navigator/models/model_p.png deleted file mode 100644 index 356601e090f91d9db5592147d17c51bdc33fb091..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3751 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 diff --git a/src/assets/images/navigator/models/model_snowwar1.png b/src/assets/images/navigator/models/model_snowwar1.png deleted file mode 100644 index 41bab59ce4ec0e52db8dd7cc3f37b3f363303228..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19090 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

Ull{GX01V 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 V;)BDmH6Z{1002ovPDHLkV1k2Pk+A>( diff --git a/src/assets/images/navigator/models/model_snowwar2.png b/src/assets/images/navigator/models/model_snowwar2.png deleted file mode 100644 index 41bab59ce4ec0e52db8dd7cc3f37b3f363303228..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19090 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

Ull{GX01V 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 V;)BDmH6Z{1002ovPDHLkV1k2Pk+A>( diff --git a/src/assets/images/navigator/models/model_t.png b/src/assets/images/navigator/models/model_t.png deleted file mode 100644 index 920255d74e150324784449c3c63b545c53beb543..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4329 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 diff --git a/src/assets/images/navigator/models/model_u.png b/src/assets/images/navigator/models/model_u.png deleted file mode 100644 index 96da1012a9bdd8b56e569ce6e950caf0787d606b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4126 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 wtH0c{y~4D+)~Os{O1f?5uUwcfi09^Gj#Q*>R diff --git a/src/assets/images/navigator/models/model_v.png b/src/assets/images/navigator/models/model_v.png deleted file mode 100644 index 6d85c22c736481ce8b4f1388a43393267e3b2016..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4416 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 diff --git a/src/assets/images/navigator/models/model_w.png b/src/assets/images/navigator/models/model_w.png deleted file mode 100644 index 7bc8024fdb59f4e39be4ee682f8421d66a7f8a14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4331 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 diff --git a/src/assets/images/navigator/models/model_x.png b/src/assets/images/navigator/models/model_x.png deleted file mode 100644 index ce0403737fe8bad143927c5f61a9d66a48ba47aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4103 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 Z1>46=DF)r|nEyKt3lm%8awCtY{|8PCT*CkW diff --git a/src/assets/images/navigator/models/model_y.png b/src/assets/images/navigator/models/model_y.png deleted file mode 100644 index 430344cb2c901ab2fabf38a56687f6dfe13f7002..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4245 zcmeHJ`8O2)_kIn7v5#H0w=E?5z8l8AHVj5m_EEBx-ip%L*GRHQmSo>Uwi>c!8A~C? zzJ^eiD9e1k|BmnHo^$VW&pqe<@I2?a=iJz97KZdRTr>axdSfF!s|yUfNGllmMXg>w zUAO>hKO_750MN4hmk^NkiW2}D%iBogwQHWf0lxP=ef{{2kw|{Od%hmG@45rBi$&lSRY@sNp6t0{K&Hs17E5eJFQdUJQ9+A})aq zB|#TQ^Nngnpdc~4Fea}5WHGqVYohIFZRosVQfs|pKc{|}3J;@8Gm=Ls;^<0s`Ir{M zd%JoTSELZ3G{SxW4y$()xPK-D0mmU48dnAJR38B3;TKvMz?)~|Wq6`VjGMZdHz2qO z2tFWL#T15P1&E+T-M0W?0Kw&Ch**O>C~z8Zby)`2B!QFY)3q-EmvfvM3;_-=1=t{Y z$$+25Jw^|Bs)LGQ+c*5zmW!7ml3#;mfI>03TsqE~e_{0dt99LPDoXMQC5K^6w zGB3%6DljhW4+4;v%yz+c|Lh@wp^89IN^E4fCAs;Lk|gNjvV6WeT<(VeU@;(M^jt!^ zo(rc=iSs@$xV!`Pyh)q);3(dsjuFuS@;0XJ_Wl0TMnC^~^VHPp%E~vBE?o!be!C~< z*v?ycyR*B0LNrc~4i`Qw35Uu#h8jYT7di(I%!+u1Urmxc#RJCK?kP< zo|317Vy1)k)JZ8qSGcQF7p_a=hU2;CbfqFpS1f9%hF9E4`YVE00gv*GO7UZm>a=;! zpy|i>*BO@EA=Va34b|y`u{aA%$3R@-FhYqij?Bnofes@mbG$JB=NML$plPzAk*rl5 zn%~BVcTe*knQHV6gO+6VJ|Gu%8r5bf`!ci+rTLYv0oh!l%oSl!Ks(|VAe)uMo|ipx z?;V$Bf>QqaNVzBDbdnabR|fx`lS;npu8dUAC*4{V3F;Krfm*=|y7C^b8rur;*4RVW z;o3kbbErO^S_vAc%kRvmV}vooSbQ@o;pY)nV49{@rY4U-b&3k6l$gE~X<_=)#pxm^ z8;voN5Sn04Vv&Xi#~{0ug_&cKa-z-8$&72?pvRcU490w{gf=8fvlWcEgi=0FyLr`7 zslJrpzuFhMlC$z@MSg{QMPSc?CdUQg|K`|wNzAJMj>)A}_^QGxrF({)j!j{f)oe*V znn^L~x^88Dqg6F3x`ajHL6+)JIJ>cFQDs5u7cNf@&!gMb-ve5hW>fhr(nsvZ1~v@8 zr++6u2&AKrVhit$!HQkV=A`1pUJB%_&M

N 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 Xk!GtIeuWX3RvA29{an^LB{Ts5AIV;W diff --git a/src/assets/images/room-widgets/stickie-widget/stickie-shakesp.png b/src/assets/images/room-widgets/stickie-widget/stickie-shakesp.png deleted file mode 100644 index d5011c74b29bd0641a0c9897c207903d63a3491c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5036 zcmc&YcQ_nQusTr^AtFlDQ=&#f^cr`ZIPFgFLO7i}L{B2oTM#|Eb4b)g^bon|<%l2% z?#?;AM3iXHFaN)P-`j6yXJ===o!Qy>cJ|viBLf{KdQN&WGBPHxuC~b~ZMnn-I?Bub z&WD2cmxLT)qN7DtGs3-k$xyj!LNv+9>Qfj_9jPy63P$=c;N|?r*Z7q(b3DolcM0W| zONA!5GK<9m`Gg%zp7da($)RA91LU_vOjTq(C)t+FFkUMkp; zs_a(KHpEi%l`@N!atk8Lf`qmumRY>>m1zpSw^RrnNqI=9u)!BW3B@o%F?9LA#jS}I zmtcc0fz1^{XR;x`iebxT7C+w_6H3i~Wa`i78!wl@2qk8dZ}g_~42ftPLJ4d(*KoPi zbQx_sodsDz+b)-w5=u;om$pz=3ngYal;ujL-C~)=a=GO~0dzjkXfg-#JsrGI2pdn+ z9ZLa@zX4-kgT~%~hmy2LQbCtNV?&K#E{Pk`!~lBnf78f#H_jei+PvbcYl$EuyV~;~ zlK1+coyo|q$APsqVNdNgb5G1?LBGD8teL>SqNfv`8D>6uFfjNyL2tPNEaj$&nOgd~ z9s_xGfV|Yy^NWjaHNm!7@5p)G6#}=a?4q?&A&2ThUZ1>u{rUDf3~bk~w}&%LW3NqX zfBJ@isRl^f2?g(p^(Rc3Lu$g_UJlIvcb)$~QTQaG3Kdz+g#y20a`#vZT6+Sl^xqX2=7{{8Jtqb0$B8X=Q20d`_p9TAL8Zjtfy3F(Pj-U5 z&-2}F?@wdl(qp;~meznGWO^F&Iwb}k{BG;cQ-aKfCcG}Xv^n`CYGT(mMzKxbkHd|t z&5rlv_nMu@EJEp{8VT_RFva9fVJ@OQi3TyTlKy7m6pO!bIt2NBb#NIv?oIy@NcZap zYm;@)x1Ak$6jR+p%%KVqe}B)GyHmxt>7Ng1;>~#(aplbSERWOoC0MfAdVbFl#{#TF zuj;diDU8&uM&~G6ENm+b7jJhPZb8BQ5nT`Fa;qDy%CIvpoEW)d&HkZlKAch zG16Cibkn#P-k1vT%jTaAvi*Fe=cPg4U;P=xdR^m+noB(X=-0LIjcu~5^4hK?ukwB^ zVk^(k=YO79n>tmYAQX}$mT|7#*Db7Jk5tI`DGpV7&E4b2xtlBp5gy^!MpYJ`uipOQ z7AnbnKwC5J^h*jPIGj9To&TOuHO;8=_OehaZ7#=R`*n0*3R%UR zY%_dI+i$`{giiJoPeVv3N$lYTnKhjyliE&Lj$5?eU{89W>*8j&%KMJ19%2!1Cq2%| zS>Oc}iiz*x-#;)~iwLtnU;KIhZM9#1VyVKnk3kv94b>asazWA?_aAK3okb6EJ)}0L zc&*6&Whwx^e!$!v|Nb6fpsvx1UmE=B7Ml}PD?pE~)-(P(RxUJs7O!B?8_m*0Sc$$% zHC{U5`;)dogUKdet%la4*>hT>WiPK2uinjzSvWikM35D_h!ccTt@B{Bd^A9ol~z4! zk=)xx2-)OnIOpI!N{Oj;zWGfb!E0(>Pl$osW4KL^w15nYb!%;{Twk;B z?Z%02VQxbI(xP{~Zf@PHjfQPa-8kY{+1$s@bOGpd`!soDlA$_IIxbEIXT5(okLd_X z#lq#bH7pr|spfKekQ3|I^aWPNVK@3s;zyWm;-&K*W`x73G`0p=CP5<4q^0v-bNf6a zi2iPkDl4ea`1MdN#!^=1?Fiu5Mt+IQk?t$WZ!|tl=Dh0$iz;Hy9ry(JMhJnX%iyWl{k0^f=nq`eOMaB!t@p#k_nm z*xg>tJPta(LWnh-lI!|T$_f6e$3o(F~mNM z&eoFwZHx6~K4tI{{FQ2H3s0iTFRak08P^aLbhNdh=T;iw?&i#nhU+-x``Sb!{qqZi zV`4^yZc>a=*X%jfqnFU#vql8lTkWyEeJXT6=FLcc3xgfz`L?Uy7h^{o8T@GcW!PI? zX#Pe&>kdX?-2mDrJ3>mxA^&@znLoH`ox~6Y?`+CYjl_oMDX4KphqjtU-Mn?Vz3Y7y z2t|`Fei4yc-!+X|nwOqlbSx>7JURj(_Y2^u*wy4LJJ$3bZ&svyf)Lc5iC0Y%%9n7h zhZNU@K}5R^Ht+b!?A_?AB{sHvlPiu-e*{Mw^Q&?}O1-SG@Gq=9_;vP(zDQ-e&ah+u z;IO|X+l?;%NJ{%DLc4M33qKAfigoeOcRySu4She5x9E`e10&inpEu*hoiQzoc^^(L zZoW%a6ONO#qYfQlKk8HoKl}Sf<{aQ@Xem*f60)J;81S-k%8@BpxrTQsGKYu z^4S0Nfp-aA|7eRrn%zCkz$?qm<~@(XGp6{V3RS7%>(FG1W6W~3cuCIb@Ufy;Y7+KE ztdtx@9_fH6_UWCF@Zc2AtzQ3XI=f!foz3Mxd$Oj{C->@KW~aH|W<)}`gGINW74r@n zr=4!#UYI=Ek#{rK&kqK|0v^gkhGm<*+)!_XM+>F5wuEaH(LQO&U_`nYi3xktTYQlD zEKWW{o-%_!)^G1JD9F9-W&;hi`*%`hz&)!rusG^QXo-J76gt!WeDCy=wuJpbO|XA1 zpieAlury90GgQ(n{e2r=fRD?~mB6IaO`c>Xf7p-15pbTup#0KC40n960W)KXFt(n< zf-01y-&w-ttBkLH2dZCY-T-)mOUu3klQFuoT7`scXOg!~h z;=;Nfj3gVyG1)k#Rq-G(KZKQP-(aRVZ|_bxD|QPfXY%#l{oX}4Y~xeA$#l-Ivs(9R zZ|3FvYvd0Pf?#T4M=Mzi+KP=OR_sLvgKb5bn5=vJZLi_en5`q+)8IzkO!-HQWw%~5 zEWr2kvI~vXmxqB;G&|Rc$x;9AzAW>`YQ;hZcer)**e-P&Y$Keg zD1OOQ%Z|0QzYl#XSZcABD?Q$iqkhKPRr(DX^oY?C#7y1g$+q8Qt+$?OAH-;bdH zSG#`)vAv1$zRozI`yj-jid;Prx9i`s6|A^4HPtTw$*R=fz9p%muan%f#M<@vCWTxY z!TnV`)!ym`JwYk07f$z2p6%$yAGMwomVjnV7mfd5&UNk%<%Q z1Xwep9=|M;qUwG9B1>y`3`{&kiTp31!!iv4ju=@sUeNAXpK$h*U@6l=Z!h*;i&&Pv z;S$>x6UuKjsX~rN{caE=ZuCVZTq|hP{FOZwMh&@FI@28};kyMKR zm;UVAQqp$AHL`l5K#=CbUIn1lQWG*RPcee;NwhwYatjNUm+y$2FZ><4V}z_w#4x1^p`-(hD7J`ETt_KaJt_kiq7<^y(mvRtaz{S@^@)B(@etaCVqqWN3oU z%8GyHKo{%vrO(R>zya>`f7Z804Gd~fzd5=AI{S>_)G6C6wrURxuX?+^>f{z$g$M}O z4dlsxYUGGFr;)k}9Ka*FQ+luPul@J_3qLQn<4=2fmN6I%tOjz|(s?nGPUg;M*DSt? z=$E`_iHxRRqoC`sDIn!<>67YQ+alJ>Kv#x9`wQe+h6vx-7p}n zm#4GhlaIV%_Rj}Xd}Xf*JO#xWPa*)c2irTx6)}e?K8}Gin|k^NGGD-n>VFPb1cUb? z?YLVKCMnwwV~|Q%*bUs$J<21BFO`CyIjeFOa%%h46JmN} zq+dz8s81w1K$*nW13H`U`KBUv`PA^=%?;j6ouw2F)u{6fWDz{7hqA(@PAm?5&n%C9 z&zijR%!;UC_R{-6>X_OtAw@JVFR%Lh%rkqJ!G*h62mq*>64r^zd|_Q?%cC9{aVq*X z=1|L~hU2cls;EIKmW{K%^6nT`1=@Jd;02JIEC5ex{Gw!au3)G74*1T(Srq4u4Djms z$^PBGOY{87^wHn_<4v8q&uz^aY~Z20LaS>}n5j^37%ahP_(xTfUeh~QR6VsPclBHp z2%^eY7H^xAd)n(DW(q!RlRWMC<8N;eNlkk!7#a5TbpOawCF1mSsi)^;6?sm7?58B6 z{Je(Rsh3ZwvPg987TB+gX5(3b#ryd8p3L=8O!Mzxo*AKfoxnegbPwFkNLky~=b&V# z5nlCO!xY?76f^Hasn6G`>P80SX5-A6DnF882}B9`bf>NlrRT|7i-rkCdtcueHNi4^ z%s(?KG3`$_kSNuo=ZhJ3%<1i=JzCzJ-H`gWzu_6E)|UHd|5-MQGdm<@O(6m@vCIS| zTpcX4Epo~p@4KJinY|`#$}~Lp)gv16arjS&z5WID)xB#D=MvH<_}LU6UbO)$rSO1= zKtI2Ldxeyz=LPOFlREll;#3aS3N9Oz@UM&?BoVZV`Tnp%y)5_nsw595J$&S@-hR+t it&Rsl|MSJUkB0gEYKt2Jtd~DEWMH6yc8!+9i~j*J;rwR+ diff --git a/src/assets/images/room-widgets/stickie-widget/stickie-spritesheet.png b/src/assets/images/room-widgets/stickie-widget/stickie-spritesheet.png deleted file mode 100644 index 02495714fc62ad63e0da7c100dc969321abdc86e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5828 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 J);T3K0RV@$%B27R diff --git a/src/assets/images/room-widgets/thumbnail-widget/thumbnail-camera-spritesheet.png b/src/assets/images/room-widgets/thumbnail-widget/thumbnail-camera-spritesheet.png deleted file mode 100644 index 63a9397f20e4cedf864e6111ce0bd850044caaba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 883 zcmeAS@N?(olHy`uVBq!ia0vp^EkJyLgAGU??LB=LNO2Z;L>4nJa0`Jj~)z5CGjwu3~&!|3L`3*X{5dqp$~ewyAF_-w~YBi2$S9>0Q1Y`rw`FhJ+3mYt`#1Emm*(1S@9pcB?R#5R{pLp@-=hDgOXk1s zF74j^tIa^KiD6+aN3wyNDJTIkwikl7b4s3}RGN0Ly|*?NH;J z5VMm>kiq5OBhd~v$0sw_IfU>iiSJ@!be^lx5W(im#?+=2=)yj6Aw!Z@*K+RbY5_9@ zE(@5nD;ag{G`!Qr+~FWG&!^*?noA~+WQT=>Pe+$SiblhZ>n$tzS~(e;IT=|6zT5mv zaWXMbJhaF_F~LAl?9P%Lr!AjndkG(EnNhp>&$3G`E55%xRM}B9`>Bn~;pd7)B0OqG zYBc7oEP1u-Z1XmU0}L(VuNfXbt#PP0s4sAji-99wim7G0D98gG5Z`Rr;lRMiB7h*6 zoVc4$i0xeW{}ww!6*MG4T3~ALuqEX$T%DQkbRxLz9seR1vkxV<--_3+4!$1s?8??x zxnTnBeDw=ny}fmhiSbB@K){yHL?Mo?l8`8Y*o|Z=G_oRO6tD$0)U9CkAlEWE{bylh z<&l^8^;?sH@rb|?PA-E-4i@#RB<__y73SJ{|KxsYKE88#M<@TX-Vm`yKp@VZw{7BY jW7X{{T$ef9oa-6y>7~B8=s#DM0SG)@{an^LB{Ts5nJ6~q diff --git a/src/assets/images/room-widgets/trophy-widget/trophy-spritesheet.png b/src/assets/images/room-widgets/trophy-widget/trophy-spritesheet.png deleted file mode 100644 index f9184cb57814534a20d5d669d292764fd173ff1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6595 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 diff --git a/src/assets/images/room-widgets/wordquiz-widget/thumbs-down-small.png b/src/assets/images/room-widgets/wordquiz-widget/thumbs-down-small.png deleted file mode 100644 index 78e51cfe5666ccc5fe46dcd7976f615d19eab56b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4f5uPrNAr-gYPIcsBP~c$s?*H$9 zZdkj6i$Tur7G^ow5`Hd;Ee-EoTf{t%3P-w%zGj`@S-x*>Vfq>2*}a+NP7@R&Lzig! sFNyP+%$9WF=#@-=yCb|#^S2#h&~MqhAozyaL!ccDp00i_>zopr00L$)8~^|S diff --git a/src/assets/images/room-widgets/wordquiz-widget/thumbs-down.png b/src/assets/images/room-widgets/wordquiz-widget/thumbs-down.png deleted file mode 100644 index fd320c51d72f0debe17f9537d132ec4de35bf815..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^@<6P_!3HFkdog(dsaj7L$B>F!Z?9bBYf#{5O}y9n zz20n9x0&0EGbb0S{y*j`US~PiMJ+NW|82kxr`Fv+B;%QntL{+KYvB5RZqC;?8;co3 zcluQ5JW=caG8r!IE7jJKC2Yu=J)QJ hqVly?g7yYi8Nao2ZhvIZ@C@h>22WQ%mvv4FO#s~;NumG% diff --git a/src/assets/images/room-widgets/wordquiz-widget/thumbs-up-small.png b/src/assets/images/room-widgets/wordquiz-widget/thumbs-up-small.png deleted file mode 100644 index b93111f0cc078bd21ac90ce83f59ce4663474d53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4fex5FlAr-fh6BLC0v@@|~G0&3r zDLwo$$zUt5x!UOu|5KP|N%~wU@Zvp|-f74ad^KU#&Wab3Hd4o&EqXL{^;hH>T$#?2 iEs<F!Z>KwQF(~pde^&qh zf7`pzl&z;$ a8+P{toZC}5t{w$CfWgz%&t;ucLK6V707rlT diff --git a/src/assets/images/room-widgets/youtube-widget/next.png b/src/assets/images/room-widgets/youtube-widget/next.png deleted file mode 100644 index a02e164ba6f2f67e15c80ea935f447722be8e217..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^qChOb!3HFM-ZD`IQrVs^jv*Ddk`odVe)P9VUbvCc z_`iEzMWf-Sg&u$YhnR}^{;?0`RXtv?h*$M!!6aVQV+EUdkEUB3ZA&u#Q~x-Q*}%aqjdAIwIv2^hiBLBl4!m^o1g#8dvmwF_@^$Zh9E?xd~`3 NgQu&X%Q~loCIF11JCFbX diff --git a/src/assets/images/room-widgets/youtube-widget/prev.png b/src/assets/images/room-widgets/youtube-widget/prev.png deleted file mode 100644 index d48b658ebae5457b7933bdda12413135564ea62d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^qChOb!3HFM-ZD`IQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$AjK*2sw7sn6_|FxG+^EN1mxCCxcsxC+mJ{I=o zu$;~zy9thM0!}BY58VC0IZxu~tbZ{wi3M^|k5+It?7sIm{^*8h^VobNIH!3A7#@pS zA(d>pMLOBis>g7_WrJz&Zd9(92$8+rtSC_VM%xNb!1@J*w6hZk(Ggg$;Z>hF{Fa=?cG?vR{;`k54Tx~uagj% z+*oj4WrnbL&#_zmH@sf>-zjvopY&B_o{aXZQ*IwkXGMhb-}2kKZri%o&;B{t?n(K( z!`=Cfu2Evbd$C&~`3vS*A3d8EELgVt?u)2$tI6AKW%z=p-#$5c3Dff$7rs{i7*) z(^u-xwDSwd*H^miK?%cKQn)ADNQh3MrzspnW_Qr*C_kQ1f|GoQl z<)V^fwHhD4+&}PQ_ui@7zU*FlJ#+VuW&3wub~|Q&`0qv8XV=fyU;lmPr)Xhem;A>w h8ZY$9be&_~OCMAT6X`lCRS8UI44$rjF6*2UngEKP)aP};9wU8$gdB;^Uld4*mQ#>+Vq zgulpuN+};5<2aHb^a+7A^l9q4j)vo*G{M`pQEJZfyv}7=Qrotw*}Ck(B1nl4f|g~` zw`4JYyE->bL$R@~l7j!t6??(4v><4--A#@Z;QyfuGef+gRONKh9FdduRfGFUZ@Fv3YWL*BGlmvJr1?K TLp@I}00000NkvXXu0mjfrPG%b diff --git a/src/assets/images/toolbar/arrow.png b/src/assets/images/toolbar/arrow.png deleted file mode 100644 index bf04ea0ecf9d491eb96f2433e37502b673bf7856..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14533 zcmeI3O>g5w7{>=8(2~_kNE}#kvbQb&=}X{B(K5ZxEae*B8iUc@@iaA+G}q~O)nsl zUepy^)hg0*t*Gf*rK-Ipl~k>a)iTz~idHhznxW}ZcF2tai_F038QZN}SvmHrE+0ja zZ(uwcjf$gk(F+c-R;$&pTEeB0!W2q);zrh3al;#FlJh(*650XvBkH+QoY(4l!>BIH zaiRRk?rY%Zh1@V>$0*{l=&OQDx=qFusY)txOK-?%~K5eegKk_0kJn|Nl z%r7r2%*LeM&TG%@?_e;ubQrDOVF)s$bDd%5#3y*0gx)Z)$=V%uD>vrdeMEbc!I{bw zUs>39GNub`@s-q;OoeoWOm?qEGay#v1s%`pH_}g==))ZA&wB=4oH7Zr3Qhrlqb5aFKQsqpJw&&2^$($T|+0ZL62T;!DU`xlb zBI`e8fm)Eqv5lS=46LX@2i76MzI$lmNh46^6Uu0MeJ^0$B8{?%=QRUYGRce$H;gRT zCL65=Yba9c7|TQ}b$d%?#qMeqrPQscilugYO4+eVx2jhvRozY?w%gEtA$7~Mhw(zm zQaewW8rUzS{ve=ile79j6Zif}OUy}gq0~AJ+0;A%Q!&U+B|hJMyg{ zB=KUa%jc^t-@o$hDfT3b*0Ah&BWu|4S|E;zr&=f7%AJ{w{@(#i^8@?h8lxlPUbdjp zREcVFlF;i#BP$@Qhip!8mU)_R+A*8i#POcrr_*DQwoVVt`DDE~lxDn@8EhJ`E?EhF z&BPblCY4kDUOb%rVWM9ysqDa7{GD0hF>2DTe@L9A(t}CZ2Mf_{=`>>KG2@|(t!eh;mJ6rt?U7T zJ)7YC;beM<^A+%vgUJm&<-{e z3)0}m0v8t%6bM|91~(SCxQL)Y;DR)`vB1Se1O);Yq`{2^E-oS{5V#->ZY*$d5kY~# z1!-_&fs2a>3Ir}lgBuH6TtrYHa6uZ}Sm5F!f&zgH(%{Ad7Z(u}2wac`Hx{_Kh@e2= zf;70Xz{N!b1p*hO!HoqjE+QxpxF8K~EO2oVL4m*pX>enKi;D;f1TIK}8w*@qL{K1b zK^ojx;Nl{J0)Y$C;KrBYDokGYBQAT#Z^T~a`{~z*E9^x;$zI=XBXoKbq0c@?=-)GT z{sW<*iqM}22pL}^^s;yVu(JRF diff --git a/src/assets/images/toolbar/friend-search.png b/src/assets/images/toolbar/friend-search.png deleted file mode 100644 index 7156c4fd2ef8a18ba27ed00b62cd7aaa474a74cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2213 zcmcImc~I0=9A4LBRK#i(wMaF_qgu@-+3XqJ3bG2Qs}v}%N|kK#7E*RM>n6Ahb*G+F zozV`8rJ!hS6&ZC<8MSpp>s3#%*4v7$SQVsr;a#b=FR*N#jyn9)%)I2iyzhO#?|0-k zSrk7ZCbVOCM}3Gd+$*PdOF`4&a0^5eg%Nrrha*B#7z4Yy1dq2fcCA(H_7^f+tB3 z9LS}b&&OOzNF3*yWs6pB*uJVzUV(EzlR4b$okET%DXBxVGx2D2IL zjD{h!M!?t`b;0vyfz6ZyD4%aCTuxviM=(aTR?9FHY0zVofiq$h(AY5p!4eqYILHSy zECck-Y!f{^{B{_}%dE004l?RAq+P?>IZRJd9HwD`0W$zQz!iiLPwzp$I^De z<78l^@J=QT;BHqMiu|i4T5t#+i@?E{Q*u2+cIZVcFT&(y1-_6(Fe5N?@JM6X(F`kB zy9s6GGy@I|yyjmKy_V^0qV=W&Ncx84H^D@~E_oRbh)RQzZb5nBuahq_Gv6$}WvTyP z#Ro#mrZcWI0NW>y%I@HDqiISE{@$O~};b+D{kv8-BRUkoHfPsuPNw zIZGxUpHyDXZi??$sXe^;){-atrxY%1(=B7=s^bx}t53#G7j_@jFN?JI!S>~knU*@> zd?#z^wDld1{=V*zyB>?qt`1#Zdi7Gwz(?m66&*F4D2&YPa!{KbQ+L1YOy#rIYyF+C z-F;yC?$^II+{LSMucF(c*5_ZI5_e{XvRhTe-^Xs|ZAz;?nnRThKUlPskDg7{-LNW$ z<`hs5?mZq_G%j`Imhy<_fR4$j_$?)ox-xgFzyBV}H+`S!=G0nM1^7PE-zTrokUVE^ zkLp$S6YtNibm$^>UGBUd;edE0&t_Oi$AF@fNb{#;lsD zLfGZbz0a?$y?A_0L3qh4=emWCryOCLFKn)7DZMHOjH=eP;>lAXOL7aItTql> zc%|6i$3(Avai|1rOAW8=_)Be%@XiNaI)}B&b?D-y0XnVsR&Q=g!Tgo6`uWFB$J7|+ z+`mNO&!){<({snXb=n)Mfm@!;W5aSjTxz?Q5cy}xu)bu>Th@0=Lsyj#zbidHy|W>6 zrcKzs{lVA5H%IEb>@K;}?ns+1ZHiZ8_2^6hk%awm5 N;zmy}ZyuF8_aErWD;59% diff --git a/src/assets/images/toolbar/icons/buildersclub.png b/src/assets/images/toolbar/icons/buildersclub.png deleted file mode 100644 index bbf6d681267e9fe2ed4a125dbd558233cbb6ea22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 576 zcmV-G0>Ax%@?n(5=LnY#13`g3nb&svJ90Mhib-p|3+@iB2bdBI#Yh7eB zhCr49CrX8?M93A;>6aO(NdSaCUhP;*6FXuCJbP;}PX>LHqBV-u%Rn{&(yt|S@O8*G zK&iO)UIr|QB3MCdPeV4al>ymGIS=~vcoFws?{|g?RN?8fPA^AOdf1=P$#f$GOGuGs z0SS`F^1YzJ2o^xJiezvtp`Qo~YzefAm~d;>C2&cgBGS2Vx%M@%Cm;(`iX;NodIOHm z+)2Z%^BR70yhZeRUKB_qEI8k+L7tcvVEF0YdXfoOK*N#xR)NdIE`%k(F~6Rb1;Sgc z|Ez*givYm%JPX15fHRa^ge9r065-&GAw~OLk0HWdTGoh z2px^@Jt?45EunD?1()}sza>!o`QV!^u$(c%gKH5_!2Ux1xD8=tfUh$Ym5xI5z@dLX z-d{dg$rF*8@&p_(4gO8@L>Mm9zf5pdL}p@4a9c)J04|EG66`(3&D#%5=lPeguvU5i O0000cL_!rjfMv5GDI^;=3j{=qIO<@b zD2K{nhk{TM0g-y3cq^AsWDsH*uBuEGp&W`@!O{(a?Q|TcJG1-V`{(=q|ND5@-o*8j3~JnIH(#87w-BMI{haZK4{7bX2w0VZnnC z(ZZNggDX)rVDJb

en;g;4r71(il3dFNQIoi7woGP(}Z(3vy_U8OSQHHX&X!N@-{ z-iy|TBx(?PFrr1{Fqr6v++l%C)b7K93_wB+Ux>nSDnyNog`O0`LX#KA3mKBMK|>KU;SP%5kq9yzMEd+@NWJQH8J!U zG2P^^f}RkUhA9^MhUj`)!+g~b8B2dQdTF$?@gtLAyB9qPBiy)t*-!c_C3??WV^|5 z-!RIuBCGTj<{Yc#V*?R8Y?hn#)Xk7?k{rkrmf7CL#?odZFwLT4z;3pL7Pv&3w(GW@ zYTUi;;(o^XM51%x)&B1~6`u_3DYrxJq562T{51DbQ?t|VyRx;h@b&Rmpnaxq@^;%) z&@>>mWbmp-%o{pU}99tZc?!M*#+{99Hg zQqcYP(d+HG3Z%NWE8M4B>@!(Os<@n@xUKZ>uutK&^wl45*=w<+iFE?JHYKzU5LZCs zUL`lm?K4jGG$gm$8QEq$gcA#<@|q|O^{2@F!G}rJHQsTfZyrBrrc|eGXzCEfX4Bfc z4=^X2PL`fmEOM#oS@E<>oIVkns<#%@WS|iYb$I9eJ-pD$ch2u{3>sxm;_~nm?Aq;hPjTT@?T72&Gv$a0< z_lG>bJ_p>9Gjh9={ZT>n)Nr=ct?_7{ahBffU}@!8C+_U#;&MV-CF>m9@>z;tOG{jP z?UV2UO~!*C#s!HzoW{bDnc9xp{((Nr%o)IDI#+qVWoPx^VB`hWRE=d${%&4;$;*H| zlY@s4#8y) V;qoj=JZAW>i2VYERjVUY{|16+xRn3^ diff --git a/src/assets/images/toolbar/icons/catalog.png b/src/assets/images/toolbar/icons/catalog.png deleted file mode 100644 index f68092171113671bf64cb13c059b92f59809f644..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1202 zcmV;j1Wo&iP)2}$f`ONoy-^^?s=V*T*<5>JL%*XrZIsP{o1ALM& z%QsGA48y1Vp?Zgc8Z!C>vpmxU#%fcn`cSO+mWoh!1du-jyRHL40`CPw(0t^8pXd$B zfEmHG4ELIUerDP&La7!qT&WrgC~ z1rI!#N(L$jh;wT@LN%%0**7~K$AHiGM|Cyz149EBG1Bh5ZpTpQuTv*aT2Q14f%p>+ z2c?m|cZ4F(P(=|GsnrEaD--pO8Pl!@meK2uh9NIC3Ia5k6wyhDR(ZEKH3%cCH1VL^ zF?offAO?#95)d>d*wh51o>g#U{$7>{S>B=U*sBEKp@GdbX%(o$L?G%lm1z+`JNY_=9f3sU+jdTpx2%SbKk5v&@rmsI1iv5O36ZXaCc zjl@B?Wcu(mwmCUQ`pyDXyltsDVB%OhVzFy`bHIv zVQ6??&cf8)9AsXuKxB;GpwhIj84#j!Jf5`|RnCtX7~7?d3f|aSfX(fv0_t8KvM&cy zN_eX#2B(=N?_{m5rC7D$=$e41jWj8kt*_7cx`I$iRBC2^p>Iz`)DpAFA{foGvYIoL zD>Aqzw;}pY_X%VjgFZLpCk3^o^v%9r9VmUqnJLibyp1!YPAhA9s2XtO8>N~Fu@wPI z-p#_y<0mk?QXV*c43#pxHT$}Zu?AC^N*Y9knF@kh|B&N!eW}Uka1t~bQd?D?uz)}K z5t;TuQsd#PGTcJ7$P?Fa5Qf76%~U8*Qu4j@5T#vJoIZ8fMM;5|;0dq5d;g3ggrSF$%|3ohk~ z10tsONwE*@w;VKjZP#leYnk zT}`#?5PFS`Z=&rUg2krR!n=TDzz(r(2p6s-V^b=wpB5R6;yC?8*>Ph30PFMYiDeL! Q7ytkO07*qoM6N<$g2VwgQ2+n{ diff --git a/src/assets/images/toolbar/icons/friend_all.png b/src/assets/images/toolbar/icons/friend_all.png deleted file mode 100644 index b2ca0d7d52b32aa4b6923f119618a8876862790a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 648 zcmV;30(bq1P)>-IhnZOAUGHo7Y7z0Vq%<~92^J(Mkn3W#rOhZVt55t zU!!^oUpe>mw3izYZ}O!rJ?;1FX?riZ+}}TjY37eP+FCTvC+oKS4+wKrDOz(XX9?ia zzPUW-lm);uoJ@wt3(^7*nh;v&Vn-vnF|OzA(_H} zuavJGfbO@l58(!q0fMCfp`{&TkO|aPh&}&6dK1EoL!qy??F)Sp0&U8ci_tQ0bFh|> zoRI3brGYd6^kEDK!4)*0Z7c0So5oJTgWw=A&>&#iNu`P(51!0!ddEMWFO8GE201z;-d&*3C+m3m;Q#0Vq-yRZ~u$7D2wSx#{KtfR4 zGY7yB!dp3+hX6Q)ROfU)dKw3BlX2}q(iinqT@(<}fa z`W+Ke3Binu_ai7Qz7N1jtkXhHBRG=A*r08r8i1r__D{tAij4=5M`80BBB9 iZ)i?s^lLan+2;pJ`lO2}U};GJ0000>NW%u_|*qM`#)a%v>4T-9 z9*7qC^8zEWXh7D>Gyz$hv=}bFX2_Cx1u|C6LQ9<& zCC0K)@G4`B3GBsim91k#TC1VvWQJ>R{cycKhBi!}`uPk#8qPBtWQxfxNgB^1m;k4E zCZk*KI59_toY}cB+_Pdu2ykLOpG%+ui8(V5Z@(;E1pB$yQ*`xsjUb7=xu^Qwg4_Cf z^-kbj1}{M$s_w!(?RMDbuH?kA3j97Z51KVoKy9;PICQxk3MZ$=5%khc!JZ3yl)V_Q ztT(O8vBsB~t-9{A3aCUjpD;H&8?r}f@rTM_78s1D$^fpHbvQT~n+#lJW{F^k0b7aS zFh}+%d+O29)0$!;wC15~y+v?4Y*>%Rb6W<@)YLkl;haAzQ_sUR!&X7#DCVZmg|SV- zWo{FY7HeThv>@NeyepYs)kt0Gb1wm`e|Br$ELe@LLUy{jhQq^dHf&hnZpGNzBvxzA z+Ap)$Ox#T*^lq|$dbPsWo@vp?>;t{19VD%hJ4?Rt^$8i}QuJjhKz>`6O)r(v1GbLX zhK0*R>GVyk6?;=lJOB9>dKmWq0k#Ps2u?jK@!Q|sqkMY^@1F**tn~|YTxGIbpA&-s O0000W6W0H-@A^~*- z3FB3*o?@xAv|`mcY|BX?ou>H+k`zYf>uJ6A6(vrYg_wa_O$Z%kD^MedD#c;N@HGU@TTPUbmSq0G$(pVl~p?X`<2KStlaz(WcFh1SSUg# zGZ}EN$69VPxrS!IQNl!+2@7opKJlbJYZ*mT_A+XUlHTqq3xhe)YQ4259k1CuX=yv1 zu?`^cAf41{&#$x+XdYpw%56B2u@2ly)MR&0lg6>h8JCIanR4uegPg*~^tf%VrQn_+ z6}VSrx{bhS%9c-2CbfH&=|&Oq($jg13rLHBs<6kXP+#@fRF5ShG#E{&!BSKRL^6R` zo-YxDb*Pj{<3wOhil8KJrB4nmWgv}}6LLtD(nO_H2Iqj3zB$0wF<>NeaCdvkeMW_>0=w!{1%eBaqSr$8uS#TmtqXrE^ zk~Dz(B&5b990R-ChzSTxDiUBukz9}@Ps9|2RF)_wa2G_a7Pe1Ft)cL8W}|pg8-8YL z$UY(U3L6OyIm`rUn9={-5|gBvP%4wOgQZysEm^Q|UB}o;V(s|W(GC;oI*zQE%}y|z zEtx;M+q~zO_jqDFu1%}NaONOW)5coPLGZJe<#qLAF@wfqoRzkJZnR_ zQ@K=AC$UpTx&pHisij~|uxxX8!toB@%qo;Q^G)RVIdHd*pPJFdI&msh%u%KU%K!`s zbKw`O&blD&K27Y@em=od~5r{jviG+1K}7b_xIz~O>vu*MuN zRz$FX!v)h|jX7Mbh+qMS3#P#ubGTR$!2%8!OoKJ%aIqqS1spDz25ZdWVnqZCI9xCd z)|kV^iU<~PxL_KrF^7v45iH=XafWrmTV2wFktcYL% zhYO~`8gsZ<5y1iu7fgdS=5Vnhf(0Bdmc<$YJu zuX`@y(a6>M%bU_h>N~b9LQ`J)jj6jc3U_W8{PF8M(auE+=Ks4aI51L&Zm4N%s#|u; zzsnX7R#$)EbWF?QrGD{eF9uwEqxIulQh)A3+tI@{vZVoO+fsW%oprCx?c4JAN6lDc z%(0`fhJPFs=SKy%`5){_oMSprQ~KK_5iNf%UGTz}o$uy`7*7SKwjQ4qv?W~rujOgK zYuiLgboz7R z%#EVD;fKzl+L$8$AI}HAcCwk{N><6Nco2I?KcHgyq zx+enzXhXcf`T4rLmlGE?Pmhgz(Ar^K{JgE&_F8n&cUiOf-S_;Ox?gs_v&S#eKc4by zke_}kWWPURIX~4?rd##0st8+RB`+zCD{&wv4OHmKw zcWiHJw;U5a_-wZ(-1hXztlD#pckHu=&iAf56h?mYYRsD--G6$!>wf+B1ubv>s^_i2 z*o&e)s@$-UORu2y-U)E1c(cQdbU|A%@Z8QyZ`cKWK_ z**Bt{orV2#vuB~%XNTr2eK+Gy`n)AMA0%gOmv7zBzVYkIpg+uO_tzI!H|*cHsp-8{ zmuGLc_V;&n4^X!L)Q49h{#LN$_a{G2?Z1`Lc``9=z>I<<1T0&Y1#9Np9`j3mxBgKDItdL52hW Wv$rRrd>iw!Y*t2&=8tJ5oBs#*X1^@s6N;AwK00083NklIskTjx#|H^tZVV3XBo87lBd3o@$?{?>Aem8G+_w6~CzI;Nby&Cn+U%cIW=2u^D zl|=m~4B%_}&T~p%eDm!y>(jqqLDDCZAQjmP5_|2(@(+IVU^n*P`F6X_YK^zTJ&n_t z4q8_m`+MdO#vfD#?QbnT4Tc2Q?RLGpFy$}reCL)v3$%a>JU$6a0!j8*0u*=Urt?2G zhq={Hf|z2^JczKJPKQB7^f?AC>J5%^Kec*H!wT@h%OU^!<9&ukU{Va2i(MuH0cl8t zPXX^PIfmVRj`#ansv=nX{A6eWqjuoKT|aX4ilJk` zA?*m9Q^UAgSa2w`3mKj(XLw*?(hv8cb%qf-lmph-#mOt?Dnb2XOA`WRfy+!s=^Cb* zKRkbpTWj6cSuOx$tr46S!s<0sLkp~Bhm((B|12)|+fE5oSSo?7B}l_sJDETuY|Ku^ zdV?*7l?+?S%L2B9fo{yt`-kgmEV`Fq_%u>>)(?s$t~Rh_j9Lw$VI;#jc32)UhBF5~ z-h%hCfvZ-T6PJX3%$9J{m?3hP`G2^eay~U zE^7npos0UXXXk=r4Wnnc+ViXIf?tZEUs;7C3XBUp!ip>y{i+x{6eR2lF?8arozBJ1 zSP9tJK{EHiSsK^Sv2D5Z0wl_SZTc$2)I7c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxR5#hc&_u!9QqR!T z(8R(}N5ROz&{*HVSl`fC*U-qyz|zXlQ~?TIxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7KMf<|~|UP^v> zu_jo#udkJ7UU5lcUUI6Zi>(sS0KLr26e|-8Qx|79CnIx9b2CFjS4#_X7e_}|6H6CU zXGUI2$*<4On9mVa^UGcH4m8Bi-4(mjoHi=1_s7nPZ!6K zid%2OqKghI@T6$6pH!?;d+zi0<*om53vc@L7)}zHamJ!P@tBPrcXs zO2cyIAHOHz2fw9Qs06WnvskdYa&tTXB*)f+&)0rs%H*rL?5AhU1IeRaO3w1BAK=+8V|?13-*UQ5r5dA%fBXQ%eH&-zl`lYd3FC~#GncL*%& z+h&_@tY><$ykv`ANYrS5WmA^0$+hoW zjs>aLiQ29+*(0T7@p6+W^Ld8=vt7~J;SGD$!ljmPS29`p=HorlExxa{kHt1HGFZy) VDRlbp)(tAFJYD@<);T3K0RULZ(Cq*K diff --git a/src/assets/images/toolbar/icons/house.png b/src/assets/images/toolbar/icons/house.png deleted file mode 100644 index f2c8746ab2d045bcae2b99e07df7e534ca299ae7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 399 zcmV;A0dW3_P)PFkQj_bQ7!pmCio@=cniW4^UL4yCcAsB0B)d5#(ah900N$6bi^8u&6r`>A}5bOYu#UKZO_#qC$a11gOgo)+DFe#3JrvY+(j?9OJ0x2N@4|Z~V zj4K342??tB9GQBjLjD?IcylO`WGAiS4ApfID)VP_FRH!1kyw~0GE28 z13;lbj3ZDC1ZjX_VjO@|J=6i%9D&yX=sqG8$Am%vnE!i)U49N6gZNZ+0CH(YO-!r< t=;jE5O*2|Mf~W>6EgeC0Go8j53;@05@P!IqvTgtX002ovPDHLkV1g{Rnh5{^ diff --git a/src/assets/images/toolbar/icons/inventory.png b/src/assets/images/toolbar/icons/inventory.png deleted file mode 100644 index d848586ae31f18b3a33f6badb4de59a0b0e73c09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1973 zcmV;m2TJ&fP)Mdq%#-IFu1lap5QG57Sn*ZzwJHlZi4hK*$CiODtOAb`upUFG)MuHt=o&9DWghSGeEbQBRF0^6`fWcx+& ziwYigl@=ZV>@Dlj5cGuyI%c+MyWIc`Ai(U-D|ni_2b9(0H>(p2jf9Yd53G^%EW*cD zarL;Tv{(V&xtYs)ul@zW-4@6U!Dh$IYubP90mBLa08ITcz4o;UQyNUk>PLxSAFw+# z9t?$v_`nR-7ll_(D>U9Z91sOYaoNIJj<=bmc!FTZICe5c28GJLC4%cIQFm=pVtqms zrUI^|sk1 zwH4H?KMVJLaE6Y#t^in7nytcZE&M3jyuW6)9;`F?`=h|gD%fY>h{6t7vR{V6u~sfR z23>z10Su!VJQ$SrRU?H<T+!{WPcpbFuE5p%R$YSKdbnY#w8hxH;X5Xv z&~Faz5|KVkhK9nrx&d}OTVz-$%|%GTpc?=kC%afsDnh>A0jIdF?b-zepn%6Q!dDou zRZ@4$4+1X%c;t@rbLvwb_7#R=LFa%eb@q!z2p-@710-N^eu{#DGX>AX;Yz11O_yZu z4)nSYD4;BW6`Hp+Cct+?U~X#-3kUaMw{VDJ0l}iJ1)YPu4`_e_GD!EEH7`)?T>HUV%jeAg{7O+`2VsLa6H*5p+WTBtGu z!y0S}Dl(i0?9N1)&zGS1rGXH5EEWMqF+sTl3wdDsu7)PU`+vMOrJ*}cVYhG`Rdo6- zvE+G{)nlms&?@Nx9)qe{ct|8vIL6<}K5(@x1%-IWaH_UIA_;T`fZnt5S>T9=ttFP@ z(vJZORhQ4UaVukm2^5_K(Cp#tctqhyza>b(0J>@m4aFtO?n{x81r!$7`3g5#!WCUM z6BeDPn6$Md+a$O&C~eIGvR1)126u6yztiT$j!VPB$1;#xJt&4;v5(0;o=)REPzc}z$QDkZE zI^P<3h?~TQdV9x$Ve*`J&cTl7=^?G0{1ol`if8Qg3S6~|1kcy-ESc{H^K@Nku*A~i zIkUJh!`bvu1O)--39g2j!>gh4SDgAKn`n={|96^eu`Kpo`M6C3vibw0WtU{KJ_ z2T(fh;`tIT(Xajm2shzjT~=}SBs|KA$gB4i{nC6sIObIFuJZ}@{o*kcJr?-V0>G_8 z7eA}$@#d?DC$(lYkrV$F6B7gc1SYl~pFMHVZ~gyoUp?PH3m)g34)!Ld00000NkvXX Hu0mjfpuwsH diff --git a/src/assets/images/toolbar/icons/joinroom.png b/src/assets/images/toolbar/icons/joinroom.png deleted file mode 100644 index 894ee78ff75fafb47bff9aa359b4d2e170897c06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1084 zcmaJ=K}Zx)7#{Ibq8-8nt#BFU2@iCcg2McInF%YNoU?P^VS_b z6i6W@b_qlx1VM-{cI;4LL;~1+8)fj_rLkR@BjYy{<#;6 zc9fM=l@J6`7U>k?cs}DiCyMcVcDZLBPn9T~LJ2s4vXTjiHU;(rGNMU?APyvD^yV^X zCWzt-YBGgVVizw%%`G_?x2+kNO%Tm3wjs$w0FnJ*P}Tj^j~9y+sVaV|mlZvt5dvwo zbIb&Zv1n2r87gKuYcWhehW8`vpnir931sM&~dYyxT_}~pLc$*v$3vZ z`18x6@sHxCokuETvQJun@NBWp cwYOE#N8CME5?FcuVH+DDBH^g85bPWO10OhQfdBvi diff --git a/src/assets/images/toolbar/icons/me-menu/achievements.png b/src/assets/images/toolbar/icons/me-menu/achievements.png deleted file mode 100644 index 575464d6179161e17ea2322fbc271bb17b9e07bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2306 zcmcIleQXnD9KPusV=}CQW2n*NoP-6gcm23)d!cM&oveh8x>ek8#$NBqL-@Swd;4yUOMEl;Nca zGG~zUdQVDfgADHSdXJr$TbLt*bIq#X|BqSPfeMdcewGGB>vQ%E9Ajs|0v^xWNwKE?Iyqnq8UW1U2e2glmSZVX`C~d zt*FJOH_&F%M9)Kwq`^jzR>EMyNdrUD3}r!67Y41#yq~FbJe;xxzwB7Os!9w&gu`Kd z*rXTbI>KPHK@KBfG~y6}E76e3M(~jG;5dT=D4Z-vsvw3?jgj?dEcWlhjZO7FiCE1swXh)SS{jWP$ynm|Z>aNHQr zrT0pWa$wX`o+Cg21R+d;!VGCsQoX2(O1=0Wex#Sv-bhTT3|Li^J)#&GPn3I{1vNsi z(K#-b6G9qqp{6Od1vpq0*fAq%G{B7EM%qJK7^9gn(KtylBsm6k!Ajs+m7N$^{ zD&v0@p9(Ek&xYy%?5+f+xkG4uXe=?rKXW#^c0pw4bvSMex!Ri2tjHYcIZKm z%?*E@&pRC@p7Nt7Uhb|KAaxtI&znM`r;oCWTH5Opvve3csVw4cUxQa zrq8E7G4+k}`@fp`|wM!$;dy)FZU*FTViQCqaJl|6_oUyh4&a2X@ zHxs`cELi)=sV%WDKioHiIZ7@qjmdX%-8Iz3k?FOw z*Ys_5PLEGsQgZ!=Z`ik{Nf(d)HnQvN#mptYd1KYfh8nJQ&wKp)#ihv36TfdOvcJ+4 zUChpZZsXl&udI&O?EG|6-l5AYoV|{8PZSrGJ z#TLHj?7bSBet+H{?!xu^8?Jn8INcv=*fD*eYVXX-DN7AgUo2W(qJ#%6QtX@I+GK=D zHrLJ=QCg4h|Dthk@WY?DxG|%JYi{{@!&a$g75>OjjdWnc@aBqS`|<+ISI-P|_y>0F z%6$6TA^oRl?T^ml@jA;Y9J?2KTmAw!-a94$ diff --git a/src/assets/images/toolbar/icons/me-menu/clothing.png b/src/assets/images/toolbar/icons/me-menu/clothing.png deleted file mode 100644 index bfacabd844f94288df500e1b6ab84ae5e7c5e7fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2255 zcmcIleQXnD9KP`}w(*e$6WCDUb|4wD>wUDn?M@0C>#)NWMk%r(hFf2mnbro_K%m`-Fxr* zywC6XeZ0S0Q844xp-H2X5Cj>TXSX@w`+0bePKbxk%PHVGg2bgtIXMNh9R;pjJO@G2 zP6}@K>3~+Mg5hrWkrNXqB&i|i^5s=dcXLZiYs(4rxch7Onwt6ZJCY3@Um^n{e?{tt z)K#ut+qsY_}X-?nBk3%I54#JA5_vinZuh1{%}$VDaV=QFLo@$tJ^LsP=?H`mOIYh2&T zHg9T7Gg-ITT934}WVKQ+O_?w!bzkGYahA^tTTKMpT!%KNHH@Fe~k z4Kr=a>rZ;!21amS=p2MZ!j7Ak5AIdNm?Z}6ML`4^{G5KrAscFw5oF*mlB-ZFbmVh_ z;y3c5;sM66KLF7PGHFUUzzYk3hI&A;BwMjN2bwWd60O)=i-U9oazKe>uTa74iWx4U zVxho_*p$iWq%a2w{6OQ;u-_*Kxv&-M=H=j6pC&N08=@_=V%fSuw9rw2<|ryaEk*_x zD03#7!5S&XOq!TWsWcDbuVNRNCW$KMz6iRyhKanKbB0Ky4^N|`Ev+;SjmV|$H> zLTqoKO!akpDhdSf0Y8KVp)e|DDo~HY)~286`>N7+|6^8P%(EUZ0}J0oGZ-ogoL5o(JggMS&ldwC zAQxlkziM(6pQ1Vx5ysr~_&Om~OS`%q6}i2vrSd+o8F)eDD>P#?xRF#L%1a3Di!6?SN2 zt`qk6xHs}_*)IFx%jaK_+p-Mt9o9r3S1)^cI+%6lRKdRdqlxLx@3vj-_XDzGRn9e( zZCgf-zVQ?94V{bF2izPP|Mvagzc@bJQ?+^Bv5B5Z;B3Xg3x^};Z~XayPPw-r0l&2C z`r4KU2mYRz-;};y361@5Zofk>dNL2a3mU5UJ%^@cZzngP7e`R`%~#{fgu;}Q?b{^J zrKY^$RfdXBKj~jMZQ08Dww<>g7{;5*x3?pEQ;h>o71obfn!F_xZ`qM>x8@ouCyrTI zGk8?xjl)Gr{Q8e~-yJvd;G%P%ud41k^WLzdRKIX7dNi@6u>oywpLgJ^Yx!-tuXWzR z?fD@pzq34$vUkaz9ixQGJM-HzPi@>s4Zb&ZEp_|HF^9#)k5(4l_;t{kbKmZ28ZvT6 z7ukjW)-mTk`qoxU&B1MZJ7EeWyUN_p8=@l^6r`zZv{t&-}D-K_6NqfxMu z%F<3kp^#o~MQqU&pt4n(BpBQYuOO!0o|$GSHE(nwR+<3GE2u+cx3{CXg$!5mF2Vh? z*cjRjuL6@T$Z6J`_SKe02~;~3xSgij+8l+Pv2MbI1ZfAA5~#L_*!Ij$0u%WvmxcYI z3o7(mI~J3!7Q^QAW~cuFxU0F_)@Iw=;&Hd}6#CuAK$G5URC0S$7*zHLIz6+rRRP8d z6(%xU6G#eqLfa@%e>w1Z{o_BoE`gfzKrHng)UBg1CKI1|+)Sntfikt#a=7`wtI|oE rK^!;0HU;+jlbR@748r~LY0&%vC+1Ek*ngK*00000NkvXXu0mjf&T2Fj diff --git a/src/assets/images/toolbar/icons/me-menu/forums.png b/src/assets/images/toolbar/icons/me-menu/forums.png deleted file mode 100644 index e22426e6d67447fb698f844fb454b2ac6fb29024..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 416 zcmV;R0bl-!P)-t%kH38_1VPzyPb!m7_Q!m2xC|=D$sxqR5V|kNOpx<`06Z(mXX~98RRF>;WE#y^ z>~|cWD?N<6R3pF;ssVVN0%*_YgDK0>T93zE2pS1sE4;d`0n#*SEq0^rCJ(NsQgB_2 zQL&8x5CAqO?~k!Wa!SR2axC1NLnr|tFp46w*8xmlHzpZ?@BMrSGy<@4ps-#5NYjAh z`*VQLKUxR9J0Ku10P*zB9Ka<9w&R_SO$CZ`;()5;C~1;zjk3$xQ{$dllbqa0`|O>}~q0q~ouo=i?ynRiKI z{Fk#efUujIf}$6WXyU8@sFw~b0icP47u^Z~Ulc<&c@22|IQ;_c=nI{BT3d<$0000< KMNUMnLSTY(XQ?Rw diff --git a/src/assets/images/toolbar/icons/me-menu/helper-tool.png b/src/assets/images/toolbar/icons/me-menu/helper-tool.png deleted file mode 100644 index e324611fca78d810deffe9c00082e8a0ebdcdf37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 309 zcmV-50m}Y~P)9`S-s*y2< zV1BF#LHBhf=UfEvWAD>|2)p&-0PssfWQ*3!&yj-2g6=xcnY4nEp0|%)bjbw2bR3)p z5Pz-x3JXH;OC3W9E+`GS(z`?;hCGLma$M=0?f}SrUITb7z;ir+gOce3TQMMB2U1A6*hv<>piw}ZLeH!TRRat z7y*Qs4JR6%p)#XGBEq6PBy$}Q9sx2z88he{U`!AU4|xd^{N2`7Vu0))FS)zl{eGX{ z=ll6Se&2Rue(t>Fq%lbl1SRKW+Y7+^CH2;7z%vcswH<;ICWx7t`3oKS&MY(&f>PU9 zm+P!wSt0W;xLn6iPoI_~R}^g6u(`n15{L2Mt6_jZ757(+@-%`)5B+a5vQbaEXi5YBI_TLOBWf^(&HU&@FYz!k5sV zO>@@NS6#DZn3mJkZ)%R@uGxJ(+>w=$2mL5z{QiBbXNqRGRkv5W;k7MG5}Mv?wYEf> zQVq5Sd+YING^3T6oIdT<3HzJ&Ponk}wi+;NOC#Kpx@QtKpmF4-S$LQBZnAd8xiTSQ zg4U&1-?8e(?%M1w*15GcOP4q`n-Zt6hgMdPE_x>=WyVk($InkVQm}}`Jr~_BU7mfz zjyA!iGqJ9Yivyuh&~b%Yf4c_6Y>+>@C;&l&hpTr2^g(?J1P%B@bQUUwjs-L;dG!n@ zxp{ri>j!8EnwcK-Gi)iZz;3=+^x2T>2U`$WN}xZw52X?=lM zm_Wd=AmhgfJ+8Xc3v@W15A}NE=zx+{4y?rVK9xA&4EcGifDcGzGRtR`^FC!_uQ85| z@Aa3-o^DS$7UMm<7r+8Q7!fz+FOd`}P$E6UkN9%j8$X>X^Nb?NPD%3gCMv&|1tx*l zaH@l0MW4z$P1O|J!rK{zw;?1>5+GwJX>#IbnxtrgL~)A7@gArHR078+Oy9r~Ckmmy zKphS`#}`l-AIs<1Z3qyh7e$UX3ao)MSq!M#Od3%mK?x{B@i-V_UlAL5M7X;u zX@*q~gAHNTD&RRJHZ49SxP5b@hqj`G2c*xbjUHG)5|j!?=4Tg!MD(HhuxH5+Fy+q| z-?z&6U&Y5l%a$;{Vjgr?3{l;|)IQXc80^0}>t1`JXZ6BCBUFd+4h%lxJ)HLeY8iBB z^Z11)!B6M<9Q$l%_Oa%zw%kNQw{GI3C1a8-c74Xcd67>WB5mW4Bz<&PW5IWa#zp2_ z(u@t0+QXL6$v>}kq_MU3%K7a@4?hfDZYi2Cwm1BecQ)zH^>wShczfpps5j$|FZaMKcgIsf+F{kTC$IX|MTeKb4s#c*=<>!Sm@ zMQLld?fR`KJj#{)RkWEJx|SK%SZ`-C9G{3pCcnX z5|wi)(4AGjhlTv3s(s0|n?qA~R;|A|KeA_WTH=jxY4q-uU$qhXz|pPc^~c_Y@B=e$ zjKIqiUr8`dJ-@n>LdtRJ`@By5 PdjsWU<=S`6ajp3WsjVn1 diff --git a/src/assets/images/toolbar/icons/me-menu/profile.png b/src/assets/images/toolbar/icons/me-menu/profile.png deleted file mode 100644 index 04964bfe64038532a534b1e5d1b31ff2d4f9135c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 468 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 diff --git a/src/assets/images/toolbar/icons/message.png b/src/assets/images/toolbar/icons/message.png deleted file mode 100644 index c12d5bb4a4b0975f5507b76e4f10c96b8aab2a1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1099 zcmaJ=K}Zx)7@pEX1VciKy!0BQwA!7ST~~JoH_@G4U31rEU2qjDXJ_8JgU-Bh=IO4U zERpC?DHIe`bnxP#pdu-xgf0<<5POM85W)l@>LMOGY;RY0?a($b^WOiz@B9Amz4y=c zaHylIvbK_3=k?%^st%nT9urG#tQ39tV6H;voibD|4q#+oAk}@&+ z9=1?a*$Fio!?9quAS2B#hTw}iBZ&g%+fo=Y<{$V2e3hu$$23x2ox>{UY!3i(-3$Dd2-WY*OH*v_fRLzZj!EEbj-!cA8|O` z9rdlRuOo!A*(^z9G8r;y*zDLK!9g4e^^%aRJYSw)CYjlQ*cMHHxt;lRXbMyu2>;s5 zX3cVEb<%dpc!*!FChzQj^x#bO9PI+G@`V}h^z`Jc*|ioO>@D-#>ZS3u=-R2TkKZ00 zJ@Wn9-FFR%d&>3JY-Ph!;*ARULgJJ5!K;4&d;@RT diff --git a/src/assets/images/toolbar/icons/message_unsee.gif b/src/assets/images/toolbar/icons/message_unsee.gif deleted file mode 100644 index eddfe1cc2b7d244145d98d3e0429f758602fa39d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1511 zcmZ?wbhEHblwwd|Sj5htm$xBo&tCZxN)4{^3rViZPPR-@vbR&Psj#ZZEyztRNmQuF&B-gas<2f`Ovz75wF0t1!um=I zU?nBlwn~m52?day&iO^D3Z{Cdy2%EHCJN@3dWNQkCKiS|3PuKo#`*@v`i923hDKHf zmR5$Q3Q(W~w5=#5%__*n4QdyVXRDM^Qc_^0uU}qXu2*iXmtT~wZ)j<0sc&GUZ)Btk zRH0j3nOBlnp_^B%3^TzcwK%ybv!En1KTiQIIg#cFVINM%8)eo$(0erZv1Dp0vH$f^P> z=c3falKi5O{QMkPCww={D!G<3DJG%|FxFn2UJbv8D2GPf{>>2=9ZF3nBND}m`v zLFhHZsTY(IatnYqyQCInmZhe+73JqDfPHM0iQ6s4IL(9VO~LIJ6P$YWfsWA!#Vb-g z!-Rl|2gHP@S|A6W?o;!CiM%OrteG>WPn$Yr@}!9q`ulo&y1P0% z+S^)NnwuIM>g#H2s;eq1%F9Yiii-*h^7C?Yva>QX($i8?l9Lh>;^SgtqN5@s!oxyC zf`bAB{QZ1=yuCa<+}&JVoShsU?CorAtgS39%*{+qjExKp^!0Rgw6!!f)YVi~l$8_} z2E%h009bK&rn)CWx>KY`bbWJEwSTbu`A>XQvu2%D> z#aQz1h^PwMy=OyX(X4~~`x_mm9(P#hAg_4o#O13(oFK2TqIqRA&@2B0rb(`zr5t>_ z;NQWt%KHK=ZHgkIoQpC~+2xfT`*G%qTF>!a%g{$uTZMxiKdbyyko3*0sxAZyD4@^}hd9@DpmBs0;Z4FH&Ufo9R zjm6Cw|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfLrx|^289Xnil2Z&vY8S|xv6<2KrRD=b5Uwy zNotBhd1gt5g1e`0K#E=}J5cN9Otb&+B`H$r)!7-h*mM_6OWMD9e$&z@k*&GfYwrq%UHMdv9zj?o0G?D*( z)F^g=%!IF%#RvbpS;_NW&&!w9G(6&LlY4ndj?UC7F|n007m~hgIlpd#&O*0KR&pma q9orR))>`bkVfQ|&@C)lJtGBFE`qNVjcXm$&1&*hypUXO@geCydQkbm( diff --git a/src/assets/images/toolbar/icons/rooms.png b/src/assets/images/toolbar/icons/rooms.png deleted file mode 100644 index 00261ceed4d77b87ce0c6d84fa6311558aff4ab3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1465 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 XSX*->TJxg$2y>vh)xZ7m?p1#QUUeJ! diff --git a/src/assets/images/unique/catalog-info-amount-bg.png b/src/assets/images/unique/catalog-info-amount-bg.png deleted file mode 100644 index 4a56c9b265580af4a41d2db6a93c0749e5f447e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 757 zcmVHU6$*_|olkZ5@Yv}3=2k7Pe%oFutjyA1iMDh4Eu|d$HMaFJ z=2ly{Yq2PWwR(Deuiiet7P^0aQAw(wwh8Ml(_g8!bNVf%9Q!r4^)cpFTexe{2*TQc zx~w4qYrxt!tP4=5(tIsszs}VU3y9 zH>?)6P*BGLYq$ZvVYRSDf;t9R!)NskEA{=GL6zWvjY)$B>u^3x+gHHq7glbvVnIDP zITL5Pv_lD0IA|Qq7_1Qu@C~c9va+B`C#M}!^rsgH-2hky+k|xkR===n+&~so?qui; zYd}rg!^$WJJL0UqVb$KVu%J>WW6rP!)YNsrK*b#FNDBCd6|%#@ih{bfzCoUxUNl8N z1!}s?W1zw|BZK7|R*aqW`>#1{%TZ8g^D7co2%3~p!e(1I^;14=q+5N%N=Zg2KIB+>}-JDdeB|f|g<=C&WtyC;siVAV<*8kTW zwq-ke`*aEwGlYwKayLxeGEdcy2U&d2tkRDlJ>CH|jiXYqa=BV-Qh>X`!opJlt1nnJ zs{{$Ev^;Qzlu8ORNa8pAFLMtn*_Cw=S!`Qems2b z8&=EBA{+1@8rIk;;2Ty;WJ3gXNLXWAi*HyhVK^12L%|w*uzbU6nY36Rb!b>)!=P_i zEt6IU)OHu@n0A{6tdVZ5Rlg6Q18Tq;u#OQ{^d%G;eSH5klFCzIWn=BHRNFcImQs%W n8r%99b13w+KB3T9-#zsU?45%fJ6~3100000NkvXXu0mjfX8veL diff --git a/src/assets/images/unique/catalog-info-sold-out.png b/src/assets/images/unique/catalog-info-sold-out.png deleted file mode 100644 index 79626e146ba750d69a301276da31ea7ef3f5cf9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1100 zcmeAS@N?(olHy`uVBq!ia0y~yV9Wus+RgrtArf|+Rp#}#h@3H{`@JgOMv(~k-itlr1eUQnY2zEJgu}q~=E*E`3LzkBxfcI$Ha zoR?RRw!isk>9x^iZBmtG$+}B>;(C9t`74n8`01uk?q6L@s|)uQXCGVm?C*oue}75I z-?m%*^+gEN+plxKF28zy>$&^7+e<#yPPMgj*PON@)JMPlT`1`s>Q`URu1dw%d2?_}ZGVsMjG(UZ?8Uof5(MBiQTMk^zG|X&(56}uOoK2XlD#}26OI$ zy_~Px&&P$m{QG?U;;i#?Cp$maI{W(SjZNR2ds?TTJ|%xu`0AR+TwB&!zZE)`)@W;5 zUZuzCaj@l|gLDS-Ti=MswR_&#&bOJgXVPpr&D1y7WVSIxGu^E(+9&A4w2j5=80)S7 z+FLGv-Ne1&W1W56^xbbVeHsfmlQ+j(y%K-Yu(tVAEANGOlDBjldcXhv@Jr-Ikssd; zvE;*g6TdL=zPjK-Yy-vGDH+=l}vO3nk(7@=}q~&Ww!c`w2|B3+^g! ziDr_1KY!bG-30%IwyA5@E#BenvS6-@y*5zy>;r!P-#w~b@V2*+;kH%yg1ISI1Fxta zQes)ayCwXgtl2>lXX~63)lQBr^fMl)FIoxPNd*l^4r<=G<(aWe4Ul=ZfC|c{bO+ zE{{+8J@ea1c5f^%@HO&o0fzpz$Jq(j*Gx!uO_{H)w7mAl)(d6g=NNKQJC#t6R%<#j)JtaNQL3H7$32mhPO37rxag2!TSYHz01FxapSF z+rqbso#WUtx$o)rFAZiF?94LMmu7n`>3{va`1o^;Q&+7ZDSKn;+ja?V{pnNVjkmJg zvOL!IJ5m1gQDD$~)BJZw0+_%9?+D&FT)>*^pLxsWiR|RZsvEP4Dvx`AzNT?%tM{E4 zzPYPS)|bY;yEE;5YJ76>t9{m~@zIu1KcwX2*Cp;vE3Fd9PzL2u&gK7^WQ+WSO%%1B Q0*eO*Pgg&ebxsLQ0Oxob-v9sr diff --git a/src/assets/images/unique/grid-bg-glass.png b/src/assets/images/unique/grid-bg-glass.png deleted file mode 100644 index 5b64c480bf04361ebab979eab0f6caa99077be46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbB=6Jd|hE&{od)1q(!GMS5!p;TX z?fqOX^gaonAURcJmxhyY+-nhw_L;fIk1#*pcYW)(wCc(CO-;QPs|0`I@}9crkkQf= z8@x1i*916~ofh?4QD?nPXq8Ta_CjGlAJr0}$tzp(S~gF)P#YfM^)Xjm^Qoe0fYU5a zCe{BZQkwt( diff --git a/src/assets/images/unique/grid-bg-sold-out.png b/src/assets/images/unique/grid-bg-sold-out.png deleted file mode 100644 index 94f66620ab811801e478e811b15ed62f043fe2a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 332 zcmV-S0ki&zP)h5Ga+``7kYa zTrp5p1lpq+Dta6m1np5m#S(C@u91AsKcnY-&l9qr>nW)@RV)E&&fkYF#tEcBQ4^U2 zZ{$lOwq}e8CghukP!gIn0E95cn-H1@36V#(F%1bZ%Rm!GURE*%-&|-w0mL6>0r77u zQ{eNEFc%?&ftMgkC}kdU5UPasM8Jd+e;q{-E0E?Ms)>LJwL}CHYJpgRS|iZkj;07+ eT_6ysi~0dr*QT5gZfC^+0000|k1|%Oc%$NbBI14-?iy0WWg+Q3`(%rg0K*4HH z7srr_TW_x~yg!L}n3b0WpUM0vb84vR#~Bx1Y>1Iw*T`_mi2y^Z(BE zzRp{_WrA=|eV(xBl!j{$LYY}O1QZ+^7#NwrjAIU&M^=4fe0tpC?5fn}H@|nx4UhTe syjCogNkzk9KWpfeG~H#3rf7d>%2~-dJ5BUh3eXu0p00i_>zopr0Jl*@f&c&j diff --git a/src/assets/images/unique/grid-count-bg.png b/src/assets/images/unique/grid-count-bg.png deleted file mode 100644 index 68e13bddbb5ecc5d535563bf0073c16f78a854d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^DnQK1!3HFwjQR>doC1%?Vg?3oArNM~bhqvgP|(-Y z#WAGfRXdq6fvLB6=2f1V4r`oA!&m2g1p2Z^)DWM{Xe^ZuB<`N zn-z`^6=p1UlQl_^WhuYnkd$)#fUM~O2_A->-#iQ+f2}?PG?>BD)z4*}Q$iB};qNn{ diff --git a/src/assets/images/unique/inventory-info-amount-bg.png b/src/assets/images/unique/inventory-info-amount-bg.png deleted file mode 100644 index af4e31e2e55f34b6625efeca646af58d95562065..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 521 zcmV+k0`~ohP)YULD%yF`E#M-(sSQ%7;Yg;D}8O$1^L97Js3?hS}G5YPT1SWL`X^?mRmxw+;EC`c`nZlA;cb=jmoWm68ZdHs;7zL(OcbOf3?*;_ z61#);4HJOWg4qC}Ek(ww>zg7l6o=an^Cvtb4AaL?O9TU#W_G_QvP=|*{UJ!K==8Nr z!S<~M1M5f)7_*L)hKbgZk}zhnmWBxm+P3!zJvR3~BMaKU_z&$Du$2Q`L=+;<00000 LNkvXXu0mjfB01-z diff --git a/src/assets/images/unique/numbers.png b/src/assets/images/unique/numbers.png deleted file mode 100644 index e1ece79f46a35183bb72afcc166d116bc04615ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^hCs~9!3HGXl(Q@cQjwl6jv*DdmIga=F&J=s`ai#H z`auP+$-Ha}O|>OI@V$3EC=|ghwpJ=46%P_p!L9lxe&L5m1>4+P z>(ae#ibLh%1^N8Q1A>%QL>{F{R(hj`GUoMQEMBXMJcd-;4W%gp%3J=r+~Nh3t(uLf zZo0CAYr1V}b^AHl&~&V7uBz9OrhA(0S&lqC6o^)Yk+;#lG>rvM4W(aIxu>eb;jlKW z*LcxWb&P?-Pz?hC0+qX2MMfwq&(0XytfWPpS253I!AJr=s2U0=ourWFbK0z&+60EF zBa*9nO%o~2fWCh;G)?E|vRc`JC{w+M5|`cGoT(eEINDtV>ib?ND=U&w)@e5s z5LJug&@)|PGM!>%Vw1wfVkmG3MV1@kFmfUbo8ed&%x`l#5MGG+lg14>1&+C&9;=%s zqmUbM%mBHXsUcTqAqw0&wQ!(EIKnfwmx>tv9g^J5DpZBQ=ui#U%`iZYfg@zvc7Os) zbCE+_TBn%Uj^QZsowzNY@WSUIxLa4`ka`g>QUV8j^xFd*Ji}?WNvJ zeo1zY7Qa~O|5x!-YiXZkJqF9Cs)%${vCvEkqyD#McWOTCnjmRvZz zO(`*K!!=E$8Q4KVWMUNP1S1kT77HSa={T6ENaC5E39Wi`{IT-8mdx2?Sck=Mz5&3) zd<$V2BwoME zH?A%zAAa<}N$<=fzrMUrS_fB8KN)m>|EzWT(jVb7E!Fzv^55^0Z-2UF{_yk7558HG juYB=o`Pi3lU%&sW+F!419-NEBHr82LYk$7{#ykH20l7o+ diff --git a/src/assets/images/wired/icon_action.png b/src/assets/images/wired/icon_action.png deleted file mode 100644 index 78e90e6302316b47e54429b3440551c8499eaf87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmeAS@N?(olHy`uVBq!ia0vp@K+MO%1|+}KPrC%9iacE$Ln>}1Cmi7YXFP%9-}^gz z9@ra7DNhvnTmSP1%cf=j11k3{Q_en=ovq@tasGUHuHMsXJ60OBii(OB^q%;nagIr| zA#noR1PLEy9%XCeNiMUMCjNEqnXj}`yy}FR(&xgX!kfOnSmyrdQp@SENeq6x48`Bq VJ#7q2kpbGy;OXk;vd$@?2>>7KL7o5r diff --git a/src/assets/images/wired/icon_condition.png b/src/assets/images/wired/icon_condition.png deleted file mode 100644 index 26925a63f58d0070286af95dcc6280d98af51d98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmeAS@N?(olHy`uVBq!ia0vp@K+MO%1|+}KPrC%9N<3X0Ln>}1Cp0wt&#(~ElIwKk zTaph~(&hMDg!(;G-q3rL! V%ztc#SAq63c)I$ztaD0e0s!`tI1K;* diff --git a/src/assets/images/wired/icon_trigger.png b/src/assets/images/wired/icon_trigger.png deleted file mode 100644 index f48d13c8751c476841934a05d27981388a5b467c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169 zcmeAS@N?(olHy`uVBq!ia0vp@K+MO%1|+}KPrC%93OrpLLn>}1Cmdk;zcFFYga4mnY&+^FqP9Q~q0J2GqVqmv+}x%E|>n*9!#1_LgA}Aj!gWf#JSWyN0W(_f#KYQv$3aY STb2XuX7F_Nb6Mw<&;$SpoITb6 diff --git a/src/assets/images/wired/icon_wired_around.png b/src/assets/images/wired/icon_wired_around.png deleted file mode 100644 index 0b4b5a12545cb73a0f588dae5ad803c8954255af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmGcI0YV&#S9GGLLkg|>2BR0pkTSD zi(^Q|t>lD+gdhE^_t_sYu(5bFbR`CNhi+(K6y;#}$P~oWuv1B{<8|W?Te;GNBqjlA zhC*h!*8dCHOdYNsiaGM2;aN;g+k$FeMwc_~Mju#3%+@!4d2?Kx?f1fU!3TsJBA7qg qisc{N^K0IXhz3jHNaL{gj0}9DSzfmuh6@6nz~JfX=d#Wzp$PzgMnP== diff --git a/src/assets/images/wired/icon_wired_left_right.png b/src/assets/images/wired/icon_wired_left_right.png deleted file mode 100644 index 862d6d8138b8d597bd57b732bd0ca62e9c5db082..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmGcI0YV&#S9GGLLkg|>2BR0pkSP* zi(^Q|t>gp+J{5+KwF>|GS%q0y8Y&nq*&0l)F@LOG zc-`2z6q4+wG-@xnc39*Q(~dvel4}^k7TehNS0f9h@EE^ Q2HM2n>FVdQ&MBb@0GiJ;hyVZp diff --git a/src/assets/images/wired/icon_wired_north_east.png b/src/assets/images/wired/icon_wired_north_east.png deleted file mode 100644 index 3710854fdafa269ca0973583aca7e810ed450f44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(1|(lrEz1IN3Opi<85p>QK$!8;-MT+OL4Qvd z$B>F!$q5b(EDCk}NB(yn&~RYvct3d+Ckso%4;#%{G9DW_Q>yGI{$tGMI*|OUcEwxH zj4T6|gbJoBtS{F6Y}dV#uFVdQ&MBb@02RV9 An*aa+ diff --git a/src/assets/images/wired/icon_wired_north_west.png b/src/assets/images/wired/icon_wired_north_west.png deleted file mode 100644 index 09eeefc18a1708ce99e036dac88ed5e552db1e87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(1|(lrEz1IN3Opi<85p>QK$!8;-MT+O!3a+m z$B>F!$q5MwKm1wh_>XY%cr;9C`|GggKm!{`<^e8_n0fz)_lKXE*DxGSV3_~JMY`J6+6HI`gQu&X J%Q~loCIBUrHKPCk diff --git a/src/assets/images/wired/icon_wired_rotate_clockwise.png b/src/assets/images/wired/icon_wired_rotate_clockwise.png deleted file mode 100644 index 2827e3d23da0f4d5b51ecec406ccd267291579cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^+(699!3HFsq+HVlaSA*li-F=oAk28_ZrvZCpo^!A zV@SoVmdKI;Vst08a5LT>t<8 diff --git a/src/assets/images/wired/icon_wired_rotate_counter_clockwise.png b/src/assets/images/wired/icon_wired_rotate_counter_clockwise.png deleted file mode 100644 index 7e281bacbc901f43d3fd7afdc492c23fd85fe029..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^+(699!3HFsq+HVlaSA*li-F=oAk28_ZrvZCpqrBWJMJ@otT*XdC@@=TP1kj0&pGT#>})m+%Rbl%a2p6P7#tNY(9AgS q_!wJ~smX(4C+3Y@6HOn4a4=ZSRQ(^2`y>)*B7>)^pUXO@geCyMyDJ+2 diff --git a/src/assets/images/wired/icon_wired_south_east.png b/src/assets/images/wired/icon_wired_south_east.png deleted file mode 100644 index 4217c4b830ff0c3101323d4440eb9fe1be8380a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(1|(lrEz1IN3Opi<85p>QK$!8;-MT+O!B|fh z$B>F!$q5b&>QK$!8;-MT+O!Dvqx z$B>F!$q5QPEDaV6u>p+zZ0rjA_>cT={9&^xYJ!9P6_=FDzZVvrkVtW`VHRs-P`SJ@ zvnb(!VkfV^Lm98)(Spkp8SQwV7q(ugS2EF>wCbh2!2RY{DGmmPiA!Ci0_L~g23o`5 M>FVdQ&MBb@00|Z}u>b%7 diff --git a/src/assets/images/wired/icon_wired_up_down.png b/src/assets/images/wired/icon_wired_up_down.png deleted file mode 100644 index c2d243bae57101cfa041bcba5e4673e892e9fbc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmGcI0YV&#S9GGLLkg|>2BR0prE&> zi(^Q|t>lD+gdhE^_t_sYuqiQ`F>^_HF#P|xLupto?r7~m}M6D9WP*Hcs<85QdRWCZJ@CXp00i_>zopr0KBCt*#H0l diff --git a/src/assets/styles/bootstrap/_accordion.scss b/src/assets/styles/bootstrap/_accordion.scss deleted file mode 100644 index fc62ceb..0000000 --- a/src/assets/styles/bootstrap/_accordion.scss +++ /dev/null @@ -1,118 +0,0 @@ -// -// Base styles -// - -.accordion-button { - position: relative; - display: flex; - align-items: center; - width: 100%; - padding: $accordion-button-padding-y $accordion-button-padding-x; - @include font-size($font-size-base); - color: $accordion-button-color; - text-align: left; // Reset button style - background-color: $accordion-button-bg; - border: 0; - @include border-radius(0); - overflow-anchor: none; - @include transition($accordion-transition); - - &:not(.collapsed) { - color: $accordion-button-active-color; - background-color: $accordion-button-active-bg; - box-shadow: inset 0 ($accordion-border-width * -1) 0 $accordion-border-color; - - &::after { - background-image: escape-svg($accordion-button-active-icon); - transform: $accordion-icon-transform; - } - } - - // Accordion icon - &::after { - flex-shrink: 0; - width: $accordion-icon-width; - height: $accordion-icon-width; - margin-left: auto; - content: ""; - background-image: escape-svg($accordion-button-icon); - background-repeat: no-repeat; - background-size: $accordion-icon-width; - @include transition($accordion-icon-transition); - } - - &:hover { - z-index: 2; - } - - &:focus { - z-index: 3; - border-color: $accordion-button-focus-border-color; - outline: 0; - box-shadow: $accordion-button-focus-box-shadow; - } -} - -.accordion-header { - margin-bottom: 0; -} - -.accordion-item { - background-color: $accordion-bg; - border: $accordion-border-width solid $accordion-border-color; - - &:first-of-type { - @include border-top-radius($accordion-border-radius); - - .accordion-button { - @include border-top-radius($accordion-inner-border-radius); - } - } - - &:not(:first-of-type) { - border-top: 0; - } - - // Only set a border-radius on the last item if the accordion is collapsed - &:last-of-type { - @include border-bottom-radius($accordion-border-radius); - - .accordion-button { - &.collapsed { - @include border-bottom-radius($accordion-inner-border-radius); - } - } - - .accordion-collapse { - @include border-bottom-radius($accordion-border-radius); - } - } -} - -.accordion-body { - padding: $accordion-body-padding-y $accordion-body-padding-x; -} - - -// Flush accordion items -// -// Remove borders and border-radius to keep accordion items edge-to-edge. - -.accordion-flush { - .accordion-collapse { - border-width: 0; - } - - .accordion-item { - border-right: 0; - border-left: 0; - @include border-radius(0); - - &:first-child { border-top: 0; } - &:last-child { border-bottom: 0; } - - .accordion-button { - @include border-radius(0); - } - } -} diff --git a/src/assets/styles/bootstrap/_alert.scss b/src/assets/styles/bootstrap/_alert.scss deleted file mode 100644 index 80b6a43..0000000 --- a/src/assets/styles/bootstrap/_alert.scss +++ /dev/null @@ -1,58 +0,0 @@ -// -// Base styles -// -@use 'sass:math'; - -.alert { - position: relative; - padding: $alert-padding-y $alert-padding-x; - margin-bottom: $alert-margin-bottom; - border: $alert-border-width solid transparent; - @include border-radius($alert-border-radius); -} - -// Headings for larger alerts -.alert-heading { - // Specified to prevent conflicts of changing $headings-color - color: inherit; -} - -// Provide class for links that match alerts -.alert-link { - font-weight: $alert-link-font-weight; -} - - -// Dismissible alerts -// -// Expand the right padding and account for the close button's positioning. - -.alert-dismissible { - padding-right: $alert-dismissible-padding-r; - - // Adjust close link position - .btn-close { - position: absolute; - top: 0; - right: 0; - z-index: $stretched-link-z-index + 1; - padding: $alert-padding-y * 1.25 $alert-padding-x; - } -} - - -// scss-docs-start alert-modifiers -// Generate contextual modifier classes for colorizing the alert. - -@each $state, $value in $theme-colors { - $alert-background: shift-color($value, $alert-bg-scale); - $alert-border: shift-color($value, $alert-border-scale); - $alert-color: shift-color($value, $alert-color-scale); - @if (contrast-ratio($alert-background, $alert-color) < $min-contrast-ratio) { - $alert-color: mix($value, color-contrast($alert-background), math.abs($alert-color-scale)); - } - .alert-#{$state} { - @include alert-variant($alert-background, $alert-border, $alert-color); - } -} -// scss-docs-end alert-modifiers diff --git a/src/assets/styles/bootstrap/_badge.scss b/src/assets/styles/bootstrap/_badge.scss deleted file mode 100644 index 08df1b8..0000000 --- a/src/assets/styles/bootstrap/_badge.scss +++ /dev/null @@ -1,29 +0,0 @@ -// Base class -// -// Requires one of the contextual, color modifier classes for `color` and -// `background-color`. - -.badge { - display: inline-block; - padding: $badge-padding-y $badge-padding-x; - @include font-size($badge-font-size); - font-weight: $badge-font-weight; - line-height: 1; - color: $badge-color; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - @include border-radius($badge-border-radius); - @include gradient-bg(); - - // Empty badges collapse automatically - &:empty { - display: none; - } -} - -// Quick fix for badges in buttons -.btn .badge { - position: relative; - top: -1px; -} diff --git a/src/assets/styles/bootstrap/_breadcrumb.scss b/src/assets/styles/bootstrap/_breadcrumb.scss deleted file mode 100644 index f7fafe7..0000000 --- a/src/assets/styles/bootstrap/_breadcrumb.scss +++ /dev/null @@ -1,28 +0,0 @@ -.breadcrumb { - display: flex; - flex-wrap: wrap; - padding: $breadcrumb-padding-y $breadcrumb-padding-x; - margin-bottom: $breadcrumb-margin-bottom; - @include font-size($breadcrumb-font-size); - list-style: none; - background-color: $breadcrumb-bg; - @include border-radius($breadcrumb-border-radius); -} - -.breadcrumb-item { - // The separator between breadcrumbs (by default, a forward-slash: "/") - + .breadcrumb-item { - padding-left: $breadcrumb-item-padding-x; - - &::before { - float: left; // Suppress inline spacings and underlining of the separator - padding-right: $breadcrumb-item-padding-x; - color: $breadcrumb-divider-color; - content: var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{"/* rtl:"} var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{"*/"}; - } - } - - &.active { - color: $breadcrumb-active-color; - } -} diff --git a/src/assets/styles/bootstrap/_button-group.scss b/src/assets/styles/bootstrap/_button-group.scss deleted file mode 100644 index 13aa056..0000000 --- a/src/assets/styles/bootstrap/_button-group.scss +++ /dev/null @@ -1,139 +0,0 @@ -// Make the div behave like a button -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-flex; - vertical-align: middle; // match .btn alignment given font-size hack above - - > .btn { - position: relative; - flex: 1 1 auto; - } - - // Bring the hover, focused, and "active" buttons to the front to overlay - // the borders properly - > .btn-check:checked + .btn, - > .btn-check:focus + .btn, - > .btn:hover, - > .btn:focus, - > .btn:active, - > .btn.active { - z-index: 1; - } -} - -// Optional: Group multiple button groups together for a toolbar -.btn-toolbar { - display: flex; - flex-wrap: wrap; - justify-content: flex-start; - - .input-group { - width: auto; - } -} - -.btn-group { - // Prevent double borders when buttons are next to each other - > .btn:not(:first-child), - > .btn-group:not(:first-child) { - margin-left: -$btn-border-width; - } - - // Reset rounded corners - > .btn:not(:last-child):not(.dropdown-toggle), - > .btn-group:not(:last-child) > .btn { - @include border-end-radius(0); - } - - // The left radius should be 0 if the button is: - // - the "third or more" child - // - the second child and the previous element isn't `.btn-check` (making it the first child visually) - // - part of a btn-group which isn't the first child - > .btn:nth-child(n + 3), - > :not(.btn-check) + .btn, - > .btn-group:not(:first-child) > .btn { - @include border-start-radius(0); - } -} - -// Sizing -// -// Remix the default button sizing classes into new ones for easier manipulation. - -.btn-group-sm > .btn { @extend .btn-sm; } -.btn-group-lg > .btn { @extend .btn-lg; } - - -// -// Split button dropdowns -// - -.dropdown-toggle-split { - padding-right: $btn-padding-x * .75; - padding-left: $btn-padding-x * .75; - - &::after, - .dropup &::after, - .dropend &::after { - margin-left: 0; - } - - .dropstart &::before { - margin-right: 0; - } -} - -.btn-sm + .dropdown-toggle-split { - padding-right: $btn-padding-x-sm * .75; - padding-left: $btn-padding-x-sm * .75; -} - -.btn-lg + .dropdown-toggle-split { - padding-right: $btn-padding-x-lg * .75; - padding-left: $btn-padding-x-lg * .75; -} - - -// The clickable button for toggling the menu -// Set the same inset shadow as the :active state -.btn-group.show .dropdown-toggle { - @include box-shadow($btn-active-box-shadow); - - // Show no shadow for `.btn-link` since it has no other button styles. - &.btn-link { - @include box-shadow(none); - } -} - - -// -// Vertical button groups -// - -.btn-group-vertical { - flex-direction: column; - align-items: flex-start; - justify-content: center; - - > .btn, - > .btn-group { - width: 100%; - } - - > .btn:not(:first-child), - > .btn-group:not(:first-child) { - margin-top: -$btn-border-width; - } - - // Reset rounded corners - > .btn:not(:last-child):not(.dropdown-toggle), - > .btn-group:not(:last-child) > .btn { - @include border-bottom-radius(0); - } - - > .btn ~ .btn, - > .btn-group:not(:first-child) > .btn { - @include border-top-radius(0); - } -} diff --git a/src/assets/styles/bootstrap/_buttons.scss b/src/assets/styles/bootstrap/_buttons.scss deleted file mode 100644 index 3c2cba9..0000000 --- a/src/assets/styles/bootstrap/_buttons.scss +++ /dev/null @@ -1,116 +0,0 @@ -// -// Base styles -// - -.btn { - display: inline-block; - font-family: $btn-font-family; - font-weight: $btn-font-weight; - line-height: $btn-line-height; - color: $body-color; - text-align: center; - text-decoration: if($link-decoration == none, null, none); - white-space: $btn-white-space; - vertical-align: middle; - cursor: if($enable-button-pointers, pointer, null); - user-select: none; - background-color: transparent; - border: $btn-border-width solid transparent; - @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius); - @include transition($btn-transition); - - &:hover { - color: $body-color; - text-decoration: if($link-hover-decoration == underline, none, null); - } - - .btn-check:focus + &, - &:focus { - outline: 0; - box-shadow: $btn-focus-box-shadow; - } - - .btn-check:checked + &, - .btn-check:active + &, - &:active, - &.active { - @include box-shadow($btn-active-box-shadow); - - &:focus { - @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow); - } - } - - &:disabled, - &.disabled, - fieldset:disabled & { - pointer-events: none; - opacity: $btn-disabled-opacity; - @include box-shadow(none); - } -} - - -// -// Alternate buttons -// - -// scss-docs-start btn-variant-loops -@each $color, $value in $theme-colors { - .btn-#{$color} { - @include button-variant($value, $value); - } -} - -@each $color, $value in $theme-colors { - .btn-outline-#{$color} { - @include button-outline-variant($value); - } -} -// scss-docs-end btn-variant-loops - - -// -// Link buttons -// - -// Make a button look and behave like a link -.btn-link { - font-weight: $font-weight-normal; - color: $btn-link-color; - text-decoration: $link-decoration; - box-shadow: none !important; - - &:active { - color: $btn-link-color !important; - } - - &:hover { - color: $btn-link-hover-color; - text-decoration: $link-hover-decoration; - } - - &:focus { - text-decoration: $link-hover-decoration; - } - - &:disabled, - &.disabled { - color: $btn-link-disabled-color; - } - - // No need for an active state here -} - - -// -// Button Sizes -// - -.btn-lg { - @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg); -} - -.btn-sm { - @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm); -} diff --git a/src/assets/styles/bootstrap/_card.scss b/src/assets/styles/bootstrap/_card.scss deleted file mode 100644 index 22890f5..0000000 --- a/src/assets/styles/bootstrap/_card.scss +++ /dev/null @@ -1,216 +0,0 @@ -// -// Base styles -// - -.card { - position: relative; - display: flex; - flex-direction: column; - min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106 - height: $card-height; - word-wrap: break-word; - background-color: $card-bg; - background-clip: border-box; - border: $card-border-width solid $card-border-color; - @include border-radius($card-border-radius); - @include box-shadow($card-box-shadow); - - > hr { - margin-right: 0; - margin-left: 0; - } - - > .list-group { - border-top: inherit; - border-bottom: inherit; - - &:first-child { - border-top-width: 0; - @include border-top-radius($card-inner-border-radius); - } - - &:last-child { - border-bottom-width: 0; - @include border-bottom-radius($card-inner-border-radius); - } - } - - // Due to specificity of the above selector (`.card > .list-group`), we must - // use a child selector here to prevent double borders. - > .card-header + .list-group, - > .list-group + .card-footer { - border-top: 0; - } -} - -.card-body { - // Enable `flex-grow: 1` for decks and groups so that card blocks take up - // as much space as possible, ensuring footers are aligned to the bottom. - flex: 1 1 auto; - padding: $card-spacer-y $card-spacer-x; - color: $card-color; -} - -.card-title { - margin-bottom: $card-title-spacer-y; -} - -.card-subtitle { - margin-top: -$card-title-spacer-y * .5; - margin-bottom: 0; -} - -.card-text:last-child { - margin-bottom: 0; -} - -.card-link { - &:hover { - text-decoration: if($link-hover-decoration == underline, none, null); - } - - + .card-link { - margin-left: $card-spacer-x; - } -} - -// -// Optional textual caps -// - -.card-header { - padding: $card-cap-padding-y $card-cap-padding-x; - margin-bottom: 0; // Removes the default margin-bottom of - color: $card-cap-color; - background-color: $card-cap-bg; - border-bottom: $card-border-width solid $card-border-color; - - &:first-child { - @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0); - } -} - -.card-footer { - padding: $card-cap-padding-y $card-cap-padding-x; - color: $card-cap-color; - background-color: $card-cap-bg; - border-top: $card-border-width solid $card-border-color; - - &:last-child { - @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius); - } -} - - -// -// Header navs -// - -.card-header-tabs { - margin-right: -$card-cap-padding-x * .5; - margin-bottom: -$card-cap-padding-y; - margin-left: -$card-cap-padding-x * .5; - border-bottom: 0; - - @if $nav-tabs-link-active-bg != $card-bg { - .nav-link.active { - background-color: $card-bg; - border-bottom-color: $card-bg; - } - } -} - -.card-header-pills { - margin-right: -$card-cap-padding-x * .5; - margin-left: -$card-cap-padding-x * .5; -} - -// Card image -.card-img-overlay { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - padding: $card-img-overlay-padding; - @include border-radius($card-inner-border-radius); -} - -.card-img, -.card-img-top, -.card-img-bottom { - width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch -} - -.card-img, -.card-img-top { - @include border-top-radius($card-inner-border-radius); -} - -.card-img, -.card-img-bottom { - @include border-bottom-radius($card-inner-border-radius); -} - - -// -// Card groups -// - -.card-group { - // The child selector allows nested `.card` within `.card-group` - // to display properly. - > .card { - margin-bottom: $card-group-margin; - } - - @include media-breakpoint-up(sm) { - display: flex; - flex-flow: row wrap; - // The child selector allows nested `.card` within `.card-group` - // to display properly. - > .card { - // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4 - flex: 1 0 0%; - margin-bottom: 0; - - + .card { - margin-left: 0; - border-left: 0; - } - - // Handle rounded corners - @if $enable-rounded { - &:not(:last-child) { - @include border-end-radius(0); - - .card-img-top, - .card-header { - // stylelint-disable-next-line property-disallowed-list - border-top-right-radius: 0; - } - .card-img-bottom, - .card-footer { - // stylelint-disable-next-line property-disallowed-list - border-bottom-right-radius: 0; - } - } - - &:not(:first-child) { - @include border-start-radius(0); - - .card-img-top, - .card-header { - // stylelint-disable-next-line property-disallowed-list - border-top-left-radius: 0; - } - .card-img-bottom, - .card-footer { - // stylelint-disable-next-line property-disallowed-list - border-bottom-left-radius: 0; - } - } - } - } - } -} diff --git a/src/assets/styles/bootstrap/_carousel.scss b/src/assets/styles/bootstrap/_carousel.scss deleted file mode 100644 index 3d8fb15..0000000 --- a/src/assets/styles/bootstrap/_carousel.scss +++ /dev/null @@ -1,229 +0,0 @@ -// Notes on the classes: -// -// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically) -// even when their scroll action started on a carousel, but for compatibility (with Firefox) -// we're preventing all actions instead -// 2. The .carousel-item-start and .carousel-item-end is used to indicate where -// the active slide is heading. -// 3. .active.carousel-item is the current slide. -// 4. .active.carousel-item-start and .active.carousel-item-end is the current -// slide in its in-transition state. Only one of these occurs at a time. -// 5. .carousel-item-next.carousel-item-start and .carousel-item-prev.carousel-item-end -// is the upcoming slide in transition. - -.carousel { - position: relative; -} - -.carousel.pointer-event { - touch-action: pan-y; -} - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden; - @include clearfix(); -} - -.carousel-item { - position: relative; - display: none; - float: left; - width: 100%; - margin-right: -100%; - backface-visibility: hidden; - @include transition($carousel-transition); -} - -.carousel-item.active, -.carousel-item-next, -.carousel-item-prev { - display: block; -} - -/* rtl:begin:ignore */ -.carousel-item-next:not(.carousel-item-start), -.active.carousel-item-end { - transform: translateX(100%); -} - -.carousel-item-prev:not(.carousel-item-end), -.active.carousel-item-start { - transform: translateX(-100%); -} - -/* rtl:end:ignore */ - - -// -// Alternate transitions -// - -.carousel-fade { - .carousel-item { - opacity: 0; - transition-property: opacity; - transform: none; - } - - .carousel-item.active, - .carousel-item-next.carousel-item-start, - .carousel-item-prev.carousel-item-end { - z-index: 1; - opacity: 1; - } - - .active.carousel-item-start, - .active.carousel-item-end { - z-index: 0; - opacity: 0; - @include transition(opacity 0s $carousel-transition-duration); - } -} - - -// -// Left/right controls for nav -// - -.carousel-control-prev, -.carousel-control-next { - position: absolute; - top: 0; - bottom: 0; - z-index: 1; - // Use flex for alignment (1-3) - display: flex; // 1. allow flex styles - align-items: center; // 2. vertically center contents - justify-content: center; // 3. horizontally center contents - width: $carousel-control-width; - padding: 0; - color: $carousel-control-color; - text-align: center; - background: none; - border: 0; - opacity: $carousel-control-opacity; - @include transition($carousel-control-transition); - - // Hover/focus state - &:hover, - &:focus { - color: $carousel-control-color; - text-decoration: none; - outline: 0; - opacity: $carousel-control-hover-opacity; - } -} -.carousel-control-prev { - left: 0; - background-image: if($enable-gradients, linear-gradient(90deg, rgba($black, .25), rgba($black, .001)), null); -} -.carousel-control-next { - right: 0; - background-image: if($enable-gradients, linear-gradient(270deg, rgba($black, .25), rgba($black, .001)), null); -} - -// Icons for within -.carousel-control-prev-icon, -.carousel-control-next-icon { - display: inline-block; - width: $carousel-control-icon-width; - height: $carousel-control-icon-width; - background-repeat: no-repeat; - background-position: 50%; - background-size: 100% 100%; -} - -/* rtl:options: { - "autoRename": true, - "stringMap":[ { - "name" : "prev-next", - "search" : "prev", - "replace" : "next" - } ] -} */ -.carousel-control-prev-icon { - background-image: escape-svg($carousel-control-prev-icon-bg); -} -.carousel-control-next-icon { - background-image: escape-svg($carousel-control-next-icon-bg); -} - -// Optional indicator pips/controls -// -// Add a container (such as a list) with the following class and add an item (ideally a focusable control, -// like a button) with data-bs-target for each slide your carousel holds. - -.carousel-indicators { - position: absolute; - right: 0; - bottom: 0; - left: 0; - z-index: 2; - display: flex; - justify-content: center; - padding: 0; - // Use the .carousel-control's width as margin so we don't overlay those - margin-right: $carousel-control-width; - margin-bottom: 1rem; - margin-left: $carousel-control-width; - list-style: none; - - [data-bs-target] { - box-sizing: content-box; - flex: 0 1 auto; - width: $carousel-indicator-width; - height: $carousel-indicator-height; - padding: 0; - margin-right: $carousel-indicator-spacer; - margin-left: $carousel-indicator-spacer; - text-indent: -999px; - cursor: pointer; - background-color: $carousel-indicator-active-bg; - background-clip: padding-box; - border: 0; - // Use transparent borders to increase the hit area by 10px on top and bottom. - border-top: $carousel-indicator-hit-area-height solid transparent; - border-bottom: $carousel-indicator-hit-area-height solid transparent; - opacity: $carousel-indicator-opacity; - @include transition($carousel-indicator-transition); - } - - .active { - opacity: $carousel-indicator-active-opacity; - } -} - - -// Optional captions -// -// - -.carousel-caption { - position: absolute; - right: (100% - $carousel-caption-width) * .5; - bottom: $carousel-caption-spacer; - left: (100% - $carousel-caption-width) * .5; - padding-top: $carousel-caption-padding-y; - padding-bottom: $carousel-caption-padding-y; - color: $carousel-caption-color; - text-align: center; -} - -// Dark mode carousel - -.carousel-dark { - .carousel-control-prev-icon, - .carousel-control-next-icon { - filter: $carousel-dark-control-icon-filter; - } - - .carousel-indicators [data-bs-target] { - background-color: $carousel-dark-indicator-active-bg; - } - - .carousel-caption { - color: $carousel-dark-caption-color; - } -} diff --git a/src/assets/styles/bootstrap/_close.scss b/src/assets/styles/bootstrap/_close.scss deleted file mode 100644 index 32a0f68..0000000 --- a/src/assets/styles/bootstrap/_close.scss +++ /dev/null @@ -1,40 +0,0 @@ -// transparent background and border properties included for button version. -// iOS requires the button element instead of an anchor tag. -// If you want the anchor version, it requires `href="#"`. -// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile - -.btn-close { - box-sizing: content-box; - width: $btn-close-width; - height: $btn-close-height; - padding: $btn-close-padding-y $btn-close-padding-x; - color: $btn-close-color; - background: transparent escape-svg($btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements - border: 0; // for button elements - @include border-radius(); - opacity: $btn-close-opacity; - - // Override 's hover style - &:hover { - color: $btn-close-color; - text-decoration: none; - opacity: $btn-close-hover-opacity; - } - - &:focus { - outline: 0; - box-shadow: $btn-close-focus-shadow; - opacity: $btn-close-focus-opacity; - } - - &:disabled, - &.disabled { - pointer-events: none; - user-select: none; - opacity: $btn-close-disabled-opacity; - } -} - -.btn-close-white { - filter: $btn-close-white-filter; -} diff --git a/src/assets/styles/bootstrap/_containers.scss b/src/assets/styles/bootstrap/_containers.scss deleted file mode 100644 index f88f1e5..0000000 --- a/src/assets/styles/bootstrap/_containers.scss +++ /dev/null @@ -1,41 +0,0 @@ -// Container widths -// -// Set the container width, and override it for fixed navbars in media queries. - -@if $enable-grid-classes { - // Single container class with breakpoint max-widths - .container, - // 100% wide container at all breakpoints - .container-fluid { - @include make-container(); - } - - // Responsive containers that are 100% wide until a breakpoint - @each $breakpoint, $container-max-width in $container-max-widths { - .container-#{$breakpoint} { - @extend .container-fluid; - } - - @include media-breakpoint-up($breakpoint, $grid-breakpoints) { - %responsive-container-#{$breakpoint} { - max-width: $container-max-width; - } - - // Extend each breakpoint which is smaller or equal to the current breakpoint - $extend-breakpoint: true; - - @each $name, $width in $grid-breakpoints { - @if ($extend-breakpoint) { - .container#{breakpoint-infix($name, $grid-breakpoints)} { - @extend %responsive-container-#{$breakpoint}; - } - - // Once the current breakpoint is reached, stop extending - @if ($breakpoint == $name) { - $extend-breakpoint: false; - } - } - } - } - } -} diff --git a/src/assets/styles/bootstrap/_dropdown.scss b/src/assets/styles/bootstrap/_dropdown.scss deleted file mode 100644 index adc1143..0000000 --- a/src/assets/styles/bootstrap/_dropdown.scss +++ /dev/null @@ -1,240 +0,0 @@ -// The dropdown wrapper (`

`) -.dropup, -.dropend, -.dropdown, -.dropstart { - position: relative; -} - -.dropdown-toggle { - white-space: nowrap; - - // Generate the caret automatically - @include caret(); -} - -// The dropdown menu -.dropdown-menu { - position: absolute; - z-index: $zindex-dropdown; - display: none; // none by default, but block on "open" of the menu - min-width: $dropdown-min-width; - padding: $dropdown-padding-y $dropdown-padding-x; - margin: 0; // Override default margin of ul - @include font-size($dropdown-font-size); - color: $dropdown-color; - text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) - list-style: none; - background-color: $dropdown-bg; - background-clip: padding-box; - border: $dropdown-border-width solid $dropdown-border-color; - @include border-radius($dropdown-border-radius); - @include box-shadow($dropdown-box-shadow); - - &[data-bs-popper] { - top: 100%; - left: 0; - margin-top: $dropdown-spacer; - } -} - -// scss-docs-start responsive-breakpoints -// We deliberately hardcode the `bs-` prefix because we check -// this custom property in JS to determine Popper's positioning - -@each $breakpoint in map-keys($grid-breakpoints) { - @include media-breakpoint-up($breakpoint) { - $infix: breakpoint-infix($breakpoint, $grid-breakpoints); - - .dropdown-menu#{$infix}-start { - --bs-position: start; - - &[data-bs-popper] { - right: auto; - left: 0; - } - } - - .dropdown-menu#{$infix}-end { - --bs-position: end; - - &[data-bs-popper] { - right: 0; - left: auto; - } - } - } -} -// scss-docs-end responsive-breakpoints - -// Allow for dropdowns to go bottom up (aka, dropup-menu) -// Just add .dropup after the standard .dropdown class and you're set. -.dropup { - .dropdown-menu[data-bs-popper] { - top: auto; - bottom: 100%; - margin-top: 0; - margin-bottom: $dropdown-spacer; - } - - .dropdown-toggle { - @include caret(up); - } -} - -.dropend { - .dropdown-menu[data-bs-popper] { - top: 0; - right: auto; - left: 100%; - margin-top: 0; - margin-left: $dropdown-spacer; - } - - .dropdown-toggle { - @include caret(end); - &::after { - vertical-align: 0; - } - } -} - -.dropstart { - .dropdown-menu[data-bs-popper] { - top: 0; - right: 100%; - left: auto; - margin-top: 0; - margin-right: $dropdown-spacer; - } - - .dropdown-toggle { - @include caret(start); - &::before { - vertical-align: 0; - } - } -} - - -// Dividers (basically an `
`) within the dropdown -.dropdown-divider { - height: 0; - margin: $dropdown-divider-margin-y 0; - overflow: hidden; - border-top: 1px solid $dropdown-divider-bg; -} - -// Links, buttons, and more within the dropdown menu -// -// `
- -
- - - ); -}; diff --git a/src/common/layout/LayoutNotificationAlertView.tsx b/src/common/layout/LayoutNotificationAlertView.tsx deleted file mode 100644 index 8db771a..0000000 --- a/src/common/layout/LayoutNotificationAlertView.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { FC, useMemo } from 'react'; -import { NotificationAlertType } from '../../api'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroCardViewProps } from '../card'; - -export interface LayoutNotificationAlertViewProps extends NitroCardViewProps -{ - title?: string; - type?: string; - onClose: () => void; -} - -export const LayoutNotificationAlertView: FC = props => -{ - const { title = '', onClose = null, classNames = [], children = null,type = NotificationAlertType.DEFAULT, ...rest } = props; - - const getClassNames = useMemo(() => - { - const newClassNames: string[] = [ 'nitro-alert' ]; - - newClassNames.push('nitro-alert-' + type); - - if(classNames.length) newClassNames.push(...classNames); - - return newClassNames; - }, [ classNames, type ]); - - return ( - - - - { children } - - - ); -} diff --git a/src/common/layout/LayoutNotificationBubbleView.tsx b/src/common/layout/LayoutNotificationBubbleView.tsx deleted file mode 100644 index 256837d..0000000 --- a/src/common/layout/LayoutNotificationBubbleView.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { FC, useEffect, useMemo, useState } from 'react'; -import { Flex, FlexProps } from '../Flex'; -import { TransitionAnimation, TransitionAnimationTypes } from '../transitions'; - -export interface LayoutNotificationBubbleViewProps extends FlexProps -{ - fadesOut?: boolean; - timeoutMs?: number; - onClose: () => void; -} - -export const LayoutNotificationBubbleView: FC = props => -{ - const { fadesOut = true, timeoutMs = 8000, onClose = null, overflow = 'hidden', classNames = [], ...rest } = props; - const [ isVisible, setIsVisible ] = useState(false); - - const getClassNames = useMemo(() => - { - const newClassNames: string[] = [ 'nitro-notification-bubble', 'rounded' ]; - - if(classNames.length) newClassNames.push(...classNames); - - return newClassNames; - }, [ classNames ]); - - useEffect(() => - { - setIsVisible(true); - - return () => setIsVisible(false); - }, []); - - useEffect(() => - { - if(!fadesOut) return; - - const timeout = setTimeout(() => - { - setIsVisible(false); - - setTimeout(() => onClose(), 300); - }, timeoutMs); - - return () => clearTimeout(timeout); - }, [ fadesOut, timeoutMs, onClose ]); - - return ( - - - - ); -} diff --git a/src/common/layout/LayoutPetImageView.tsx b/src/common/layout/LayoutPetImageView.tsx deleted file mode 100644 index e052ddf..0000000 --- a/src/common/layout/LayoutPetImageView.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import { GetRoomEngine, IPetCustomPart, PetFigureData, TextureUtils, Vector3d } from '@nitrots/nitro-renderer'; -import { CSSProperties, FC, useEffect, useMemo, useRef, useState } from 'react'; -import { Base, BaseProps } from '../Base'; - -interface LayoutPetImageViewProps extends BaseProps -{ - figure?: string; - typeId?: number; - paletteId?: number; - petColor?: number; - customParts?: IPetCustomPart[]; - posture?: string; - headOnly?: boolean; - direction?: number; - scale?: number; -} - -export const LayoutPetImageView: FC = props => -{ - const { figure = '', typeId = -1, paletteId = -1, petColor = 0xFFFFFF, customParts = [], posture = 'std', headOnly = false, direction = 0, scale = 1, style = {}, ...rest } = props; - const [ petUrl, setPetUrl ] = useState(null); - const [ width, setWidth ] = useState(0); - const [ height, setHeight ] = useState(0); - const isDisposed = useRef(false); - - const getStyle = useMemo(() => - { - let newStyle: CSSProperties = {}; - - if(petUrl && petUrl.length) newStyle.backgroundImage = `url(${ petUrl })`; - - if(scale !== 1) - { - newStyle.transform = `scale(${ scale })`; - - if(!(scale % 1)) newStyle.imageRendering = 'pixelated'; - } - - newStyle.width = width; - newStyle.height = height; - - if(Object.keys(style).length) newStyle = { ...newStyle, ...style }; - - return newStyle; - }, [ petUrl, scale, style, width, height ]); - - useEffect(() => - { - let url = null; - - let petTypeId = typeId; - let petPaletteId = paletteId; - let petColor1 = petColor; - let petCustomParts: IPetCustomPart[] = customParts; - let petHeadOnly = headOnly; - - if(figure && figure.length) - { - const petFigureData = new PetFigureData(figure); - - petTypeId = petFigureData.typeId; - petPaletteId = petFigureData.paletteId; - petColor1 = petFigureData.color; - petCustomParts = petFigureData.customParts; - } - - if(petTypeId === 16) petHeadOnly = false; - - const imageResult = GetRoomEngine().getRoomObjectPetImage(petTypeId, petPaletteId, petColor1, new Vector3d((direction * 45)), 64, { - imageReady: async (id, texture, image) => - { - if(isDisposed.current) return; - - if(image) - { - setPetUrl(image.src); - setWidth(image.width); - setHeight(image.height); - } - - else if(texture) - { - setPetUrl(await TextureUtils.generateImageUrl(texture)); - setWidth(texture.width); - setHeight(texture.height); - } - }, - imageFailed: (id) => - { - - } - }, petHeadOnly, 0, petCustomParts, posture); - - if(imageResult) - { - (async () => - { - const image = await imageResult.getImage(); - - if(image) - { - setPetUrl(image.src); - setWidth(image.width); - setHeight(image.height); - } - })(); - } - }, [ figure, typeId, paletteId, petColor, customParts, posture, headOnly, direction ]); - - useEffect(() => - { - isDisposed.current = false; - - return () => - { - isDisposed.current = true; - } - }, []); - - const url = `url('${ petUrl }')`; - - return ; -} diff --git a/src/common/layout/LayoutPrizeProductImageView.tsx b/src/common/layout/LayoutPrizeProductImageView.tsx deleted file mode 100644 index 206c7a8..0000000 --- a/src/common/layout/LayoutPrizeProductImageView.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { FC } from 'react'; -import { ProductTypeEnum } from '../../api'; -import { LayoutBadgeImageView } from './LayoutBadgeImageView'; -import { LayoutCurrencyIcon } from './LayoutCurrencyIcon'; -import { LayoutFurniImageView } from './LayoutFurniImageView'; - -interface LayoutPrizeProductImageViewProps -{ - productType: string; - classId: number; - extraParam?: string; -} - -export const LayoutPrizeProductImageView: FC = props => -{ - const { productType = ProductTypeEnum.FLOOR, classId = -1, extraParam = undefined } = props; - - switch(productType) - { - case ProductTypeEnum.WALL: - case ProductTypeEnum.FLOOR: - return - case ProductTypeEnum.BADGE: - return - case ProductTypeEnum.HABBO_CLUB: - return - } - - return null; -} diff --git a/src/common/layout/LayoutProgressBar.tsx b/src/common/layout/LayoutProgressBar.tsx deleted file mode 100644 index 9b5fb96..0000000 --- a/src/common/layout/LayoutProgressBar.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { FC, useMemo } from 'react'; -import { Base } from '../Base'; -import { Column, ColumnProps } from '../Column'; -import { Flex } from '../Flex'; - -interface LayoutProgressBarProps extends ColumnProps -{ - text?: string; - progress: number; - maxProgress?: number; -} - -export const LayoutProgressBar: FC = props => -{ - const { text = '', progress = 0, maxProgress = 100, position = 'relative', justifyContent = 'center', classNames = [], children = null, ...rest } = props; - - const getClassNames = useMemo(() => - { - const newClassNames: string[] = [ 'nitro-progress-bar', 'text-white' ]; - - if(classNames.length) newClassNames.push(...classNames); - - return newClassNames; - }, [ classNames ]); - - return ( - - { text && (text.length > 0) && - { text } } - - { children } - - ); -} diff --git a/src/common/layout/LayoutRarityLevelView.tsx b/src/common/layout/LayoutRarityLevelView.tsx deleted file mode 100644 index 6fd84d2..0000000 --- a/src/common/layout/LayoutRarityLevelView.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { FC, useMemo } from 'react'; -import { Base, BaseProps } from '../Base'; - -interface LayoutRarityLevelViewProps extends BaseProps -{ - level: number; -} - -export const LayoutRarityLevelView: FC = props => -{ - const { level = 0, classNames = [], children = null, ...rest } = props; - - const getClassNames = useMemo(() => - { - const newClassNames: string[] = [ 'nitro-rarity-level' ]; - - if(classNames.length) newClassNames.push(...classNames); - - return newClassNames; - }, [ classNames ]); - - return ( - -
{ level }
- { children } - - ); -} diff --git a/src/common/layout/LayoutRoomObjectImageView.tsx b/src/common/layout/LayoutRoomObjectImageView.tsx deleted file mode 100644 index cc668f8..0000000 --- a/src/common/layout/LayoutRoomObjectImageView.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { GetRoomEngine, TextureUtils, Vector3d } from '@nitrots/nitro-renderer'; -import { CSSProperties, FC, useEffect, useMemo, useState } from 'react'; -import { Base, BaseProps } from '../Base'; - -interface LayoutRoomObjectImageViewProps extends BaseProps -{ - roomId: number; - objectId: number; - category: number; - direction?: number; - scale?: number; -} - -export const LayoutRoomObjectImageView: FC = props => -{ - const { roomId = -1, objectId = 1, category = -1, direction = 2, scale = 1, style = {}, ...rest } = props; - const [ imageElement, setImageElement ] = useState(null); - - const getStyle = useMemo(() => - { - let newStyle: CSSProperties = {}; - - if(imageElement?.src?.length) - { - newStyle.backgroundImage = `url('${ imageElement.src }')`; - newStyle.width = imageElement.width; - newStyle.height = imageElement.height; - } - - if(scale !== 1) - { - newStyle.transform = `scale(${ scale })`; - - if(!(scale % 1)) newStyle.imageRendering = 'pixelated'; - } - - if(Object.keys(style).length) newStyle = { ...newStyle, ...style }; - - return newStyle; - }, [ imageElement, scale, style ]); - - useEffect(() => - { - const imageResult = GetRoomEngine().getRoomObjectImage(roomId, objectId, category, new Vector3d(direction * 45), 64, { - imageReady: async (id, texture, image) => setImageElement(await TextureUtils.generateImage(texture)), - imageFailed: null - }); - - // needs (roomObjectImage.data.width > 140) || (roomObjectImage.data.height > 200) scale 1 - - if(!imageResult) return; - - (async () => setImageElement(await TextureUtils.generateImage(imageResult.data)))(); - }, [ roomId, objectId, category, direction, scale ]); - - if(!imageElement) return null; - - return ; -} diff --git a/src/common/layout/LayoutRoomPreviewerView.tsx b/src/common/layout/LayoutRoomPreviewerView.tsx deleted file mode 100644 index e6a005b..0000000 --- a/src/common/layout/LayoutRoomPreviewerView.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { GetRenderer, GetTicker, NitroTicker, RoomPreviewer, TextureUtils } from '@nitrots/nitro-renderer'; -import { FC, MouseEvent, ReactNode, useEffect, useRef } from 'react'; - -export interface LayoutRoomPreviewerViewProps -{ - roomPreviewer: RoomPreviewer; - height?: number; - children?: ReactNode; -} - -export const LayoutRoomPreviewerView: FC = props => -{ - const { roomPreviewer = null, height = 0, children = null } = props; - const elementRef = useRef(); - - const onClick = (event: MouseEvent) => - { - if(!roomPreviewer) return; - - if(event.shiftKey) roomPreviewer.changeRoomObjectDirection(); - else roomPreviewer.changeRoomObjectState(); - } - - useEffect(() => - { - if(!elementRef) return; - - const width = elementRef.current.parentElement.clientWidth; - const texture = TextureUtils.createRenderTexture(width, height); - - const update = async (ticker: NitroTicker) => - { - if(!roomPreviewer || !elementRef.current) return; - - roomPreviewer.updatePreviewRoomView(); - - const renderingCanvas = roomPreviewer.getRenderingCanvas(); - - if(!renderingCanvas.canvasUpdated) return; - - GetRenderer().render({ - target: texture, - container: renderingCanvas.master, - clear: true - }); - - let canvas = GetRenderer().texture.generateCanvas(texture); - const base64 = canvas.toDataURL('image/png'); - - canvas = null; - - elementRef.current.style.backgroundImage = `url(${ base64 })`; - } - - GetTicker().add(update); - - const resizeObserver = new ResizeObserver(() => - { - if(!roomPreviewer || !elementRef.current) return; - - const width = elementRef.current.parentElement.offsetWidth; - - roomPreviewer.modifyRoomCanvas(width, height); - - update(GetTicker()); - }); - - roomPreviewer.getRoomCanvas(width, height); - - resizeObserver.observe(elementRef.current); - - return () => - { - GetTicker().remove(update); - - resizeObserver.disconnect(); - - texture.destroy(true); - } - }, [ roomPreviewer, elementRef, height ]); - - return ( -
-
- { children } -
- ); -} diff --git a/src/common/layout/LayoutRoomThumbnailView.tsx b/src/common/layout/LayoutRoomThumbnailView.tsx deleted file mode 100644 index 144c1f2..0000000 --- a/src/common/layout/LayoutRoomThumbnailView.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { FC, useMemo } from 'react'; -import { GetConfigurationValue } from '../../api'; -import { Base, BaseProps } from '../Base'; - -export interface LayoutRoomThumbnailViewProps extends BaseProps -{ - roomId?: number; - customUrl?: string; -} - -export const LayoutRoomThumbnailView: FC = props => -{ - const { roomId = -1, customUrl = null, shrink = true, overflow = 'hidden', classNames = [], children = null, ...rest } = props; - - const getClassNames = useMemo(() => - { - const newClassNames: string[] = [ 'room-thumbnail', 'rounded', 'border' ]; - - if(classNames.length) newClassNames.push(...classNames); - - return newClassNames; - }, [ classNames ]); - - const getImageUrl = useMemo(() => - { - if(customUrl && customUrl.length) return (GetConfigurationValue('image.library.url') + customUrl); - - return (GetConfigurationValue('thumbnails.url').replace('%thumbnail%', roomId.toString())); - }, [ customUrl, roomId ]); - - return ( - - { getImageUrl && } - { children } - - ); -} diff --git a/src/common/layout/LayoutTrophyView.tsx b/src/common/layout/LayoutTrophyView.tsx deleted file mode 100644 index a65cd95..0000000 --- a/src/common/layout/LayoutTrophyView.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText } from '../../api'; -import { Base } from '../Base'; -import { Column } from '../Column'; -import { Flex } from '../Flex'; -import { Text } from '../Text'; -import { DraggableWindow } from '../draggable-window'; - -interface LayoutTrophyViewProps -{ - color: string; - message: string; - date: string; - senderName: string; - customTitle?: string; - onCloseClick: () => void; -} - -export const LayoutTrophyView: FC = props => -{ - const { color = '', message = '', date = '', senderName = '', customTitle = null, onCloseClick = null } = props; - - return ( - - - - - { LocalizeText('widget.furni.trophy.title') } - - - { customTitle && - { customTitle } } - { message } - - - { date } - { senderName } - - - - ); -} diff --git a/src/common/layout/UserProfileIconView.tsx b/src/common/layout/UserProfileIconView.tsx deleted file mode 100644 index d31fa66..0000000 --- a/src/common/layout/UserProfileIconView.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { FC, useMemo } from 'react'; -import { GetUserProfile } from '../../api'; -import { Base, BaseProps } from '../Base'; - -export interface UserProfileIconViewProps extends BaseProps -{ - userId?: number; - userName?: string; -} - -export const UserProfileIconView: FC = props => -{ - const { userId = 0, userName = null, classNames = [], pointer = true, children = null, ...rest } = props; - - const getClassNames = useMemo(() => - { - const newClassNames: string[] = [ 'nitro-friends-spritesheet', 'icon-profile-sm' ]; - - if(classNames.length) newClassNames.push(...classNames); - - return newClassNames; - }, [ classNames ]); - - return ( - GetUserProfile(userId) } { ... rest }> - { children } - - ); -} diff --git a/src/common/layout/index.ts b/src/common/layout/index.ts deleted file mode 100644 index cbb0568..0000000 --- a/src/common/layout/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -export * from './LayoutAvatarImageView'; -export * from './LayoutBackgroundImage'; -export * from './LayoutBadgeImageView'; -export * from './LayoutCounterTimeView'; -export * from './LayoutCurrencyIcon'; -export * from './LayoutFurniIconImageView'; -export * from './LayoutFurniImageView'; -export * from './LayoutGiftTagView'; -export * from './LayoutGridItem'; -export * from './LayoutImage'; -export * from './LayoutItemCountView'; -export * from './LayoutLoadingSpinnerView'; -export * from './LayoutMiniCameraView'; -export * from './LayoutNotificationAlertView'; -export * from './LayoutNotificationBubbleView'; -export * from './LayoutPetImageView'; -export * from './LayoutProgressBar'; -export * from './LayoutRarityLevelView'; -export * from './LayoutRoomObjectImageView'; -export * from './LayoutRoomPreviewerView'; -export * from './LayoutRoomThumbnailView'; -export * from './LayoutTrophyView'; -export * from './UserProfileIconView'; -export * from './limited-edition'; diff --git a/src/common/layout/limited-edition/LayoutLimitedEditionCompactPlateView.tsx b/src/common/layout/limited-edition/LayoutLimitedEditionCompactPlateView.tsx deleted file mode 100644 index ee41c6c..0000000 --- a/src/common/layout/limited-edition/LayoutLimitedEditionCompactPlateView.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { FC, useMemo } from 'react'; -import { Base, BaseProps } from '../../Base'; -import { LayoutLimitedEditionStyledNumberView } from './LayoutLimitedEditionStyledNumberView'; - -interface LayoutLimitedEditionCompactPlateViewProps extends BaseProps -{ - uniqueNumber: number; - uniqueSeries: number; -} - -export const LayoutLimitedEditionCompactPlateView: FC = props => -{ - const { uniqueNumber = 0, uniqueSeries = 0, classNames = [], children = null, ...rest } = props; - - const getClassNames = useMemo(() => - { - const newClassNames: string[] = [ 'unique-compact-plate', 'z-index-1' ]; - - if(classNames.length) newClassNames.push(...classNames); - - return newClassNames; - }, [ classNames ]); - - return ( - -
- -
-
- -
- { children } - - ); -} diff --git a/src/common/layout/limited-edition/LayoutLimitedEditionCompletePlateView.tsx b/src/common/layout/limited-edition/LayoutLimitedEditionCompletePlateView.tsx deleted file mode 100644 index c83e230..0000000 --- a/src/common/layout/limited-edition/LayoutLimitedEditionCompletePlateView.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { FC, useMemo } from 'react'; -import { LocalizeText } from '../../../api'; -import { Base, BaseProps } from '../../Base'; -import { Column } from '../../Column'; -import { Flex } from '../../Flex'; -import { LayoutLimitedEditionStyledNumberView } from './LayoutLimitedEditionStyledNumberView'; - -interface LayoutLimitedEditionCompletePlateViewProps extends BaseProps -{ - uniqueLimitedItemsLeft: number; - uniqueLimitedSeriesSize: number; -} - -export const LayoutLimitedEditionCompletePlateView: FC = props => -{ - const { uniqueLimitedItemsLeft = 0, uniqueLimitedSeriesSize = 0, classNames = [], ...rest } = props; - - const getClassNames = useMemo(() => - { - const newClassNames: string[] = [ 'unique-complete-plate' ]; - - if(classNames.length) newClassNames.push(...classNames); - - return newClassNames; - }, [ classNames ]); - - return ( - - - - { LocalizeText('unique.items.left') } -
-
- - { LocalizeText('unique.items.number.sold') } -
-
-
- - ); -} diff --git a/src/common/layout/limited-edition/LayoutLimitedEditionStyledNumberView.tsx b/src/common/layout/limited-edition/LayoutLimitedEditionStyledNumberView.tsx deleted file mode 100644 index fe34ba4..0000000 --- a/src/common/layout/limited-edition/LayoutLimitedEditionStyledNumberView.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { FC } from 'react'; - -interface LayoutLimitedEditionStyledNumberViewProps -{ - value: number; -} - -export const LayoutLimitedEditionStyledNumberView: FC = props => -{ - const { value = 0 } = props; - const numbers = value.toString().split(''); - - return ( - <> - { numbers.map((number, index) => ) } - - ); -} diff --git a/src/common/layout/limited-edition/index.ts b/src/common/layout/limited-edition/index.ts deleted file mode 100644 index ee41cf9..0000000 --- a/src/common/layout/limited-edition/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './LayoutLimitedEditionCompactPlateView'; -export * from './LayoutLimitedEditionCompletePlateView'; -export * from './LayoutLimitedEditionStyledNumberView'; diff --git a/src/common/transitions/TransitionAnimation.tsx b/src/common/transitions/TransitionAnimation.tsx deleted file mode 100644 index 6eefd2d..0000000 --- a/src/common/transitions/TransitionAnimation.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { FC, ReactNode, useEffect, useState } from 'react'; -import { Transition } from 'react-transition-group'; -import { getTransitionAnimationStyle } from './TransitionAnimationStyles'; - -interface TransitionAnimationProps -{ - type: string; - inProp: boolean; - timeout?: number; - className?: string; - children?: ReactNode; -} - -export const TransitionAnimation: FC = props => -{ - const { type = null, inProp = false, timeout = 300, className = null, children = null } = props; - - const [ isChildrenVisible, setChildrenVisible ] = useState(false); - - useEffect(() => - { - let timeoutData: ReturnType = null; - - if(inProp) - { - setChildrenVisible(true); - } - else - { - timeoutData = setTimeout(() => - { - setChildrenVisible(false); - clearTimeout(timeout); - }, timeout); - } - - return () => - { - if(timeoutData) clearTimeout(timeoutData); - } - }, [ inProp, timeout ]); - - return ( - - { state => ( -
- { isChildrenVisible && children } -
- ) } -
- ); -} diff --git a/src/common/transitions/TransitionAnimationStyles.ts b/src/common/transitions/TransitionAnimationStyles.ts deleted file mode 100644 index 0d512d0..0000000 --- a/src/common/transitions/TransitionAnimationStyles.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { CSSProperties } from 'react'; -import { TransitionStatus } from 'react-transition-group'; -import { ENTERING, EXITING } from 'react-transition-group/Transition'; -import { TransitionAnimationTypes } from './TransitionAnimationTypes'; - -export function getTransitionAnimationStyle(type: string, transition: TransitionStatus, timeout: number = 300): Partial -{ - switch(type) - { - case TransitionAnimationTypes.BOUNCE: - switch(transition) - { - default: - return {} - case ENTERING: - return { - animationName: 'bounceIn', - animationDuration: `${ timeout }ms` - } - case EXITING: - return { - animationName: 'bounceOut', - animationDuration: `${ timeout }ms` - } - } - case TransitionAnimationTypes.SLIDE_LEFT: - switch(transition) - { - default: - return {} - case ENTERING: - return { - animationName: 'slideInLeft', - animationDuration: `${ timeout }ms` - } - case EXITING: - return { - animationName: 'slideOutLeft', - animationDuration: `${ timeout }ms` - } - } - case TransitionAnimationTypes.SLIDE_RIGHT: - switch(transition) - { - default: - return {} - case ENTERING: - return { - animationName: 'slideInRight', - animationDuration: `${ timeout }ms` - } - case EXITING: - return { - animationName: 'slideOutRight', - animationDuration: `${ timeout }ms` - } - } - case TransitionAnimationTypes.FLIP_X: - switch(transition) - { - default: - return {} - case ENTERING: - return { - animationName: 'flipInX', - animationDuration: `${ timeout }ms` - } - case EXITING: - return { - animationName: 'flipOutX', - animationDuration: `${ timeout }ms` - } - } - case TransitionAnimationTypes.FADE_UP: - switch(transition) - { - default: - return {} - case ENTERING: - return { - animationName: 'fadeInUp', - animationDuration: `${ timeout }ms` - } - case EXITING: - return { - animationName: 'fadeOutDown', - animationDuration: `${ timeout }ms` - } - } - case TransitionAnimationTypes.FADE_IN: - switch(transition) - { - default: - return {} - case ENTERING: - return { - animationName: 'fadeIn', - animationDuration: `${ timeout }ms` - } - case EXITING: - return { - animationName: 'fadeOut', - animationDuration: `${ timeout }ms` - } - } - case TransitionAnimationTypes.FADE_DOWN: - switch(transition) - { - default: - return {} - case ENTERING: - return { - animationName: 'fadeInDown', - animationDuration: `${ timeout }ms` - } - case EXITING: - return { - animationName: 'fadeOutUp', - animationDuration: `${ timeout }ms` - } - } - case TransitionAnimationTypes.HEAD_SHAKE: - switch(transition) - { - default: - return {} - case ENTERING: - return { - animationName: 'headShake', - animationDuration: `${ timeout }ms` - } - } - } - - return null; -} diff --git a/src/common/transitions/TransitionAnimationTypes.ts b/src/common/transitions/TransitionAnimationTypes.ts deleted file mode 100644 index 4ecc23b..0000000 --- a/src/common/transitions/TransitionAnimationTypes.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class TransitionAnimationTypes -{ - public static BOUNCE: string = 'bounce'; - public static SLIDE_LEFT: string = 'slideLeft'; - public static SLIDE_RIGHT: string = 'slideRight'; - public static FLIP_X: string = 'flipX'; - public static FADE_IN: string = 'fadeIn'; - public static FADE_DOWN: string = 'fadeDown'; - public static FADE_UP: string = 'fadeUp'; - public static HEAD_SHAKE: string = 'headShake'; -} diff --git a/src/common/transitions/index.ts b/src/common/transitions/index.ts deleted file mode 100644 index 283a005..0000000 --- a/src/common/transitions/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './TransitionAnimation'; -export * from './TransitionAnimationStyles'; -export * from './TransitionAnimationTypes'; diff --git a/src/common/types/AlignItemType.ts b/src/common/types/AlignItemType.ts deleted file mode 100644 index 5a61476..0000000 --- a/src/common/types/AlignItemType.ts +++ /dev/null @@ -1 +0,0 @@ -export type AlignItemType = 'start' | 'end' | 'center' | 'baseline' | 'stretch'; diff --git a/src/common/types/AlignSelfType.ts b/src/common/types/AlignSelfType.ts deleted file mode 100644 index 8e26378..0000000 --- a/src/common/types/AlignSelfType.ts +++ /dev/null @@ -1 +0,0 @@ -export type AlignSelfType = 'start' | 'end' | 'center' | 'baseline' | 'stretch'; diff --git a/src/common/types/ButtonSizeType.ts b/src/common/types/ButtonSizeType.ts deleted file mode 100644 index 0f9dd4a..0000000 --- a/src/common/types/ButtonSizeType.ts +++ /dev/null @@ -1 +0,0 @@ -export type ButtonSizeType = 'lg' | 'sm'; diff --git a/src/common/types/ColorVariantType.ts b/src/common/types/ColorVariantType.ts deleted file mode 100644 index 1ff6f60..0000000 --- a/src/common/types/ColorVariantType.ts +++ /dev/null @@ -1 +0,0 @@ -export type ColorVariantType = 'primary' | 'success' | 'danger' | 'secondary' | 'link' | 'black' | 'white' | 'dark' | 'warning' | 'muted' | 'light'; diff --git a/src/common/types/ColumnSizesType.ts b/src/common/types/ColumnSizesType.ts deleted file mode 100644 index 2b130d8..0000000 --- a/src/common/types/ColumnSizesType.ts +++ /dev/null @@ -1 +0,0 @@ -export type ColumnSizesType = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12; diff --git a/src/common/types/DisplayType.ts b/src/common/types/DisplayType.ts deleted file mode 100644 index 7551d72..0000000 --- a/src/common/types/DisplayType.ts +++ /dev/null @@ -1 +0,0 @@ -export type DisplayType = 'none' | 'inline' | 'inline-block' | 'block' | 'grid' | 'table' | 'table-cell' | 'table-row' | 'flex' | 'inline-flex'; diff --git a/src/common/types/FloatType.ts b/src/common/types/FloatType.ts deleted file mode 100644 index 63e495f..0000000 --- a/src/common/types/FloatType.ts +++ /dev/null @@ -1 +0,0 @@ -export type FloatType = 'start' | 'end' | 'none'; diff --git a/src/common/types/FontSizeType.ts b/src/common/types/FontSizeType.ts deleted file mode 100644 index 120c11c..0000000 --- a/src/common/types/FontSizeType.ts +++ /dev/null @@ -1 +0,0 @@ -export type FontSizeType = 1 | 2 | 3 | 4 | 5 | 6; diff --git a/src/common/types/FontWeightType.ts b/src/common/types/FontWeightType.ts deleted file mode 100644 index c7c9286..0000000 --- a/src/common/types/FontWeightType.ts +++ /dev/null @@ -1 +0,0 @@ -export type FontWeightType = 'bold' | 'bolder' | 'normal' | 'light' | 'lighter'; diff --git a/src/common/types/JustifyContentType.ts b/src/common/types/JustifyContentType.ts deleted file mode 100644 index 73a318d..0000000 --- a/src/common/types/JustifyContentType.ts +++ /dev/null @@ -1 +0,0 @@ -export type JustifyContentType = 'start' | 'end' | 'center' | 'between' | 'around' | 'evenly'; diff --git a/src/common/types/OverflowType.ts b/src/common/types/OverflowType.ts deleted file mode 100644 index 9231ff9..0000000 --- a/src/common/types/OverflowType.ts +++ /dev/null @@ -1 +0,0 @@ -export type OverflowType = 'auto' | 'hidden' | 'visible' | 'scroll' | 'y-scroll' | 'unset'; diff --git a/src/common/types/PositionType.ts b/src/common/types/PositionType.ts deleted file mode 100644 index 4e20b2f..0000000 --- a/src/common/types/PositionType.ts +++ /dev/null @@ -1 +0,0 @@ -export type PositionType = 'static' | 'relative' | 'fixed' | 'absolute' | 'sticky'; diff --git a/src/common/types/SpacingType.ts b/src/common/types/SpacingType.ts deleted file mode 100644 index 91c2bb5..0000000 --- a/src/common/types/SpacingType.ts +++ /dev/null @@ -1 +0,0 @@ -export type SpacingType = 0 | 1 | 2 | 3 | 4 | 5; diff --git a/src/common/types/TextAlignType.ts b/src/common/types/TextAlignType.ts deleted file mode 100644 index cb82648..0000000 --- a/src/common/types/TextAlignType.ts +++ /dev/null @@ -1 +0,0 @@ -export type TextAlignType = 'start' | 'center' | 'end'; diff --git a/src/common/types/index.ts b/src/common/types/index.ts deleted file mode 100644 index 333177e..0000000 --- a/src/common/types/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -export * from './AlignItemType'; -export * from './AlignSelfType'; -export * from './ButtonSizeType'; -export * from './ColorVariantType'; -export * from './ColumnSizesType'; -export * from './DisplayType'; -export * from './FloatType'; -export * from './FontSizeType'; -export * from './FontWeightType'; -export * from './JustifyContentType'; -export * from './OverflowType'; -export * from './PositionType'; -export * from './SpacingType'; -export * from './TextAlignType'; diff --git a/src/common/utils/CreateTransitionToIcon.ts b/src/common/utils/CreateTransitionToIcon.ts deleted file mode 100644 index 656eea5..0000000 --- a/src/common/utils/CreateTransitionToIcon.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { GetEventDispatcher, NitroToolbarAnimateIconEvent } from '@nitrots/nitro-renderer'; - -export const CreateTransitionToIcon = (image: HTMLImageElement, fromElement: HTMLElement, icon: string) => -{ - const bounds = fromElement.getBoundingClientRect(); - const x = (bounds.x + (bounds.width / 2)); - const y = (bounds.y + (bounds.height / 2)); - const event = new NitroToolbarAnimateIconEvent(image, x, y); - - event.iconName = icon; - - GetEventDispatcher().dispatchEvent(event); -} diff --git a/src/common/utils/FriendlyTimeView.tsx b/src/common/utils/FriendlyTimeView.tsx deleted file mode 100644 index cf5a635..0000000 --- a/src/common/utils/FriendlyTimeView.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { FC, useEffect, useMemo, useState } from 'react'; -import { FriendlyTime } from '../../api'; -import { Base, BaseProps } from '../Base'; - -interface FriendlyTimeViewProps extends BaseProps -{ - seconds: number; - isShort?: boolean; -} - -export const FriendlyTimeView: FC = props => -{ - const { seconds = 0, isShort = false, children = null, ...rest } = props; - const [ updateId, setUpdateId ] = useState(-1); - - const getStartSeconds = useMemo(() => (Math.round(new Date().getSeconds()) - seconds), [ seconds ]); - - useEffect(() => - { - const interval = setInterval(() => setUpdateId(prevValue => (prevValue + 1)), 10000); - - return () => clearInterval(interval); - }, []); - - const value = (Math.round(new Date().getSeconds()) - getStartSeconds); - - return { isShort ? FriendlyTime.shortFormat(value) : FriendlyTime.format(value) }; -} diff --git a/src/common/utils/index.ts b/src/common/utils/index.ts deleted file mode 100644 index 11d60a3..0000000 --- a/src/common/utils/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './CreateTransitionToIcon'; -export * from './FriendlyTimeView'; diff --git a/src/components/achievements/AchievementsView.scss b/src/components/achievements/AchievementsView.scss deleted file mode 100644 index 3fa61ac..0000000 --- a/src/components/achievements/AchievementsView.scss +++ /dev/null @@ -1,15 +0,0 @@ -.nitro-achievements { - width: $achievement-width; - height: $achievement-height; -} - -.nitro-achievements-back-arrow { - background: url('@/assets/images/achievements/back-arrow.png') no-repeat center; - width: 33px; - height: 34px; -} - -.nitro-achievements-badge-image { - width: 80px !important; - height: 80px !important; -} diff --git a/src/components/achievements/AchievementsView.tsx b/src/components/achievements/AchievementsView.tsx deleted file mode 100644 index 3af9b98..0000000 --- a/src/components/achievements/AchievementsView.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { AddLinkEventTracker, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { AchievementUtilities, LocalizeText } from '../../api'; -import { Base, Column, LayoutImage, LayoutProgressBar, NitroCardContentView, NitroCardHeaderView, NitroCardSubHeaderView, NitroCardView, Text } from '../../common'; -import { useAchievements } from '../../hooks'; -import { AchievementCategoryView } from './views/AchievementCategoryView'; -import { AchievementsCategoryListView } from './views/category-list/AchievementsCategoryListView'; - -export const AchievementsView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const { achievementCategories = [], selectedCategoryCode = null, setSelectedCategoryCode = null, achievementScore = 0, getProgress = 0, getMaxProgress = 0, selectedCategory = null } = useAchievements(); - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setIsVisible(true); - return; - case 'hide': - setIsVisible(false); - return; - case 'toggle': - setIsVisible(prevValue => !prevValue); - return; - } - }, - eventUrlPrefix: 'achievements/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, []); - - if(!isVisible) return null; - - return ( - - setIsVisible(false) } /> - { selectedCategory && - - setSelectedCategoryCode(null) } className="nitro-achievements-back-arrow" /> - - { LocalizeText(`quests.${ selectedCategory.code }.name`) } - { LocalizeText('achievements.details.categoryprogress', [ 'progress', 'limit' ], [ selectedCategory.getProgress().toString(), selectedCategory.getMaxProgress().toString() ]) } - - - } - - { !selectedCategory && - <> - - - { LocalizeText('achievements.categories.score', [ 'score' ], [ achievementScore.toString() ]) } - - - } - { selectedCategory && - } - - - ); -}; diff --git a/src/components/achievements/views/AchievementBadgeView.tsx b/src/components/achievements/views/AchievementBadgeView.tsx deleted file mode 100644 index 5b0d4f9..0000000 --- a/src/components/achievements/views/AchievementBadgeView.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { AchievementData } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { AchievementUtilities } from '../../../api'; -import { BaseProps, LayoutBadgeImageView } from '../../../common'; - -interface AchievementBadgeViewProps extends BaseProps -{ - achievement: AchievementData; - scale?: number; -} - -export const AchievementBadgeView: FC = props => -{ - const { achievement = null, scale = 1, ...rest } = props; - - if(!achievement) return null; - - return ; -} diff --git a/src/components/achievements/views/AchievementCategoryView.tsx b/src/components/achievements/views/AchievementCategoryView.tsx deleted file mode 100644 index 8774d20..0000000 --- a/src/components/achievements/views/AchievementCategoryView.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { FC, useEffect } from 'react'; -import { AchievementCategory } from '../../../api'; -import { Column } from '../../../common'; -import { useAchievements } from '../../../hooks'; -import { AchievementListView } from './achievement-list'; -import { AchievementDetailsView } from './AchievementDetailsView'; - -interface AchievementCategoryViewProps -{ - category: AchievementCategory; -} - -export const AchievementCategoryView: FC = props => -{ - const { category = null } = props; - const { selectedAchievement = null, setSelectedAchievementId = null } = useAchievements(); - - useEffect(() => - { - if(!category) return; - - if(!selectedAchievement) - { - setSelectedAchievementId(category?.achievements?.[0]?.achievementId); - } - }, [ category, selectedAchievement, setSelectedAchievementId ]); - - if(!category) return null; - - return ( - - - { !!selectedAchievement && - } - - ); -} diff --git a/src/components/achievements/views/AchievementDetailsView.tsx b/src/components/achievements/views/AchievementDetailsView.tsx deleted file mode 100644 index b04fa18..0000000 --- a/src/components/achievements/views/AchievementDetailsView.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { AchievementData } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { AchievementUtilities, LocalizeBadgeDescription, LocalizeBadgeName, LocalizeText } from '../../../api'; -import { Column, Flex, LayoutCurrencyIcon, LayoutProgressBar, Text } from '../../../common'; -import { AchievementBadgeView } from './AchievementBadgeView'; - -interface AchievementDetailsViewProps -{ - achievement: AchievementData; -} - -export const AchievementDetailsView: FC = props => -{ - const { achievement = null } = props; - - if(!achievement) return null; - - return ( - - - - - { LocalizeText('achievements.details.level', [ 'level', 'limit' ], [ AchievementUtilities.getAchievementLevel(achievement).toString(), achievement.levelCount.toString() ]) } - - - - - - { LocalizeBadgeName(AchievementUtilities.getAchievementBadgeCode(achievement)) } - - - { LocalizeBadgeDescription(AchievementUtilities.getAchievementBadgeCode(achievement)) } - - - { ((achievement.levelRewardPoints > 0) || (achievement.scoreLimit > 0)) && - - { (achievement.levelRewardPoints > 0) && - - - { LocalizeText('achievements.details.reward') } - - - { achievement.levelRewardPoints } - - - } - { (achievement.scoreLimit > 0) && - } - } - - - ) -} diff --git a/src/components/achievements/views/achievement-list/AchievementListItemView.tsx b/src/components/achievements/views/achievement-list/AchievementListItemView.tsx deleted file mode 100644 index 9da632b..0000000 --- a/src/components/achievements/views/achievement-list/AchievementListItemView.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { AchievementData } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { LayoutGridItem } from '../../../../common'; -import { useAchievements } from '../../../../hooks'; -import { AchievementBadgeView } from '../AchievementBadgeView'; - -interface AchievementListItemViewProps -{ - achievement: AchievementData; -} - -export const AchievementListItemView: FC = props => -{ - const { achievement = null } = props; - const { selectedAchievement = null, setSelectedAchievementId = null } = useAchievements(); - - if(!achievement) return null; - - return ( - 0) } onClick={ event => setSelectedAchievementId(achievement.achievementId) }> - - - ); -} diff --git a/src/components/achievements/views/achievement-list/AchievementListView.tsx b/src/components/achievements/views/achievement-list/AchievementListView.tsx deleted file mode 100644 index f009581..0000000 --- a/src/components/achievements/views/achievement-list/AchievementListView.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { AchievementData } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { AutoGrid } from '../../../../common'; -import { AchievementListItemView } from './AchievementListItemView'; - -interface AchievementListViewProps -{ - achievements: AchievementData[]; -} - -export const AchievementListView: FC = props => -{ - const { achievements = null } = props; - - return ( - - { achievements && (achievements.length > 0) && achievements.map((achievement, index) => ) } - - ); -} diff --git a/src/components/achievements/views/achievement-list/index.ts b/src/components/achievements/views/achievement-list/index.ts deleted file mode 100644 index 87ccb43..0000000 --- a/src/components/achievements/views/achievement-list/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './AchievementListItemView'; -export * from './AchievementListView'; diff --git a/src/components/achievements/views/category-list/AchievementsCategoryListItemView.tsx b/src/components/achievements/views/category-list/AchievementsCategoryListItemView.tsx deleted file mode 100644 index 91b96c6..0000000 --- a/src/components/achievements/views/category-list/AchievementsCategoryListItemView.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Dispatch, FC, SetStateAction } from 'react'; -import { AchievementUtilities, IAchievementCategory, LocalizeText } from '../../../../api'; -import { LayoutBackgroundImage, LayoutGridItem, Text } from '../../../../common'; - -interface AchievementCategoryListItemViewProps -{ - category: IAchievementCategory; - selectedCategoryCode: string; - setSelectedCategoryCode: Dispatch>; -} - -export const AchievementsCategoryListItemView: FC = props => -{ - const { category = null, selectedCategoryCode = null, setSelectedCategoryCode = null } = props; - - if(!category) return null; - - const progress = AchievementUtilities.getAchievementCategoryProgress(category); - const maxProgress = AchievementUtilities.getAchievementCategoryMaxProgress(category); - const getCategoryImage = AchievementUtilities.getAchievementCategoryImageUrl(category, progress); - const getTotalUnseen = AchievementUtilities.getAchievementCategoryTotalUnseen(category); - - return ( - setSelectedCategoryCode(category.code) }> - { LocalizeText(`quests.${ category.code }.name`) } - - { progress } / { maxProgress } - - - ); -} diff --git a/src/components/achievements/views/category-list/AchievementsCategoryListView.tsx b/src/components/achievements/views/category-list/AchievementsCategoryListView.tsx deleted file mode 100644 index ca36296..0000000 --- a/src/components/achievements/views/category-list/AchievementsCategoryListView.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Dispatch, FC, SetStateAction } from 'react'; -import { IAchievementCategory } from '../../../../api'; -import { AutoGrid } from '../../../../common'; -import { AchievementsCategoryListItemView } from './AchievementsCategoryListItemView'; - -interface AchievementsCategoryListViewProps -{ - categories: IAchievementCategory[]; - selectedCategoryCode: string; - setSelectedCategoryCode: Dispatch>; -} - -export const AchievementsCategoryListView: FC = props => -{ - const { categories = null, selectedCategoryCode = null, setSelectedCategoryCode = null } = props; - - return ( - - { categories && (categories.length > 0) && categories.map((category, index) => ) } - - ); -}; diff --git a/src/components/achievements/views/category-list/index.ts b/src/components/achievements/views/category-list/index.ts deleted file mode 100644 index 5a367f8..0000000 --- a/src/components/achievements/views/category-list/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './AchievementsCategoryListItemView'; -export * from './AchievementsCategoryListView'; diff --git a/src/components/achievements/views/index.ts b/src/components/achievements/views/index.ts deleted file mode 100644 index 576c635..0000000 --- a/src/components/achievements/views/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './achievement-list'; -export * from './AchievementBadgeView'; -export * from './AchievementCategoryView'; -export * from './AchievementDetailsView'; -export * from './category-list'; diff --git a/src/components/avatar-editor-new/AvatarEditorView.scss b/src/components/avatar-editor-new/AvatarEditorView.scss deleted file mode 100644 index 22b873d..0000000 --- a/src/components/avatar-editor-new/AvatarEditorView.scss +++ /dev/null @@ -1,336 +0,0 @@ -.nitro-avatar-editor-spritesheet { - background: url('@/assets/images/avatareditor/avatar-editor-spritesheet.png') transparent no-repeat; - - &.arrow-left-icon { - width: 28px; - height: 21px; - background-position: -226px -131px; - } - - &.arrow-right-icon { - width: 28px; - height: 21px; - background-position: -226px -162px; - } - - &.ca-icon { - width: 25px; - height: 25px; - background-position: -226px -61px; - - &.selected { - width: 25px; - height: 25px; - background-position: -226px -96px; - } - } - - &.cc-icon { - width: 31px; - height: 29px; - background-position: -145px -5px; - - &.selected { - width: 31px; - height: 29px; - background-position: -145px -44px; - } - } - - &.ch-icon { - width: 29px; - height: 24px; - background-position: -186px -39px; - - &.selected { - width: 29px; - height: 24px; - background-position: -186px -73px; - } - } - - &.clear-icon { - width: 27px; - height: 27px; - background-position: -145px -157px; - } - - &.cp-icon { - width: 30px; - height: 24px; - background-position: -145px -264px; - - &.selected { - width: 30px; - height: 24px; - background-position: -186px -5px; - } - } - - - &.ea-icon { - width: 35px; - height: 16px; - background-position: -226px -193px; - - &.selected { - width: 35px; - height: 16px; - background-position: -226px -219px; - } - } - - &.fa-icon { - width: 27px; - height: 20px; - background-position: -186px -137px; - - &.selected { - width: 27px; - height: 20px; - background-position: -186px -107px; - } - } - - &.female-icon { - width: 18px; - height: 27px; - background-position: -186px -202px; - - &.selected { - width: 18px; - height: 27px; - background-position: -186px -239px; - } - } - - &.ha-icon { - width: 25px; - height: 22px; - background-position: -226px -245px; - - &.selected { - width: 25px; - height: 22px; - background-position: -226px -277px; - } - } - - &.he-icon { - width: 31px; - height: 27px; - background-position: -145px -83px; - - &.selected { - width: 31px; - height: 27px; - background-position: -145px -120px; - } - } - - &.hr-icon { - width: 29px; - height: 25px; - background-position: -145px -194px; - - &.selected { - width: 29px; - height: 25px; - background-position: -145px -229px; - } - } - - &.lg-icon { - width: 19px; - height: 20px; - background-position: -303px -45px; - - &.selected { - width: 19px; - height: 20px; - background-position: -303px -75px; - } - } - - &.loading-icon { - width: 21px; - height: 25px; - background-position: -186px -167px; - } - - - &.male-icon { - width: 21px; - height: 21px; - background-position: -186px -276px; - - &.selected { - width: 21px; - height: 21px; - background-position: -272px -5px; - } - } - - - &.sellable-icon { - width: 17px; - height: 15px; - background-position: -303px -105px; - } - - - &.sh-icon { - width: 37px; - height: 10px; - background-position: -303px -5px; - - &.selected { - width: 37px; - height: 10px; - background-position: -303px -25px; - } - } - - - &.spotlight-icon { - width: 130px; - height: 305px; - background-position: -5px -5px; - } - - - &.wa-icon { - width: 36px; - height: 18px; - background-position: -226px -5px; - - &.selected { - width: 36px; - height: 18px; - background-position: -226px -33px; - } - } -} - -.nitro-avatar-editor-wardrobe-figure-preview { - background-color: $pale-sky; - overflow: hidden; - z-index: 1; - - .avatar-image { - position: absolute; - bottom: -15px; - margin: 0 auto; - z-index: 4; - } - - .avatar-shadow { - position: absolute; - left: 0; - right: 0; - bottom: 25px; - width: 40px; - height: 20px; - margin: 0 auto; - border-radius: 100%; - background-color: rgba(0, 0, 0, 0.20); - z-index: 2; - } - - &:after { - position: absolute; - content: ''; - top: 75%; - bottom: 0; - left: 0; - right: 0; - border-radius: 50%; - background-color: $pale-sky; - box-shadow: 0 0 8px 2px rgba($white,.6); - transform: scale(2); - } - - .button-container { - position: absolute; - bottom: 0; - z-index: 5; - } -} - -.nitro-avatar-editor { - width: $avatar-editor-width; - height: $avatar-editor-height; - - .category-item { - height: 40px; - } - - .figure-preview-container { - position: relative; - height: 100%; - background-color: $pale-sky; - overflow: hidden; - z-index: 1; - - .arrow-container { - position: absolute; - width: 100%; - margin: 0 auto; - padding: 0 10px; - display: flex; - justify-content: space-between; - bottom: 12px; - z-index: 5; - - .icon { - cursor: pointer; - } - } - - .avatar-image { - position: absolute; - left: 0; - right: 0; - bottom: 50px; - margin: 0 auto; - z-index: 4; - } - - .avatar-spotlight { - position: absolute; - top: -10px; - left: 0; - right: 0; - margin: 0 auto; - opacity: 0.3; - pointer-events: none; - z-index: 3; - } - - .avatar-shadow { - position: absolute; - left: 0; - right: 0; - bottom: 15px; - width: 70px; - height: 30px; - margin: 0 auto; - border-radius: 100%; - background-color: rgba(0, 0, 0, 0.20); - z-index: 2; - } - - &:after { - position: absolute; - content: ''; - top: 75%; - bottom: 0; - left: 0; - right: 0; - border-radius: 50%; - background-color: $pale-sky; - box-shadow: 0 0 8px 2px rgba($white,.6); - transform: scale(2); - } - } -} diff --git a/src/components/avatar-editor-new/AvatarEditorView.tsx b/src/components/avatar-editor-new/AvatarEditorView.tsx deleted file mode 100644 index eb1973d..0000000 --- a/src/components/avatar-editor-new/AvatarEditorView.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { AddLinkEventTracker, AvatarEditorFigureCategory, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { FaDice, FaTrash, FaUndo } from 'react-icons/fa'; -import { AvatarEditorAction, LocalizeText } from '../../api'; -import { Button, ButtonGroup, Column, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common'; -import { useAvatarEditor } from '../../hooks'; -import { AvatarEditorModelView } from './views/AvatarEditorModelView'; - -const DEFAULT_MALE_FIGURE: string = 'hr-100.hd-180-7.ch-215-66.lg-270-79.sh-305-62.ha-1002-70.wa-2007'; -const DEFAULT_FEMALE_FIGURE: string = 'hr-515-33.hd-600-1.ch-635-70.lg-716-66-62.sh-735-68'; - -export const AvatarEditorNewView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const { setIsVisible: setEditorVisibility, avatarModels, activeModelKey, setActiveModelKey } = useAvatarEditor(); - - const processAction = (action: string) => - { - switch(action) - { - case AvatarEditorAction.ACTION_CLEAR: - return; - case AvatarEditorAction.ACTION_RESET: - return; - case AvatarEditorAction.ACTION_RANDOMIZE: - return; - case AvatarEditorAction.ACTION_SAVE: - return; - } - } - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setIsVisible(true); - return; - case 'hide': - setIsVisible(false); - return; - case 'toggle': - setIsVisible(prevValue => !prevValue); - return; - } - }, - eventUrlPrefix: 'avatar-editor/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, []); - - useEffect(() => - { - setEditorVisibility(isVisible) - }, [ isVisible, setEditorVisibility ]); - - if(!isVisible) return null; - - return ( - - setIsVisible(false) } /> - - { Object.keys(avatarModels).map(modelKey => - { - const isActive = (activeModelKey === modelKey); - - return ( - setActiveModelKey(modelKey) }> - { LocalizeText(`avatareditor.category.${ modelKey }`) } - - ); - }) } - - - - - { ((activeModelKey.length > 0) && (activeModelKey !== AvatarEditorFigureCategory.WARDROBE)) && - } - { (activeModelKey === AvatarEditorFigureCategory.WARDROBE) } - - - { /* */ } - - - - - - - - - - - - - ); -} diff --git a/src/components/avatar-editor-new/views/AvatarEditorIcon.tsx b/src/components/avatar-editor-new/views/AvatarEditorIcon.tsx deleted file mode 100644 index a05baa1..0000000 --- a/src/components/avatar-editor-new/views/AvatarEditorIcon.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { FC, useMemo } from 'react'; -import { Base, BaseProps } from '../../../common'; - -type AvatarIconType = 'male' | 'female' | 'clear' | 'sellable' | string; - -export interface AvatarEditorIconProps extends BaseProps -{ - icon: AvatarIconType; - selected?: boolean; -} - -export const AvatarEditorIcon: FC = props => -{ - const { icon = null, selected = false, classNames = [], children = null, ...rest } = props; - - const getClassNames = useMemo(() => - { - const newClassNames: string[] = [ 'nitro-avatar-editor-spritesheet' ]; - - if(icon && icon.length) newClassNames.push(icon + '-icon'); - - if(selected) newClassNames.push('selected'); - - if(classNames.length) newClassNames.push(...classNames); - - return newClassNames; - }, [ icon, selected, classNames ]); - - return -} diff --git a/src/components/avatar-editor-new/views/AvatarEditorModelView.tsx b/src/components/avatar-editor-new/views/AvatarEditorModelView.tsx deleted file mode 100644 index c012383..0000000 --- a/src/components/avatar-editor-new/views/AvatarEditorModelView.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { AvatarEditorFigureCategory } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useMemo, useState } from 'react'; -import { FigureData, IAvatarEditorCategory } from '../../../api'; -import { Column, Flex, Grid } from '../../../common'; -import { useAvatarEditor } from '../../../hooks'; -import { AvatarEditorIcon } from './AvatarEditorIcon'; -import { AvatarEditorFigureSetView } from './figure-set'; -import { AvatarEditorPaletteSetView } from './palette-set'; - -export const AvatarEditorModelView: FC<{ - name: string, - categories: IAvatarEditorCategory[] -}> = props => -{ - const { name = '', categories = [] } = props; - const [ activeSetType, setActiveSetType ] = useState(''); - const { maxPaletteCount = 1 } = useAvatarEditor(); - - const activeCategory = useMemo(() => - { - return categories.find(category => category.setType === activeSetType) ?? null; - }, [ categories, activeSetType ]); - - const setGender = (gender: string) => - { - // - } - - useEffect(() => - { - if(!activeCategory) return; - - // we need to run this when we change which parts r selected - /* for(const partItem of activeCategory.partItems) - { - if(!partItem || !part.isSelected) continue; - - setMaxPaletteCount(part.maxColorIndex || 1); - - break; - } */ - }, [ activeCategory ]) - - useEffect(() => - { - if(!categories || !categories.length) return; - - setActiveSetType(categories[0]?.setType) - }, [ categories ]); - - if(!activeCategory) return null; - - return ( - - - { (name === AvatarEditorFigureCategory.GENERIC) && - <> - setGender(FigureData.MALE) }> - - - setGender(FigureData.FEMALE) }> - - - } - { (name !== AvatarEditorFigureCategory.GENERIC) && (categories.length > 0) && categories.map(category => - { - return ( - setActiveSetType(category.setType) }> - - - ); - }) } - - - - - - { (maxPaletteCount >= 1) && - } - { (maxPaletteCount === 2) && - } - - - ); -} diff --git a/src/components/avatar-editor-new/views/figure-set/AvatarEditorFigureSetItemView.tsx b/src/components/avatar-editor-new/views/figure-set/AvatarEditorFigureSetItemView.tsx deleted file mode 100644 index 1c00fc9..0000000 --- a/src/components/avatar-editor-new/views/figure-set/AvatarEditorFigureSetItemView.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { AvatarEditorThumbnailsHelper, FigureData, GetConfigurationValue, IAvatarEditorCategoryPartItem } from '../../../../api'; -import { LayoutCurrencyIcon, LayoutGridItem, LayoutGridItemProps } from '../../../../common'; -import { useAvatarEditor } from '../../../../hooks'; -import { AvatarEditorIcon } from '../AvatarEditorIcon'; - -export const AvatarEditorFigureSetItemView: FC<{ - setType: string; - partItem: IAvatarEditorCategoryPartItem; - isSelected: boolean; -} & LayoutGridItemProps> = props => -{ - const { setType = null, partItem = null, isSelected = false, ...rest } = props; - const [ assetUrl, setAssetUrl ] = useState(''); - const { selectedColorParts = null, getFigureStringWithFace = null } = useAvatarEditor(); - - const isHC = !GetConfigurationValue('hc.disabled', false) && ((partItem.partSet?.clubLevel ?? 0) > 0); - - useEffect(() => - { - if(!setType || !setType.length || !partItem) return; - - const loadImage = async () => - { - const isHC = !GetConfigurationValue('hc.disabled', false) && ((partItem.partSet?.clubLevel ?? 0) > 0); - - let url: string = null; - - if(setType === FigureData.FACE) - { - url = await AvatarEditorThumbnailsHelper.buildForFace(getFigureStringWithFace(partItem.id), isHC); - } - else - { - url = await AvatarEditorThumbnailsHelper.build(setType, partItem, partItem.usesColor, selectedColorParts[setType] ?? null, isHC); - } - - if(url && url.length) setAssetUrl(url); - } - - loadImage(); - }, [ setType, partItem, selectedColorParts, getFigureStringWithFace ]); - - if(!partItem) return null; - - return ( - - { !partItem.isClear && isHC && } - { partItem.isClear && } - { !partItem.isClear && partItem.partSet.isSellable && } - - ); -} diff --git a/src/components/avatar-editor-new/views/figure-set/AvatarEditorFigureSetView.tsx b/src/components/avatar-editor-new/views/figure-set/AvatarEditorFigureSetView.tsx deleted file mode 100644 index 7db3743..0000000 --- a/src/components/avatar-editor-new/views/figure-set/AvatarEditorFigureSetView.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { FC, useRef } from 'react'; -import { IAvatarEditorCategory, IAvatarEditorCategoryPartItem } from '../../../../api'; -import { InfiniteGrid } from '../../../../common'; -import { useAvatarEditor } from '../../../../hooks'; -import { AvatarEditorFigureSetItemView } from './AvatarEditorFigureSetItemView'; - -export const AvatarEditorFigureSetView: FC<{ - category: IAvatarEditorCategory -}> = props => -{ - const { category = null } = props; - const { selectedParts = null, selectEditorPart } = useAvatarEditor(); - const elementRef = useRef(null); - - const isPartItemSelected = (partItem: IAvatarEditorCategoryPartItem) => - { - if(!category || !category.setType || !selectedParts || !selectedParts[category.setType]) return false; - - const partId = selectedParts[category.setType]; - - return (partId === partItem.id); - } - - const columnCount = 3; - - return ( - - { - if(!item) return null; - - return ( - selectEditorPart(category.setType, item.partSet?.id ?? -1) } /> - ) - } } /> - ); -} diff --git a/src/components/avatar-editor-new/views/figure-set/index.ts b/src/components/avatar-editor-new/views/figure-set/index.ts deleted file mode 100644 index 0c5880b..0000000 --- a/src/components/avatar-editor-new/views/figure-set/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './AvatarEditorFigureSetItemView'; -export * from './AvatarEditorFigureSetView'; diff --git a/src/components/avatar-editor-new/views/palette-set/AvatarEditorPaletteSetItemView.tsx b/src/components/avatar-editor-new/views/palette-set/AvatarEditorPaletteSetItemView.tsx deleted file mode 100644 index 672c356..0000000 --- a/src/components/avatar-editor-new/views/palette-set/AvatarEditorPaletteSetItemView.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { ColorConverter, IPartColor } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { GetConfigurationValue } from '../../../../api'; -import { LayoutCurrencyIcon, LayoutGridItem, LayoutGridItemProps } from '../../../../common'; - -export interface AvatarEditorPaletteSetItemProps extends LayoutGridItemProps -{ - setType: string; - partColor: IPartColor; - isSelected: boolean; -} - -// its disabled if its hc and you dont have it -export const AvatarEditorPaletteSetItem: FC = props => -{ - const { setType = null, partColor = null, isSelected = false, ...rest } = props; - - if(!partColor) return null; - - const isHC = !GetConfigurationValue('hc.disabled', false) && (partColor.clubLevel > 0); - - return ( - - { isHC && } - - ); -} diff --git a/src/components/avatar-editor-new/views/palette-set/AvatarEditorPaletteSetView.tsx b/src/components/avatar-editor-new/views/palette-set/AvatarEditorPaletteSetView.tsx deleted file mode 100644 index 2e72cd4..0000000 --- a/src/components/avatar-editor-new/views/palette-set/AvatarEditorPaletteSetView.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { IPartColor } from '@nitrots/nitro-renderer'; -import { FC, useRef } from 'react'; -import { IAvatarEditorCategory } from '../../../../api'; -import { AutoGrid } from '../../../../common'; -import { useAvatarEditor } from '../../../../hooks'; -import { AvatarEditorPaletteSetItem } from './AvatarEditorPaletteSetItemView'; - -export const AvatarEditorPaletteSetView: FC<{ - category: IAvatarEditorCategory, - paletteIndex: number; -}> = props => -{ - const { category = null, paletteIndex = -1 } = props; - const paletteSet = category?.colorItems[paletteIndex] ?? null; - const { selectedColors = null, selectEditorColor } = useAvatarEditor(); - const elementRef = useRef(null); - - const isPartColorSelected = (partColor: IPartColor) => - { - if(!category || !category.setType || !selectedColors || !selectedColors[category.setType] || !selectedColors[category.setType][paletteIndex]) return false; - - const colorId = selectedColors[category.setType][paletteIndex]; - - return (colorId === partColor.id); - } - - return ( - - { (paletteSet.length > 0) && paletteSet.map(item => - selectEditorColor(category.setType, paletteIndex, item.id) } />) } - - ); -} diff --git a/src/components/avatar-editor-new/views/palette-set/index.ts b/src/components/avatar-editor-new/views/palette-set/index.ts deleted file mode 100644 index 977e5b9..0000000 --- a/src/components/avatar-editor-new/views/palette-set/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './AvatarEditorPaletteSetItemView'; -export * from './AvatarEditorPaletteSetView'; diff --git a/src/components/avatar-editor/AvatarEditorView.scss b/src/components/avatar-editor/AvatarEditorView.scss deleted file mode 100644 index 22b873d..0000000 --- a/src/components/avatar-editor/AvatarEditorView.scss +++ /dev/null @@ -1,336 +0,0 @@ -.nitro-avatar-editor-spritesheet { - background: url('@/assets/images/avatareditor/avatar-editor-spritesheet.png') transparent no-repeat; - - &.arrow-left-icon { - width: 28px; - height: 21px; - background-position: -226px -131px; - } - - &.arrow-right-icon { - width: 28px; - height: 21px; - background-position: -226px -162px; - } - - &.ca-icon { - width: 25px; - height: 25px; - background-position: -226px -61px; - - &.selected { - width: 25px; - height: 25px; - background-position: -226px -96px; - } - } - - &.cc-icon { - width: 31px; - height: 29px; - background-position: -145px -5px; - - &.selected { - width: 31px; - height: 29px; - background-position: -145px -44px; - } - } - - &.ch-icon { - width: 29px; - height: 24px; - background-position: -186px -39px; - - &.selected { - width: 29px; - height: 24px; - background-position: -186px -73px; - } - } - - &.clear-icon { - width: 27px; - height: 27px; - background-position: -145px -157px; - } - - &.cp-icon { - width: 30px; - height: 24px; - background-position: -145px -264px; - - &.selected { - width: 30px; - height: 24px; - background-position: -186px -5px; - } - } - - - &.ea-icon { - width: 35px; - height: 16px; - background-position: -226px -193px; - - &.selected { - width: 35px; - height: 16px; - background-position: -226px -219px; - } - } - - &.fa-icon { - width: 27px; - height: 20px; - background-position: -186px -137px; - - &.selected { - width: 27px; - height: 20px; - background-position: -186px -107px; - } - } - - &.female-icon { - width: 18px; - height: 27px; - background-position: -186px -202px; - - &.selected { - width: 18px; - height: 27px; - background-position: -186px -239px; - } - } - - &.ha-icon { - width: 25px; - height: 22px; - background-position: -226px -245px; - - &.selected { - width: 25px; - height: 22px; - background-position: -226px -277px; - } - } - - &.he-icon { - width: 31px; - height: 27px; - background-position: -145px -83px; - - &.selected { - width: 31px; - height: 27px; - background-position: -145px -120px; - } - } - - &.hr-icon { - width: 29px; - height: 25px; - background-position: -145px -194px; - - &.selected { - width: 29px; - height: 25px; - background-position: -145px -229px; - } - } - - &.lg-icon { - width: 19px; - height: 20px; - background-position: -303px -45px; - - &.selected { - width: 19px; - height: 20px; - background-position: -303px -75px; - } - } - - &.loading-icon { - width: 21px; - height: 25px; - background-position: -186px -167px; - } - - - &.male-icon { - width: 21px; - height: 21px; - background-position: -186px -276px; - - &.selected { - width: 21px; - height: 21px; - background-position: -272px -5px; - } - } - - - &.sellable-icon { - width: 17px; - height: 15px; - background-position: -303px -105px; - } - - - &.sh-icon { - width: 37px; - height: 10px; - background-position: -303px -5px; - - &.selected { - width: 37px; - height: 10px; - background-position: -303px -25px; - } - } - - - &.spotlight-icon { - width: 130px; - height: 305px; - background-position: -5px -5px; - } - - - &.wa-icon { - width: 36px; - height: 18px; - background-position: -226px -5px; - - &.selected { - width: 36px; - height: 18px; - background-position: -226px -33px; - } - } -} - -.nitro-avatar-editor-wardrobe-figure-preview { - background-color: $pale-sky; - overflow: hidden; - z-index: 1; - - .avatar-image { - position: absolute; - bottom: -15px; - margin: 0 auto; - z-index: 4; - } - - .avatar-shadow { - position: absolute; - left: 0; - right: 0; - bottom: 25px; - width: 40px; - height: 20px; - margin: 0 auto; - border-radius: 100%; - background-color: rgba(0, 0, 0, 0.20); - z-index: 2; - } - - &:after { - position: absolute; - content: ''; - top: 75%; - bottom: 0; - left: 0; - right: 0; - border-radius: 50%; - background-color: $pale-sky; - box-shadow: 0 0 8px 2px rgba($white,.6); - transform: scale(2); - } - - .button-container { - position: absolute; - bottom: 0; - z-index: 5; - } -} - -.nitro-avatar-editor { - width: $avatar-editor-width; - height: $avatar-editor-height; - - .category-item { - height: 40px; - } - - .figure-preview-container { - position: relative; - height: 100%; - background-color: $pale-sky; - overflow: hidden; - z-index: 1; - - .arrow-container { - position: absolute; - width: 100%; - margin: 0 auto; - padding: 0 10px; - display: flex; - justify-content: space-between; - bottom: 12px; - z-index: 5; - - .icon { - cursor: pointer; - } - } - - .avatar-image { - position: absolute; - left: 0; - right: 0; - bottom: 50px; - margin: 0 auto; - z-index: 4; - } - - .avatar-spotlight { - position: absolute; - top: -10px; - left: 0; - right: 0; - margin: 0 auto; - opacity: 0.3; - pointer-events: none; - z-index: 3; - } - - .avatar-shadow { - position: absolute; - left: 0; - right: 0; - bottom: 15px; - width: 70px; - height: 30px; - margin: 0 auto; - border-radius: 100%; - background-color: rgba(0, 0, 0, 0.20); - z-index: 2; - } - - &:after { - position: absolute; - content: ''; - top: 75%; - bottom: 0; - left: 0; - right: 0; - border-radius: 50%; - background-color: $pale-sky; - box-shadow: 0 0 8px 2px rgba($white,.6); - transform: scale(2); - } - } -} diff --git a/src/components/avatar-editor/AvatarEditorView.tsx b/src/components/avatar-editor/AvatarEditorView.tsx deleted file mode 100644 index f2b9c0b..0000000 --- a/src/components/avatar-editor/AvatarEditorView.tsx +++ /dev/null @@ -1,316 +0,0 @@ -import { AvatarEditorFigureCategory, FigureSetIdsMessageEvent, GetAvatarRenderManager, GetSessionDataManager, GetWardrobeMessageComposer, IAvatarFigureContainer, UserFigureComposer, UserWardrobePageEvent } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { FaDice, FaTrash, FaUndo } from 'react-icons/fa'; -import { AvatarEditorAction, AvatarEditorUtilities, BodyModel, FigureData, GetClubMemberLevel, GetConfigurationValue, HeadModel, IAvatarEditorCategoryModel, LegModel, LocalizeText, SendMessageComposer, TorsoModel, generateRandomFigure } from '../../api'; -import { Button, ButtonGroup, Column, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common'; -import { useMessageEvent } from '../../hooks'; -import { AvatarEditorFigurePreviewView } from './views/AvatarEditorFigurePreviewView'; -import { AvatarEditorModelView } from './views/AvatarEditorModelView'; -import { AvatarEditorWardrobeView } from './views/AvatarEditorWardrobeView'; - -const DEFAULT_MALE_FIGURE: string = 'hr-100.hd-180-7.ch-215-66.lg-270-79.sh-305-62.ha-1002-70.wa-2007'; -const DEFAULT_FEMALE_FIGURE: string = 'hr-515-33.hd-600-1.ch-635-70.lg-716-66-62.sh-735-68'; - -export const AvatarEditorView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ figures, setFigures ] = useState>(null); - const [ figureData, setFigureData ] = useState(null); - const [ categories, setCategories ] = useState>(null); - const [ activeCategory, setActiveCategory ] = useState(null); - const [ figureSetIds, setFigureSetIds ] = useState([]); - const [ boundFurnitureNames, setBoundFurnitureNames ] = useState([]); - const [ savedFigures, setSavedFigures ] = useState<[ IAvatarFigureContainer, string ][]>([]); - const [ isWardrobeVisible, setIsWardrobeVisible ] = useState(false); - const [ lastFigure, setLastFigure ] = useState(null); - const [ lastGender, setLastGender ] = useState(null); - const [ needsReset, setNeedsReset ] = useState(true); - const [ isInitalized, setIsInitalized ] = useState(false); - - const maxWardrobeSlots = useMemo(() => GetConfigurationValue('avatar.wardrobe.max.slots', 10), []); - - useMessageEvent(FigureSetIdsMessageEvent, event => - { - const parser = event.getParser(); - - setFigureSetIds(parser.figureSetIds); - setBoundFurnitureNames(parser.boundsFurnitureNames); - }); - - useMessageEvent(UserWardrobePageEvent, event => - { - const parser = event.getParser(); - const savedFigures: [ IAvatarFigureContainer, string ][] = []; - - let i = 0; - - while(i < maxWardrobeSlots) - { - savedFigures.push([ null, null ]); - - i++; - } - - for(let [ index, [ look, gender ] ] of parser.looks.entries()) - { - const container = GetAvatarRenderManager().createFigureContainer(look); - - savedFigures[(index - 1)] = [ container, gender ]; - } - - setSavedFigures(savedFigures); - }); - - const selectCategory = useCallback((name: string) => - { - if(!categories) return; - - setActiveCategory(categories.get(name)); - }, [ categories ]); - - const resetCategories = useCallback(() => - { - const categories = new Map(); - - categories.set(AvatarEditorFigureCategory.GENERIC, new BodyModel()); - categories.set(AvatarEditorFigureCategory.HEAD, new HeadModel()); - categories.set(AvatarEditorFigureCategory.TORSO, new TorsoModel()); - categories.set(AvatarEditorFigureCategory.LEGS, new LegModel()); - - setCategories(categories); - }, []); - - const setupFigures = useCallback(() => - { - const figures: Map = new Map(); - - const maleFigure = new FigureData(); - const femaleFigure = new FigureData(); - - maleFigure.loadAvatarData(DEFAULT_MALE_FIGURE, FigureData.MALE); - femaleFigure.loadAvatarData(DEFAULT_FEMALE_FIGURE, FigureData.FEMALE); - - figures.set(FigureData.MALE, maleFigure); - figures.set(FigureData.FEMALE, femaleFigure); - - setFigures(figures); - setFigureData(figures.get(FigureData.MALE)); - }, []); - - const loadAvatarInEditor = useCallback((figure: string, gender: string, reset: boolean = true) => - { - gender = AvatarEditorUtilities.getGender(gender); - - let newFigureData = figureData; - - if(gender !== newFigureData.gender) newFigureData = figures.get(gender); - - if(figure !== newFigureData.getFigureString()) newFigureData.loadAvatarData(figure, gender); - - if(newFigureData !== figureData) setFigureData(newFigureData); - - if(reset) - { - setLastFigure(figureData.getFigureString()); - setLastGender(figureData.gender); - } - }, [ figures, figureData ]); - - const processAction = useCallback((action: string) => - { - switch(action) - { - case AvatarEditorAction.ACTION_CLEAR: - loadAvatarInEditor(figureData.getFigureStringWithFace(0, false), figureData.gender, false); - resetCategories(); - return; - case AvatarEditorAction.ACTION_RESET: - loadAvatarInEditor(lastFigure, lastGender); - resetCategories(); - return; - case AvatarEditorAction.ACTION_RANDOMIZE: - const figure = generateRandomFigure(figureData, figureData.gender, GetClubMemberLevel(), figureSetIds, [ FigureData.FACE ]); - - loadAvatarInEditor(figure, figureData.gender, false); - resetCategories(); - return; - case AvatarEditorAction.ACTION_SAVE: - SendMessageComposer(new UserFigureComposer(figureData.gender, figureData.getFigureString())); - setIsVisible(false); - return; - } - }, [ figureData, lastFigure, lastGender, figureSetIds, loadAvatarInEditor, resetCategories ]) - - const setGender = useCallback((gender: string) => - { - gender = AvatarEditorUtilities.getGender(gender); - - setFigureData(figures.get(gender)); - }, [ figures ]); - - /* useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setIsVisible(true); - return; - case 'hide': - setIsVisible(false); - return; - case 'toggle': - setIsVisible(prevValue => !prevValue); - return; - } - }, - eventUrlPrefix: 'avatar-editor/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, []); */ - - useEffect(() => - { - setSavedFigures(new Array(maxWardrobeSlots)); - }, [ maxWardrobeSlots ]); - - useEffect(() => - { - if(!isWardrobeVisible) return; - - setActiveCategory(null); - SendMessageComposer(new GetWardrobeMessageComposer()); - }, [ isWardrobeVisible ]); - - useEffect(() => - { - if(!activeCategory) return; - - setIsWardrobeVisible(false); - }, [ activeCategory ]); - - useEffect(() => - { - if(!categories) return; - - selectCategory(AvatarEditorFigureCategory.GENERIC); - }, [ categories, selectCategory ]); - - useEffect(() => - { - if(!figureData) return; - - AvatarEditorUtilities.CURRENT_FIGURE = figureData; - - resetCategories(); - - return () => AvatarEditorUtilities.CURRENT_FIGURE = null; - }, [ figureData, resetCategories ]); - - useEffect(() => - { - AvatarEditorUtilities.FIGURE_SET_IDS = figureSetIds; - AvatarEditorUtilities.BOUND_FURNITURE_NAMES = boundFurnitureNames; - - resetCategories(); - - return () => - { - AvatarEditorUtilities.FIGURE_SET_IDS = null; - AvatarEditorUtilities.BOUND_FURNITURE_NAMES = null; - } - }, [ figureSetIds, boundFurnitureNames, resetCategories ]); - - useEffect(() => - { - if(!isVisible) return; - - if(!figures) - { - setupFigures(); - - setIsInitalized(true); - - return; - } - }, [ isVisible, figures, setupFigures ]); - - useEffect(() => - { - if(!isVisible || !isInitalized || !needsReset) return; - - loadAvatarInEditor(GetSessionDataManager().figure, GetSessionDataManager().gender); - setNeedsReset(false); - }, [ isVisible, isInitalized, needsReset, loadAvatarInEditor ]); - - useEffect(() => - { - if(isVisible) return; - - return () => - { - setNeedsReset(true); - } - }, [ isVisible ]); - - if(!isVisible || !figureData) return null; - - return ( - - setIsVisible(false) } /> - - { categories && (categories.size > 0) && Array.from(categories.keys()).map(category => - { - const isActive = (activeCategory && (activeCategory.name === category)); - - return ( - selectCategory(category) }> - { LocalizeText(`avatareditor.category.${ category }`) } - - ); - }) } - setIsWardrobeVisible(true) }> - { LocalizeText('avatareditor.category.wardrobe') } - - - - - - { (activeCategory && !isWardrobeVisible) && - } - { isWardrobeVisible && - } - - - - - - - - - - - - - - - - ); -} diff --git a/src/components/avatar-editor/views/AvatarEditorFigurePreviewView.tsx b/src/components/avatar-editor/views/AvatarEditorFigurePreviewView.tsx deleted file mode 100644 index d5715ac..0000000 --- a/src/components/avatar-editor/views/AvatarEditorFigurePreviewView.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { AvatarDirectionAngle } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { FigureData } from '../../../api'; -import { Base, Column, LayoutAvatarImageView } from '../../../common'; -import { AvatarEditorIcon } from './AvatarEditorIcon'; - -export interface AvatarEditorFigurePreviewViewProps -{ - figureData: FigureData; -} - -export const AvatarEditorFigurePreviewView: FC = props => -{ - const { figureData = null } = props; - const [ updateId, setUpdateId ] = useState(-1); - - const rotateFigure = (direction: number) => - { - if(direction < AvatarDirectionAngle.MIN_DIRECTION) - { - direction = (AvatarDirectionAngle.MAX_DIRECTION + (direction + 1)); - } - - if(direction > AvatarDirectionAngle.MAX_DIRECTION) - { - direction = (direction - (AvatarDirectionAngle.MAX_DIRECTION + 1)); - } - - figureData.direction = direction; - } - - useEffect(() => - { - if(!figureData) return; - - figureData.notify = () => setUpdateId(prevValue => (prevValue + 1)); - - return () => - { - figureData.notify = null; - } - }, [ figureData ] ); - - return ( - - - - - - rotateFigure(figureData.direction + 1) } /> - rotateFigure(figureData.direction - 1) } /> - - - ); -} diff --git a/src/components/avatar-editor/views/AvatarEditorIcon.tsx b/src/components/avatar-editor/views/AvatarEditorIcon.tsx deleted file mode 100644 index a05baa1..0000000 --- a/src/components/avatar-editor/views/AvatarEditorIcon.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { FC, useMemo } from 'react'; -import { Base, BaseProps } from '../../../common'; - -type AvatarIconType = 'male' | 'female' | 'clear' | 'sellable' | string; - -export interface AvatarEditorIconProps extends BaseProps -{ - icon: AvatarIconType; - selected?: boolean; -} - -export const AvatarEditorIcon: FC = props => -{ - const { icon = null, selected = false, classNames = [], children = null, ...rest } = props; - - const getClassNames = useMemo(() => - { - const newClassNames: string[] = [ 'nitro-avatar-editor-spritesheet' ]; - - if(icon && icon.length) newClassNames.push(icon + '-icon'); - - if(selected) newClassNames.push('selected'); - - if(classNames.length) newClassNames.push(...classNames); - - return newClassNames; - }, [ icon, selected, classNames ]); - - return -} diff --git a/src/components/avatar-editor/views/AvatarEditorModelView.tsx b/src/components/avatar-editor/views/AvatarEditorModelView.tsx deleted file mode 100644 index 6eb8fe3..0000000 --- a/src/components/avatar-editor/views/AvatarEditorModelView.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react'; -import { CategoryData, FigureData, IAvatarEditorCategoryModel } from '../../../api'; -import { Column, Flex, Grid } from '../../../common'; -import { AvatarEditorIcon } from './AvatarEditorIcon'; -import { AvatarEditorFigureSetView } from './figure-set/AvatarEditorFigureSetView'; -import { AvatarEditorPaletteSetView } from './palette-set/AvatarEditorPaletteSetView'; -export interface AvatarEditorModelViewProps -{ - model: IAvatarEditorCategoryModel; - gender: string; - setGender: Dispatch>; -} - -export const AvatarEditorModelView: FC = props => -{ - const { model = null, gender = null, setGender = null } = props; - const [ activeCategory, setActiveCategory ] = useState(null); - const [ maxPaletteCount, setMaxPaletteCount ] = useState(1); - - const selectCategory = useCallback((name: string) => - { - const category = model.categories.get(name); - - if(!category) return; - - category.init(); - - setActiveCategory(category); - - for(const part of category.parts) - { - if(!part || !part.isSelected) continue; - - setMaxPaletteCount(part.maxColorIndex || 1); - - break; - } - }, [ model ]); - - useEffect(() => - { - model.init(); - - for(const name of model.categories.keys()) - { - selectCategory(name); - - break; - } - }, [ model, selectCategory ]); - - if(!model || !activeCategory) return null; - - return ( - - - { model.canSetGender && - <> - setGender(FigureData.MALE) }> - - - setGender(FigureData.FEMALE) }> - - - } - { !model.canSetGender && model.categories && (model.categories.size > 0) && Array.from(model.categories.keys()).map(name => - { - const category = model.categories.get(name); - - return ( - selectCategory(name) }> - - - ); - }) } - - - - - - { (maxPaletteCount >= 1) && - } - { (maxPaletteCount === 2) && - } - - - ); -} diff --git a/src/components/avatar-editor/views/AvatarEditorWardrobeView.tsx b/src/components/avatar-editor/views/AvatarEditorWardrobeView.tsx deleted file mode 100644 index 015d3b1..0000000 --- a/src/components/avatar-editor/views/AvatarEditorWardrobeView.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { GetAvatarRenderManager, IAvatarFigureContainer, SaveWardrobeOutfitMessageComposer } from '@nitrots/nitro-renderer'; -import { Dispatch, FC, SetStateAction, useCallback, useMemo } from 'react'; -import { FigureData, GetClubMemberLevel, GetConfigurationValue, LocalizeText, SendMessageComposer } from '../../../api'; -import { AutoGrid, Base, Button, Flex, LayoutAvatarImageView, LayoutCurrencyIcon, LayoutGridItem } from '../../../common'; - -export interface AvatarEditorWardrobeViewProps -{ - figureData: FigureData; - savedFigures: [ IAvatarFigureContainer, string ][]; - setSavedFigures: Dispatch>; - loadAvatarInEditor: (figure: string, gender: string, reset?: boolean) => void; -} - -export const AvatarEditorWardrobeView: FC = props => -{ - const { figureData = null, savedFigures = [], setSavedFigures = null, loadAvatarInEditor = null } = props; - - const hcDisabled = GetConfigurationValue('hc.disabled', false); - - const wearFigureAtIndex = useCallback((index: number) => - { - if((index >= savedFigures.length) || (index < 0)) return; - - const [ figure, gender ] = savedFigures[index]; - - loadAvatarInEditor(figure.getFigureString(), gender); - }, [ savedFigures, loadAvatarInEditor ]); - - const saveFigureAtWardrobeIndex = useCallback((index: number) => - { - if(!figureData || (index >= savedFigures.length) || (index < 0)) return; - - const newFigures = [ ...savedFigures ]; - - const figure = figureData.getFigureString(); - const gender = figureData.gender; - - newFigures[index] = [ GetAvatarRenderManager().createFigureContainer(figure), gender ]; - - setSavedFigures(newFigures); - SendMessageComposer(new SaveWardrobeOutfitMessageComposer((index + 1), figure, gender)); - }, [ figureData, savedFigures, setSavedFigures ]); - - const figures = useMemo(() => - { - if(!savedFigures || !savedFigures.length) return []; - - const items: JSX.Element[] = []; - - savedFigures.forEach(([ figureContainer, gender ], index) => - { - let clubLevel = 0; - - if(figureContainer) clubLevel = GetAvatarRenderManager().getFigureClubLevel(figureContainer, gender); - - items.push( - - { figureContainer && - } - - { !hcDisabled && (clubLevel > 0) && } - - - { figureContainer && - } - - - ); - }); - - return items; - }, [ savedFigures, hcDisabled, saveFigureAtWardrobeIndex, wearFigureAtIndex ]); - - return ( - - { figures } - - ); -} diff --git a/src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetItemView.tsx b/src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetItemView.tsx deleted file mode 100644 index 3cd6383..0000000 --- a/src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetItemView.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { AvatarEditorGridPartItem, GetConfigurationValue } from '../../../../api'; -import { LayoutCurrencyIcon, LayoutGridItem, LayoutGridItemProps } from '../../../../common'; -import { AvatarEditorIcon } from '../AvatarEditorIcon'; - -export interface AvatarEditorFigureSetItemViewProps extends LayoutGridItemProps -{ - partItem: AvatarEditorGridPartItem; -} - -export const AvatarEditorFigureSetItemView: FC = props => -{ - const { partItem = null, children = null, ...rest } = props; - const [ updateId, setUpdateId ] = useState(-1); - - const hcDisabled = GetConfigurationValue('hc.disabled', false); - - useEffect(() => - { - const rerender = () => setUpdateId(prevValue => (prevValue + 1)); - - partItem.notify = rerender; - - return () => partItem.notify = null; - }, [ partItem ]); - - return ( - - { !hcDisabled && partItem.isHC && } - { partItem.isClear && } - { partItem.isSellable && } - { children } - - ); -} diff --git a/src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetView.tsx b/src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetView.tsx deleted file mode 100644 index 3755731..0000000 --- a/src/components/avatar-editor/views/figure-set/AvatarEditorFigureSetView.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Dispatch, FC, SetStateAction, useCallback, useEffect, useRef } from 'react'; -import { AvatarEditorGridPartItem, CategoryData, IAvatarEditorCategoryModel } from '../../../../api'; -import { AutoGrid } from '../../../../common'; -import { AvatarEditorFigureSetItemView } from './AvatarEditorFigureSetItemView'; - -export interface AvatarEditorFigureSetViewProps -{ - model: IAvatarEditorCategoryModel; - category: CategoryData; - setMaxPaletteCount: Dispatch>; -} - -export const AvatarEditorFigureSetView: FC = props => -{ - const { model = null, category = null, setMaxPaletteCount = null } = props; - const elementRef = useRef(null); - - const selectPart = useCallback((item: AvatarEditorGridPartItem) => - { - const index = category.parts.indexOf(item); - - if(index === -1) return; - - model.selectPart(category.name, index); - - const partItem = category.getCurrentPart(); - - setMaxPaletteCount(partItem.maxColorIndex || 1); - }, [ model, category, setMaxPaletteCount ]); - - useEffect(() => - { - if(!model || !category || !elementRef || !elementRef.current) return; - - elementRef.current.scrollTop = 0; - }, [ model, category ]); - - return ( - - { (category.parts.length > 0) && category.parts.map((item, index) => - selectPart(item) } />) } - - ); -} diff --git a/src/components/avatar-editor/views/figure-set/index.ts b/src/components/avatar-editor/views/figure-set/index.ts deleted file mode 100644 index 0c5880b..0000000 --- a/src/components/avatar-editor/views/figure-set/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './AvatarEditorFigureSetItemView'; -export * from './AvatarEditorFigureSetView'; diff --git a/src/components/avatar-editor/views/index.ts b/src/components/avatar-editor/views/index.ts deleted file mode 100644 index a92b3b7..0000000 --- a/src/components/avatar-editor/views/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './AvatarEditorFigurePreviewView'; -export * from './AvatarEditorIcon'; -export * from './AvatarEditorModelView'; -export * from './AvatarEditorWardrobeView'; -export * from './figure-set'; -export * from './palette-set'; diff --git a/src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetItemView.tsx b/src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetItemView.tsx deleted file mode 100644 index 7868057..0000000 --- a/src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetItemView.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { AvatarEditorGridColorItem, GetConfigurationValue } from '../../../../api'; -import { LayoutCurrencyIcon, LayoutGridItem, LayoutGridItemProps } from '../../../../common'; - -export interface AvatarEditorPaletteSetItemProps extends LayoutGridItemProps -{ - colorItem: AvatarEditorGridColorItem; -} - -export const AvatarEditorPaletteSetItem: FC = props => -{ - const { colorItem = null, children = null, ...rest } = props; - const [ updateId, setUpdateId ] = useState(-1); - - const hcDisabled = GetConfigurationValue('hc.disabled', false); - - useEffect(() => - { - const rerender = () => setUpdateId(prevValue => (prevValue + 1)); - - colorItem.notify = rerender; - - return () => colorItem.notify = null; - }, [ colorItem ]); - - return ( - - { !hcDisabled && colorItem.isHC && } - { children } - - ); -} diff --git a/src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.tsx b/src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.tsx deleted file mode 100644 index c55dcb4..0000000 --- a/src/components/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { FC, useCallback, useEffect, useRef } from 'react'; -import { AvatarEditorGridColorItem, CategoryData, IAvatarEditorCategoryModel } from '../../../../api'; -import { AutoGrid } from '../../../../common'; -import { AvatarEditorPaletteSetItem } from './AvatarEditorPaletteSetItemView'; - -export interface AvatarEditorPaletteSetViewProps -{ - model: IAvatarEditorCategoryModel; - category: CategoryData; - paletteSet: AvatarEditorGridColorItem[]; - paletteIndex: number; -} - -export const AvatarEditorPaletteSetView: FC = props => -{ - const { model = null, category = null, paletteSet = [], paletteIndex = -1 } = props; - const elementRef = useRef(null); - - const selectColor = useCallback((item: AvatarEditorGridColorItem) => - { - const index = paletteSet.indexOf(item); - - if(index === -1) return; - - model.selectColor(category.name, index, paletteIndex); - }, [ model, category, paletteSet, paletteIndex ]); - - useEffect(() => - { - if(!model || !category || !elementRef || !elementRef.current) return; - - elementRef.current.scrollTop = 0; - }, [ model, category ]); - - return ( - - { (paletteSet.length > 0) && paletteSet.map((item, index) => - selectColor(item) } />) } - - ); -} diff --git a/src/components/avatar-editor/views/palette-set/index.ts b/src/components/avatar-editor/views/palette-set/index.ts deleted file mode 100644 index 977e5b9..0000000 --- a/src/components/avatar-editor/views/palette-set/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './AvatarEditorPaletteSetItemView'; -export * from './AvatarEditorPaletteSetView'; diff --git a/src/components/camera/CameraWidgetView.scss b/src/components/camera/CameraWidgetView.scss deleted file mode 100644 index aecd0b1..0000000 --- a/src/components/camera/CameraWidgetView.scss +++ /dev/null @@ -1,133 +0,0 @@ -.nitro-camera-capture { - position: relative; - - .header-close { - top: 8px; - right: 8px; - border-radius: $border-radius; - box-shadow: 0 0 0 1.5px $white; - border: 2px solid #921911; - background: repeating-linear-gradient( - rgba(245, 80, 65, 1), - rgba(245, 80, 65, 1) 50%, - rgba(194, 48, 39, 1) 50%, - rgba(194, 48, 39, 1) 100% - ); - cursor: pointer; - line-height: 1; - padding: 1px 3px; - - &:hover { - filter: brightness(1.2); - } - - &:active { - filter: brightness(0.8); - } - } - - .camera-area { - position: absolute; - top: 37px; - left: 10px; - width: 320px; - height: 320px; - } - - .camera-canvas { - position: relative; - width: 340px; - height: 462px; - background-image: url('@/assets/images/room-widgets/camera-widget/camera-spritesheet.png'); - background-position: -1px -1px; - z-index: 2; - - .camera-button { - width: 94px; - height: 94px; - cursor: pointer; - margin-top: 362px; - - background-image: url('@/assets/images/room-widgets/camera-widget/camera-spritesheet.png'); - background-position: -343px -321px; - - &:hover { - background-position: -535px -321px; - } - - &:active { - background-position: -439px -321px; - } - } - - .camera-view-finder { - background-image: url('@/assets/images/room-widgets/camera-widget/camera-spritesheet.png'); - background-position: -343px -1px; - } - - .camera-frame { - .camera-frame-preview-actions { - background: rgba(0, 0, 0, 0.5); - } - } - } - - .camera-roll { - width: 330px; - background: #bab8b4; - border-bottom-left-radius: 10px; - border-bottom-right-radius: 10px; - border: 1px solid black; - box-shadow: inset 1px 0px white, inset -1px -1px white; - - img { - width: 56px; - height: 56px; - border: 1px solid black; - object-fit: contain; - image-rendering: initial; - } - } -} - -.nitro-camera-editor { - width: $camera-editor-width; - height: $camera-editor-height; - - .picture-preview { - width: 320px; - height: 320px; - } - - .layout-grid-item { - height: 60px !important; - max-height: 60px !important; - } - - .effect-thumbnail-image { - img { - width: 50px; - height: 50px; - image-rendering: auto; - object-fit: contain; - } - } - - .remove-effect { - position: absolute; - top: 1px; - right: 1px; - padding: 2px; - font-size: 10px; - min-height: unset; - } -} - -.nitro-camera-checkout { - width: $camera-checkout-width; - - .picture-preview { - width: 320px; - height: 320px; - } -} diff --git a/src/components/camera/CameraWidgetView.tsx b/src/components/camera/CameraWidgetView.tsx deleted file mode 100644 index 62af9ca..0000000 --- a/src/components/camera/CameraWidgetView.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { AddLinkEventTracker, ILinkEventTracker, RemoveLinkEventTracker, RoomSessionEvent } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { useCamera, useNitroEvent } from '../../hooks'; -import { CameraWidgetCaptureView } from './views/CameraWidgetCaptureView'; -import { CameraWidgetCheckoutView } from './views/CameraWidgetCheckoutView'; -import { CameraWidgetEditorView } from './views/editor/CameraWidgetEditorView'; - -const MODE_NONE: number = 0; -const MODE_CAPTURE: number = 1; -const MODE_EDITOR: number = 2; -const MODE_CHECKOUT: number = 3; - -export const CameraWidgetView: FC<{}> = props => -{ - const [ mode, setMode ] = useState(MODE_NONE); - const [ base64Url, setSavedPictureUrl ] = useState(null); - const { availableEffects = [], selectedPictureIndex = -1, cameraRoll = [], setCameraRoll = null, myLevel = 0, price = { credits: 0, duckets: 0, publishDucketPrice: 0 }} = useCamera(); - - const processAction = (type: string) => - { - switch(type) - { - case 'close': - setMode(MODE_NONE); - return; - case 'edit': - setMode(MODE_EDITOR); - return; - case 'delete': - setCameraRoll(prevValue => - { - const clone = [ ...prevValue ]; - - clone.splice(selectedPictureIndex, 1); - - return clone; - }); - return; - case 'editor_cancel': - setMode(MODE_CAPTURE); - return; - } - } - - const checkoutPictureUrl = (pictureUrl: string) => - { - setSavedPictureUrl(pictureUrl); - setMode(MODE_CHECKOUT); - } - - useNitroEvent(RoomSessionEvent.ENDED, event => setMode(MODE_NONE)); - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setMode(MODE_CAPTURE); - return; - case 'hide': - setMode(MODE_NONE); - return; - case 'toggle': - setMode(prevValue => - { - if(!prevValue) return MODE_CAPTURE; - else return MODE_NONE; - }); - return; - } - }, - eventUrlPrefix: 'camera/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, []); - - if(mode === MODE_NONE) return null; - - return ( - <> - { (mode === MODE_CAPTURE) && processAction('close') } onEdit={ () => processAction('edit') } onDelete={ () => processAction('delete') } /> } - { (mode === MODE_EDITOR) && processAction('close') } onCancel={ () => processAction('editor_cancel') } onCheckout={ checkoutPictureUrl } availableEffects={ availableEffects } /> } - { (mode === MODE_CHECKOUT) && processAction('close') } onCancelClick={ () => processAction('editor_cancel') } price={ price }> } - - ); -} diff --git a/src/components/camera/index.ts b/src/components/camera/index.ts deleted file mode 100644 index 43c10cd..0000000 --- a/src/components/camera/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './CameraWidgetView'; -export * from './views'; -export * from './views/editor'; -export * from './views/editor/effect-list'; diff --git a/src/components/camera/views/CameraWidgetCaptureView.tsx b/src/components/camera/views/CameraWidgetCaptureView.tsx deleted file mode 100644 index ef92884..0000000 --- a/src/components/camera/views/CameraWidgetCaptureView.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { GetRoomEngine, NitroRectangle, TextureUtils } from '@nitrots/nitro-renderer'; -import { FC, useRef } from 'react'; -import { FaTimes } from 'react-icons/fa'; -import { CameraPicture, GetRoomSession, LocalizeText, PlaySound, SoundNames } from '../../../api'; -import { Column, DraggableWindow, Flex } from '../../../common'; -import { useCamera, useNotification } from '../../../hooks'; - -export interface CameraWidgetCaptureViewProps -{ - onClose: () => void; - onEdit: () => void; - onDelete: () => void; -} - -const CAMERA_ROLL_LIMIT: number = 5; - -export const CameraWidgetCaptureView: FC = props => -{ - const { onClose = null, onEdit = null, onDelete = null } = props; - const { cameraRoll = null, setCameraRoll = null, selectedPictureIndex = -1, setSelectedPictureIndex = null } = useCamera(); - const { simpleAlert = null } = useNotification(); - const elementRef = useRef(); - - const selectedPicture = ((selectedPictureIndex > -1) ? cameraRoll[selectedPictureIndex] : null); - - const getCameraBounds = () => - { - if(!elementRef || !elementRef.current) return null; - - const frameBounds = elementRef.current.getBoundingClientRect(); - - return new NitroRectangle(Math.floor(frameBounds.x), Math.floor(frameBounds.y), Math.floor(frameBounds.width), Math.floor(frameBounds.height)); - } - - const takePicture = async () => - { - if(selectedPictureIndex > -1) - { - setSelectedPictureIndex(-1); - return; - } - - const texture = GetRoomEngine().createTextureFromRoom(GetRoomSession().roomId, 1, getCameraBounds()); - - const clone = [ ...cameraRoll ]; - - if(clone.length >= CAMERA_ROLL_LIMIT) - { - simpleAlert(LocalizeText('camera.full.body')); - - clone.pop(); - } - - PlaySound(SoundNames.CAMERA_SHUTTER); - clone.push(new CameraPicture(texture, await TextureUtils.generateImageUrl(texture))); - - setCameraRoll(clone); - } - - return ( - - - { selectedPicture && } -
-
- -
- { !selectedPicture &&
} - { selectedPicture && -
-
- - -
-
} -
-
-
-
- { (cameraRoll.length > 0) && - - { cameraRoll.map((picture, index) => - { - return setSelectedPictureIndex(index) } />; - }) } - } - - - ); -} diff --git a/src/components/camera/views/CameraWidgetCheckoutView.tsx b/src/components/camera/views/CameraWidgetCheckoutView.tsx deleted file mode 100644 index 100e076..0000000 --- a/src/components/camera/views/CameraWidgetCheckoutView.tsx +++ /dev/null @@ -1,159 +0,0 @@ -import { CameraPublishStatusMessageEvent, CameraPurchaseOKMessageEvent, CameraStorageUrlMessageEvent, CreateLinkEvent, GetRoomEngine, PublishPhotoMessageComposer, PurchasePhotoMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useMemo, useState } from 'react'; -import { GetConfigurationValue, LocalizeText, SendMessageComposer } from '../../../api'; -import { Button, Column, Flex, LayoutCurrencyIcon, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common'; -import { useMessageEvent } from '../../../hooks'; - -export interface CameraWidgetCheckoutViewProps -{ - base64Url: string; - onCloseClick: () => void; - onCancelClick: () => void; - price: { credits: number, duckets: number, publishDucketPrice: number }; -} - -export const CameraWidgetCheckoutView: FC = props => -{ - const { base64Url = null, onCloseClick = null, onCancelClick = null, price = null } = props; - const [ pictureUrl, setPictureUrl ] = useState(null); - const [ publishUrl, setPublishUrl ] = useState(null); - const [ picturesBought, setPicturesBought ] = useState(0); - const [ wasPicturePublished, setWasPicturePublished ] = useState(false); - const [ isWaiting, setIsWaiting ] = useState(false); - const [ publishCooldown, setPublishCooldown ] = useState(0); - - const publishDisabled = useMemo(() => GetConfigurationValue('camera.publish.disabled', false), []); - - useMessageEvent(CameraPurchaseOKMessageEvent, event => - { - setPicturesBought(value => (value + 1)); - setIsWaiting(false); - }); - - useMessageEvent(CameraPublishStatusMessageEvent, event => - { - const parser = event.getParser(); - - setPublishUrl(parser.extraDataId); - setPublishCooldown(parser.secondsToWait); - setWasPicturePublished(parser.ok); - setIsWaiting(false); - }); - - useMessageEvent(CameraStorageUrlMessageEvent, event => - { - const parser = event.getParser(); - - setPictureUrl(GetConfigurationValue('camera.url') + '/' + parser.url); - }); - - const processAction = (type: string, value: string | number = null) => - { - switch(type) - { - case 'close': - onCloseClick(); - return; - case 'buy': - if(isWaiting) return; - - setIsWaiting(true); - SendMessageComposer(new PurchasePhotoMessageComposer('')); - return; - case 'publish': - if(isWaiting) return; - - setIsWaiting(true); - SendMessageComposer(new PublishPhotoMessageComposer()); - return; - case 'cancel': - onCancelClick(); - return; - } - } - - useEffect(() => - { - if(!base64Url) return; - - GetRoomEngine().saveBase64AsScreenshot(base64Url); - }, [ base64Url ]); - - if(!price) return null; - - return ( - - processAction('close') } /> - - - { (pictureUrl && pictureUrl.length) && - } - { (!pictureUrl || !pictureUrl.length) && - - { LocalizeText('camera.loading') } - } - - - - - { LocalizeText('camera.purchase.header') } - - { ((price.credits > 0) || (price.duckets > 0)) && - - { LocalizeText('catalog.purchase.confirmation.dialog.cost') } - { (price.credits > 0) && - - { price.credits } - - } - { (price.duckets > 0) && - - { price.duckets } - - } - } - { (picturesBought > 0) && - - { LocalizeText('camera.purchase.count.info') } { picturesBought } - CreateLinkEvent('inventory/toggle') }>{ LocalizeText('camera.open.inventory') } - } - - - - - - { !publishDisabled && - - - - { LocalizeText(wasPicturePublished ? 'camera.publish.successful' : 'camera.publish.explanation') } - - - { LocalizeText(wasPicturePublished ? 'camera.publish.success.short.info' : 'camera.publish.detailed.explanation') } - - { wasPicturePublished &&
{ LocalizeText('camera.link.to.published') } } - { !wasPicturePublished && (price.publishDucketPrice > 0) && - - { LocalizeText('catalog.purchase.confirmation.dialog.cost') } - - { price.publishDucketPrice } - - - } - { (publishCooldown > 0) &&
{ LocalizeText('camera.publish.wait', [ 'minutes' ], [ Math.ceil( publishCooldown / 60).toString() ]) }
} - - { !wasPicturePublished && - - - } - } - { LocalizeText('camera.warning.disclaimer') } - - - - - - ); -} diff --git a/src/components/camera/views/CameraWidgetShowPhotoView.tsx b/src/components/camera/views/CameraWidgetShowPhotoView.tsx deleted file mode 100644 index 8614695..0000000 --- a/src/components/camera/views/CameraWidgetShowPhotoView.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { FaArrowLeft, FaArrowRight } from 'react-icons/fa'; -import { GetUserProfile, IPhotoData, LocalizeText } from '../../../api'; -import { Flex, Grid, Text } from '../../../common'; - -export interface CameraWidgetShowPhotoViewProps -{ - currentIndex: number; - currentPhotos: IPhotoData[]; -} - -export const CameraWidgetShowPhotoView: FC = props => -{ - const { currentIndex = -1, currentPhotos = null } = props; - const [ imageIndex, setImageIndex ] = useState(0); - - const currentImage = (currentPhotos && currentPhotos.length) ? currentPhotos[imageIndex] : null; - - const next = () => - { - setImageIndex(prevValue => - { - let newIndex = (prevValue + 1); - - if(newIndex >= currentPhotos.length) newIndex = 0; - - return newIndex; - }); - } - - const previous = () => - { - setImageIndex(prevValue => - { - let newIndex = (prevValue - 1); - - if(newIndex < 0) newIndex = (currentPhotos.length - 1); - - return newIndex; - }); - } - - useEffect(() => - { - setImageIndex(currentIndex); - }, [ currentIndex ]); - - if(!currentImage) return null; - - return ( - - - { !currentImage.w && - { LocalizeText('camera.loading') } } - - { currentImage.m && currentImage.m.length && - { currentImage.m } } - - { (currentImage.n || '') } - { new Date(currentImage.t * 1000).toLocaleDateString() } - - { (currentPhotos.length > 1) && - - - GetUserProfile(currentImage.oi) }>{ currentImage.o } - - - } - - ); -} diff --git a/src/components/camera/views/editor/CameraWidgetEditorView.tsx b/src/components/camera/views/editor/CameraWidgetEditorView.tsx deleted file mode 100644 index 1946c64..0000000 --- a/src/components/camera/views/editor/CameraWidgetEditorView.tsx +++ /dev/null @@ -1,243 +0,0 @@ -import { GetRoomCameraWidgetManager, IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect, RoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { FaSave, FaSearchMinus, FaSearchPlus, FaTrash } from 'react-icons/fa'; -import ReactSlider from 'react-slider'; -import { CameraEditorTabs, CameraPicture, CameraPictureThumbnail, LocalizeText } from '../../../../api'; -import { Button, ButtonGroup, Column, Flex, Grid, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView, Text } from '../../../../common'; -import { CameraWidgetEffectListView } from './effect-list'; - -export interface CameraWidgetEditorViewProps -{ - picture: CameraPicture; - availableEffects: IRoomCameraWidgetEffect[]; - myLevel: number; - onClose: () => void; - onCancel: () => void; - onCheckout: (pictureUrl: string) => void; -} - -const TABS: string[] = [ CameraEditorTabs.COLORMATRIX, CameraEditorTabs.COMPOSITE ]; - -export const CameraWidgetEditorView: FC = props => -{ - const { picture = null, availableEffects = null, myLevel = 1, onClose = null, onCancel = null, onCheckout = null } = props; - const [ currentTab, setCurrentTab ] = useState(TABS[0]); - const [ selectedEffectName, setSelectedEffectName ] = useState(null); - const [ selectedEffects, setSelectedEffects ] = useState([]); - const [ effectsThumbnails, setEffectsThumbnails ] = useState([]); - const [ isZoomed, setIsZoomed ] = useState(false); - const [ currentPictureUrl, setCurrentPictureUrl ] = useState(''); - - const getColorMatrixEffects = useMemo(() => - { - return availableEffects.filter(effect => effect.colorMatrix); - }, [ availableEffects ]); - - const getCompositeEffects = useMemo(() => - { - return availableEffects.filter(effect => effect.texture); - }, [ availableEffects ]); - - const getEffectList = useCallback(() => - { - if(currentTab === CameraEditorTabs.COLORMATRIX) - { - return getColorMatrixEffects; - } - - return getCompositeEffects; - }, [ currentTab, getColorMatrixEffects, getCompositeEffects ]); - - const getSelectedEffectIndex = useCallback((name: string) => - { - if(!name || !name.length || !selectedEffects || !selectedEffects.length) return -1; - - return selectedEffects.findIndex(effect => (effect.effect.name === name)); - }, [ selectedEffects ]) - - const getCurrentEffectIndex = useMemo(() => - { - return getSelectedEffectIndex(selectedEffectName) - }, [ selectedEffectName, getSelectedEffectIndex ]) - - const getCurrentEffect = useMemo(() => - { - if(!selectedEffectName) return null; - - return (selectedEffects[getCurrentEffectIndex] || null); - }, [ selectedEffectName, getCurrentEffectIndex, selectedEffects ]); - - const setSelectedEffectAlpha = useCallback((alpha: number) => - { - const index = getCurrentEffectIndex; - - if(index === -1) return; - - setSelectedEffects(prevValue => - { - const clone = [ ...prevValue ]; - const currentEffect = clone[index]; - - clone[getCurrentEffectIndex] = new RoomCameraWidgetSelectedEffect(currentEffect.effect, alpha); - - return clone; - }); - }, [ getCurrentEffectIndex, setSelectedEffects ]); - - const processAction = useCallback((type: string, effectName: string = null) => - { - switch(type) - { - case 'close': - onClose(); - return; - case 'cancel': - onCancel(); - return; - case 'checkout': - onCheckout(currentPictureUrl); - return; - case 'change_tab': - setCurrentTab(String(effectName)); - return; - case 'select_effect': { - let existingIndex = getSelectedEffectIndex(effectName); - - if(existingIndex >= 0) return; - - const effect = availableEffects.find(effect => (effect.name === effectName)); - - if(!effect) return; - - setSelectedEffects(prevValue => - { - return [ ...prevValue, new RoomCameraWidgetSelectedEffect(effect, 1) ]; - }); - - setSelectedEffectName(effect.name); - return; - } - case 'remove_effect': { - let existingIndex = getSelectedEffectIndex(effectName); - - if(existingIndex === -1) return; - - setSelectedEffects(prevValue => - { - const clone = [ ...prevValue ]; - - clone.splice(existingIndex, 1); - - return clone; - }); - - if(selectedEffectName === effectName) setSelectedEffectName(null); - return; - } - case 'clear_effects': - setSelectedEffectName(null); - setSelectedEffects([]); - return; - case 'download': { - (async () => - { - const image = new Image(); - - image.src = currentPictureUrl - - const newWindow = window.open(''); - newWindow.document.write(image.outerHTML); - })(); - return; - } - case 'zoom': - setIsZoomed(!isZoomed); - return; - } - }, [ isZoomed, availableEffects, selectedEffectName, currentPictureUrl, getSelectedEffectIndex, onCancel, onCheckout, onClose, setIsZoomed, setSelectedEffects ]); - - useEffect(() => - { - (async () => - { - const thumbnails: CameraPictureThumbnail[] = []; - - for await (const effect of availableEffects) - { - const image = await GetRoomCameraWidgetManager().applyEffects(picture.texture, [ new RoomCameraWidgetSelectedEffect(effect, 1) ], false); - - thumbnails.push(new CameraPictureThumbnail(effect.name, image.src)); - } - - setEffectsThumbnails(thumbnails); - })(); - }, [ picture, availableEffects ]); - - useEffect(() => - { - (async () => - { - const imageUrl = await GetRoomCameraWidgetManager().applyEffects(picture.texture, selectedEffects, isZoomed); - - setCurrentPictureUrl(imageUrl.src); - })(); - }, [ picture, selectedEffects, isZoomed ]); - - return ( - - processAction('close') } /> - - { TABS.map(tab => - { - return processAction('change_tab', tab) }> - }) } - - - - - - - - - - { selectedEffectName && - - { LocalizeText('camera.effect.name.' + selectedEffectName) } - setSelectedEffectAlpha(event) } - renderThumb={ (props, state) =>
{ state.valueNow }
} /> -
} -
- - - - - - - - - - - -
-
-
-
- ); -} diff --git a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListItemView.tsx b/src/components/camera/views/editor/effect-list/CameraWidgetEffectListItemView.tsx deleted file mode 100644 index cac3a34..0000000 --- a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListItemView.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { IRoomCameraWidgetEffect } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { FaLock, FaTimes } from 'react-icons/fa'; -import { LocalizeText } from '../../../../../api'; -import { Button, LayoutGridItem, Text } from '../../../../../common'; - -export interface CameraWidgetEffectListItemViewProps -{ - effect: IRoomCameraWidgetEffect; - thumbnailUrl: string; - isActive: boolean; - isLocked: boolean; - selectEffect: () => void; - removeEffect: () => void; -} - -export const CameraWidgetEffectListItemView: FC = props => -{ - const { effect = null, thumbnailUrl = null, isActive = false, isLocked = false, selectEffect = null, removeEffect = null } = props; - - return ( - (!isActive && selectEffect()) }> - { isActive && - } - { !isLocked && (thumbnailUrl && thumbnailUrl.length > 0) && -
- -
} - { isLocked && - -
- -
- { effect.minLevel } -
} -
- ); -} diff --git a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx b/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx deleted file mode 100644 index 3f67cea..0000000 --- a/src/components/camera/views/editor/effect-list/CameraWidgetEffectListView.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { CameraPictureThumbnail } from '../../../../../api'; -import { Grid } from '../../../../../common'; -import { CameraWidgetEffectListItemView } from './CameraWidgetEffectListItemView'; - -export interface CameraWidgetEffectListViewProps -{ - myLevel: number; - selectedEffects: IRoomCameraWidgetSelectedEffect[]; - effects: IRoomCameraWidgetEffect[]; - thumbnails: CameraPictureThumbnail[]; - processAction: (type: string, name: string) => void; -} - -export const CameraWidgetEffectListView: FC = props => -{ - const { myLevel = 0, selectedEffects = [], effects = [], thumbnails = [], processAction = null } = props; - - return ( - - { effects && (effects.length > 0) && effects.map((effect, index) => - { - const thumbnailUrl = (thumbnails.find(thumbnail => (thumbnail.effectName === effect.name))); - const isActive = (selectedEffects.findIndex(selectedEffect => (selectedEffect.effect.name === effect.name)) > -1); - - return myLevel) } selectEffect={ () => processAction('select_effect', effect.name) } removeEffect={ () => processAction('remove_effect', effect.name) } /> - }) } - - ); -} diff --git a/src/components/camera/views/editor/effect-list/index.ts b/src/components/camera/views/editor/effect-list/index.ts deleted file mode 100644 index 7a4ebdb..0000000 --- a/src/components/camera/views/editor/effect-list/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './CameraWidgetEffectListItemView'; -export * from './CameraWidgetEffectListView'; diff --git a/src/components/camera/views/editor/index.ts b/src/components/camera/views/editor/index.ts deleted file mode 100644 index 49c615e..0000000 --- a/src/components/camera/views/editor/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './CameraWidgetEditorView'; -export * from './effect-list'; diff --git a/src/components/camera/views/index.ts b/src/components/camera/views/index.ts deleted file mode 100644 index cf44449..0000000 --- a/src/components/camera/views/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './CameraWidgetCaptureView'; -export * from './CameraWidgetCheckoutView'; -export * from './CameraWidgetShowPhotoView'; -export * from './editor'; -export * from './editor/effect-list'; diff --git a/src/components/campaign/CalendarItemView.tsx b/src/components/campaign/CalendarItemView.tsx deleted file mode 100644 index 040414b..0000000 --- a/src/components/campaign/CalendarItemView.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { CalendarItemState, GetConfigurationValue, ICalendarItem } from '../../api'; -import { Base, Column, Flex, LayoutImage } from '../../common'; - -interface CalendarItemViewProps -{ - itemId: number; - state: number; - active?: boolean; - product?: ICalendarItem; - onClick: (itemId: number) => void; -} - -export const CalendarItemView: FC = props => -{ - const { itemId = -1, state = null, product = null, active = false, onClick = null } = props; - - const getFurnitureIcon = (name: string) => - { - let furniData = GetSessionDataManager().getFloorItemDataByName(name); - let url = null; - - if(furniData) url = GetRoomEngine().getFurnitureFloorIconUrl(furniData.id); - else - { - furniData = GetSessionDataManager().getWallItemDataByName(name); - - if(furniData) url = GetRoomEngine().getFurnitureWallIconUrl(furniData.id); - } - - return url; - } - - return ( - onClick(itemId) }> - { (state === CalendarItemState.STATE_UNLOCKED) && - - - { product && - ('image.library.url') + product.customImage : getFurnitureIcon(product.productName) } /> } - - } - { (state !== CalendarItemState.STATE_UNLOCKED) && - - { (state === CalendarItemState.STATE_LOCKED_AVAILABLE) && - } - { ((state === CalendarItemState.STATE_LOCKED_EXPIRED) || (state === CalendarItemState.STATE_LOCKED_FUTURE)) && - } - } - - ); -} diff --git a/src/components/campaign/CalendarView.tsx b/src/components/campaign/CalendarView.tsx deleted file mode 100644 index 3178f91..0000000 --- a/src/components/campaign/CalendarView.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import { GetSessionDataManager } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { CalendarItemState, ICalendarItem, LocalizeText } from '../../api'; -import { Base, Button, Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common'; -import { CalendarItemView } from './CalendarItemView'; - -interface CalendarViewProps -{ - onClose(): void; - openPackage(id: number, asStaff: boolean): void; - receivedProducts: Map; - campaignName: string; - currentDay: number; - numDays: number; - openedDays: number[]; - missedDays: number[]; -} - -const TOTAL_SHOWN_ITEMS = 5; - -export const CalendarView: FC = props => -{ - const { onClose = null, campaignName = null, currentDay = null, numDays = null, missedDays = null, openedDays = null, openPackage = null, receivedProducts = null } = props; - const [ selectedDay, setSelectedDay ] = useState(currentDay); - const [ index, setIndex ] = useState(Math.max(0, (selectedDay - 1))); - - const getDayState = (day: number) => - { - if(openedDays.includes(day)) return CalendarItemState.STATE_UNLOCKED; - - if(day > currentDay) return CalendarItemState.STATE_LOCKED_FUTURE; - - if(missedDays.includes(day)) return CalendarItemState.STATE_LOCKED_EXPIRED; - - return CalendarItemState.STATE_LOCKED_AVAILABLE; - } - - const dayMessage = (day: number) => - { - const state = getDayState(day); - - switch(state) - { - case CalendarItemState.STATE_UNLOCKED: - return LocalizeText('campaign.calendar.info.unlocked'); - case CalendarItemState.STATE_LOCKED_FUTURE: - return LocalizeText('campaign.calendar.info.future'); - case CalendarItemState.STATE_LOCKED_EXPIRED: - return LocalizeText('campaign.calendar.info.expired'); - default: - return LocalizeText('campaign.calendar.info.available.desktop'); - } - } - - const onClickNext = () => - { - const nextDay = (selectedDay + 1); - - if(nextDay === numDays) return; - - setSelectedDay(nextDay); - - if((index + TOTAL_SHOWN_ITEMS) < (nextDay + 1)) setIndex(index + 1); - } - - const onClickPrev = () => - { - const prevDay = (selectedDay - 1); - - if(prevDay < 0) return; - - setSelectedDay(prevDay); - - if(index > prevDay) setIndex(index - 1); - } - - const onClickItem = (item: number) => - { - if(selectedDay === item) - { - const state = getDayState(item); - - if(state === CalendarItemState.STATE_LOCKED_AVAILABLE) openPackage(item, false); - - return; - } - - setSelectedDay(item); - } - - const forceOpen = () => - { - const id = selectedDay; - const state = getDayState(id); - - if(state !== CalendarItemState.STATE_UNLOCKED) openPackage(id, true); - } - - return ( - - - - - - - - - { LocalizeText('campaign.calendar.heading.day', [ 'number' ], [ (selectedDay + 1).toString() ]) } - { dayMessage(selectedDay) } - -
- { GetSessionDataManager().isModerator && - } -
-
-
- -
- - - - - - - { [ ...Array(TOTAL_SHOWN_ITEMS) ].map((e, i) => - { - const day = (index + i); - - return ( - - - - ); - }) } - - - - - - -
-
- ) -} diff --git a/src/components/campaign/CampaignView.scss b/src/components/campaign/CampaignView.scss deleted file mode 100644 index cea973f..0000000 --- a/src/components/campaign/CampaignView.scss +++ /dev/null @@ -1,71 +0,0 @@ -.nitro-campaign-calendar { - width: $nitro-calendar-width; - height: $nitro-calendar-height; - - .calendar-item { - filter: brightness(80%); - - &.active { - filter: brightness(100%); - } - } -} - -.campaign-spritesheet { - display: block; - background: transparent url('@/assets/images/campaign/campaign_spritesheet.png') no-repeat; - - &.available { - width: 69px; - height: 78px; - background-position: -5px -5px; - } - - &.campaign-day-generic-bg { - max-width: 202px; - height: 447px; - background-position: -84px -5px; - } - - &.campaign-opened { - width: 96px; - height: 66px; - background-position: -296px -5px; - } - - &.locked { - width: 42px; - height: 42px; - background-position: -296px -81px; - } - - &.locked-bg { - width: 132px; - height: 132px; - background-position: -402px -5px; - } - - &.next { - width: 33px; - height: 34px; - background-position: -5px -147px; - } - - &.prev { - width: 33px; - height: 34px; - background-position: -296px -147px; - } - - &.unavailable { - width: 68px; - height: 78px; - background-position: -339px -147px; - } - - &.unlocked-bg { - width: 190px; - height: 189px; - background-position: -296px -235px; - } -} diff --git a/src/components/campaign/CampaignView.tsx b/src/components/campaign/CampaignView.tsx deleted file mode 100644 index 5e10927..0000000 --- a/src/components/campaign/CampaignView.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { AddLinkEventTracker, CampaignCalendarData, CampaignCalendarDataMessageEvent, CampaignCalendarDoorOpenedMessageEvent, ILinkEventTracker, OpenCampaignCalendarDoorAsStaffComposer, OpenCampaignCalendarDoorComposer, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { CalendarItem, SendMessageComposer } from '../../api'; -import { useMessageEvent } from '../../hooks'; -import { CalendarView } from './CalendarView'; - -export const CampaignView: FC<{}> = props => -{ - const [ calendarData, setCalendarData ] = useState(null); - const [ lastOpenAttempt, setLastOpenAttempt ] = useState(-1); - const [ receivedProducts, setReceivedProducts ] = useState>(new Map()); - const [ isCalendarOpen, setCalendarOpen ] = useState(false); - - const openPackage = (id: number, asStaff = false) => - { - if(!calendarData) return; - - setLastOpenAttempt(id); - - if(asStaff) - { - SendMessageComposer(new OpenCampaignCalendarDoorAsStaffComposer(calendarData.campaignName, id)); - } - - else - { - SendMessageComposer(new OpenCampaignCalendarDoorComposer(calendarData.campaignName, id)); - } - } - - useMessageEvent(CampaignCalendarDataMessageEvent, event => - { - const parser = event.getParser(); - - if(!parser) return; - - setCalendarData(parser.calendarData); - }); - - useMessageEvent(CampaignCalendarDoorOpenedMessageEvent, event => - { - const parser = event.getParser(); - - if(!parser) return; - - const lastAttempt = lastOpenAttempt; - - if(parser.doorOpened) - { - setCalendarData(prev => - { - const copy = prev.clone(); - copy.openedDays.push(lastOpenAttempt); - - return copy; - }); - - setReceivedProducts(prev => - { - const copy = new Map(prev); - copy.set(lastAttempt, new CalendarItem(parser.productName, parser.customImage,parser.furnitureClassName)); - - return copy; - }); - } - - setLastOpenAttempt(-1); - }); - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const value = url.split('/'); - - if(value.length < 2) return; - - switch(value[1]) - { - case 'calendar': - setCalendarOpen(true); - break; - } - }, - eventUrlPrefix: 'openView/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, []); - - return ( - <> - { (calendarData && isCalendarOpen) && - setCalendarOpen(false) } campaignName={ calendarData.campaignName } currentDay={ calendarData.currentDay } numDays={ calendarData.campaignDays } openedDays={ calendarData.openedDays } missedDays={ calendarData.missedDays } openPackage={ openPackage } receivedProducts={ receivedProducts } /> - } - - ) -} diff --git a/src/components/catalog/CatalogView.scss b/src/components/catalog/CatalogView.scss deleted file mode 100644 index 824ddb7..0000000 --- a/src/components/catalog/CatalogView.scss +++ /dev/null @@ -1,158 +0,0 @@ -.nitro-catalog { - width: $catalog-width; - height: $catalog-height; - - font[size='16'] { - font-size: 20px; - } - - .catalog-search-button { - min-width: 30px; - width: 30px; - } - - .quantity-input { - min-height: 17px; - height: 17px; - width: 28px; - padding: 0 4px; - text-align: right; - } -} - -.nitro-catalog-gift { - width: 325px; - - .gift-preview { - width: 80px; - height: 80px; - overflow: hidden; - display: flex; - justify-content: center; - align-items: center; - } - - .gift-color { - width: 15px; - height: 15px; - border-radius: $border-radius; - } -} - -.nitro-catalog-navigation-grid-container { - border-color: #b6bec5 !important; - background-color: #cdd3d9; - border: 2px solid; - - .nitro-catalog-navigation-section { - display: grid; - - .nitro-catalog-navigation-section { - padding-left: 5px; - border-left: 2px solid #b6bec5; - } - } - - .layout-grid-item { - font-size: $font-size-sm; - height: 23px !important; - border-color: unset !important; - background-color: #cdd3d9; - border: 0 !important; - padding: 1px 3px; - - .svg-inline--fa { - color: $black; - font-size: 10px; - padding: 1px; - } - } -} - -.nitro-catalog-layout-info-loyalty { - .info-loyalty-content { - background-repeat: no-repeat; - background-position: top right; - background-image: url('@/assets/images/catalog/diamond_info_illustration.gif'); - padding-right: 123px; - } - - .info-image { - width: 123px; - height: 350px; - background-image: url('@/assets/images/catalog/diamond_info_illustration.gif'); - } -} - -.nitro-catalog-layout-vip-buy-grid { - .layout-grid-item { - height: 50px !important; - max-height: 50px !important; - - .icon-hc-banner { - width: 68px; - height: 40px; - background: url('@/assets/images/catalog/hc_big.png') center - no-repeat; - } - } -} - -.nitro-catalog-layout-marketplace-grid { - .layout-grid-item { - height: 75px !important; - } -} - -.nitro-catalog-layout-vip-gifts-grid { - .layout-grid-item { - height: 55px !important; - max-height: 55px !important; - } -} - -.nitro-catalog-layout-marketplace-post-offer { - width: $marketplace-post-offer-width; - height: $marketplace-post-offer-height; -} - -.nitro-catalog-layout-bundle-grid { - .layout-grid-item { - background-color: transparent; - } -} - -.nitro-catalog-header { - width: 290px; - height: 60px; -} - -.autocomplete-gift-container { - background: #fff; - padding: 8px; - list-style-type: none; - min-width: 307px; - border-radius: 0.2rem; - position: absolute; - font-size: 0.7875rem; - top: 81px; - left: 8px; - border: 1px solid #b6c1ce; - margin: 0; - border-radius: 2px; - margin: 0; - box-sizing: border-box; - max-height: 280px; - overflow-y: auto; - z-index: 1; - - .autocomplete-gift-item { - width: 100%; - box-sizing: border-box; - &:hover { - background-color: #ebf4ff; - } - } -} - -@import './views/targeted-offer/Offer.scss'; diff --git a/src/components/catalog/CatalogView.tsx b/src/components/catalog/CatalogView.tsx deleted file mode 100644 index 3df32be..0000000 --- a/src/components/catalog/CatalogView.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import { AddLinkEventTracker, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; -import { FC, useEffect } from 'react'; -import { GetConfigurationValue, LocalizeText } from '../../api'; -import { Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common'; -import { useCatalog } from '../../hooks'; -import { CatalogIconView } from './views/catalog-icon/CatalogIconView'; -import { CatalogGiftView } from './views/gift/CatalogGiftView'; -import { CatalogNavigationView } from './views/navigation/CatalogNavigationView'; -import { GetCatalogLayout } from './views/page/layout/GetCatalogLayout'; -import { MarketplacePostOfferView } from './views/page/layout/marketplace/MarketplacePostOfferView'; - -export const CatalogView: FC<{}> = props => -{ - const { isVisible = false, setIsVisible = null, rootNode = null, currentPage = null, navigationHidden = false, setNavigationHidden = null, activeNodes = [], searchResult = null, setSearchResult = null, openPageByName = null, openPageByOfferId = null, activateNode = null, getNodeById } = useCatalog(); - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setIsVisible(true); - return; - case 'hide': - setIsVisible(false); - return; - case 'toggle': - setIsVisible(prevValue => !prevValue); - return; - case 'open': - if(parts.length > 2) - { - if(parts.length === 4) - { - switch(parts[2]) - { - case 'offerId': - openPageByOfferId(parseInt(parts[3])); - return; - } - } - else - { - openPageByName(parts[2]); - } - } - else - { - setIsVisible(true); - } - - return; - } - }, - eventUrlPrefix: 'catalog/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, [ setIsVisible, openPageByOfferId, openPageByName ]); - - return ( - <> - { isVisible && - - setIsVisible(false) } /> - - { rootNode && (rootNode.children.length > 0) && rootNode.children.map(child => - { - if(!child.isVisible) return null; - - return ( - - { - if(searchResult) setSearchResult(null); - - activateNode(child); - } } > - - { GetConfigurationValue('catalog.tab.icons') && } - { child.localization } - - - ); - }) } - - - - { !navigationHidden && - - { activeNodes && (activeNodes.length > 0) && - } - } - - { GetCatalogLayout(currentPage, () => setNavigationHidden(true)) } - - - - } - - - - ); -} diff --git a/src/components/catalog/views/CatalogPurchaseConfirmView.tsx b/src/components/catalog/views/CatalogPurchaseConfirmView.tsx deleted file mode 100644 index 30dcfc3..0000000 --- a/src/components/catalog/views/CatalogPurchaseConfirmView.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { FC } from 'react'; - -export const CatalogPurchaseConfirmView: FC<{}> = props => -{ - const {} = props; - - return ( -
- ); -} diff --git a/src/components/catalog/views/catalog-header/CatalogHeaderView.tsx b/src/components/catalog/views/catalog-header/CatalogHeaderView.tsx deleted file mode 100644 index 9c6bbe0..0000000 --- a/src/components/catalog/views/catalog-header/CatalogHeaderView.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { GetConfigurationValue } from '../../../../api'; -import { Flex } from '../../../../common'; - -export interface CatalogHeaderViewProps -{ - imageUrl?: string; -} - -export const CatalogHeaderView: FC = props => -{ - const { imageUrl = null } = props; - const [ displayImageUrl, setDisplayImageUrl ] = useState(''); - - useEffect(() => - { - setDisplayImageUrl(imageUrl ?? GetConfigurationValue('catalog.asset.image.url').replace('%name%', 'catalog_header_roombuilder')); - }, [ imageUrl ]); - - return - - { - currentTarget.src = GetConfigurationValue('catalog.asset.image.url').replace('%name%', 'catalog_header_roombuilder'); - } } /> - ; -} diff --git a/src/components/catalog/views/catalog-icon/CatalogIconView.tsx b/src/components/catalog/views/catalog-icon/CatalogIconView.tsx deleted file mode 100644 index 2376047..0000000 --- a/src/components/catalog/views/catalog-icon/CatalogIconView.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { FC, useMemo } from 'react'; -import { GetConfigurationValue } from '../../../../api'; -import { LayoutImage } from '../../../../common'; - -export interface CatalogIconViewProps -{ - icon: number; -} - -export const CatalogIconView: FC = props => -{ - const { icon = 0 } = props; - - const getIconUrl = useMemo(() => - { - return ((GetConfigurationValue('catalog.asset.icon.url')).replace('%name%', icon.toString())); - }, [ icon ]); - - return ; -} diff --git a/src/components/catalog/views/catalog-room-previewer/CatalogRoomPreviewerView.tsx b/src/components/catalog/views/catalog-room-previewer/CatalogRoomPreviewerView.tsx deleted file mode 100644 index 0e460e5..0000000 --- a/src/components/catalog/views/catalog-room-previewer/CatalogRoomPreviewerView.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { GetEventDispatcher, NitroToolbarAnimateIconEvent, TextureUtils, ToolbarIconEnum } from '@nitrots/nitro-renderer'; -import { FC, useRef } from 'react'; -import { LayoutRoomPreviewerView, LayoutRoomPreviewerViewProps } from '../../../../common'; -import { CatalogPurchasedEvent } from '../../../../events'; -import { useUiEvent } from '../../../../hooks'; - -export const CatalogRoomPreviewerView: FC = props => -{ - const { roomPreviewer = null } = props; - const elementRef = useRef(null); - - useUiEvent(CatalogPurchasedEvent.PURCHASE_SUCCESS, event => - { - if(!elementRef) return; - - const renderTexture = roomPreviewer.getRoomObjectCurrentImage(); - - if(!renderTexture) return; - - (async () => - { - const image = await TextureUtils.generateImage(renderTexture); - - if(!image) return; - - const bounds = elementRef.current.getBoundingClientRect(); - - const x = (bounds.x + (bounds.width / 2)); - const y = (bounds.y + (bounds.height / 2)); - - const animateEvent = new NitroToolbarAnimateIconEvent(image, x, y); - - animateEvent.iconName = ToolbarIconEnum.INVENTORY; - - GetEventDispatcher().dispatchEvent(animateEvent); - })(); - }); - - return ( -
- -
- ); -} diff --git a/src/components/catalog/views/gift/CatalogGiftView.tsx b/src/components/catalog/views/gift/CatalogGiftView.tsx deleted file mode 100644 index 3ac6f25..0000000 --- a/src/components/catalog/views/gift/CatalogGiftView.tsx +++ /dev/null @@ -1,289 +0,0 @@ -import { GetSessionDataManager, GiftReceiverNotFoundEvent, PurchaseFromCatalogAsGiftComposer } from '@nitrots/nitro-renderer'; -import { ChangeEvent, FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { FaChevronLeft, FaChevronRight } from 'react-icons/fa'; -import { ColorUtils, LocalizeText, MessengerFriend, ProductTypeEnum, SendMessageComposer } from '../../../../api'; -import { Base, Button, ButtonGroup, Column, Flex, FormGroup, LayoutCurrencyIcon, LayoutFurniImageView, LayoutGiftTagView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, classNames } from '../../../../common'; -import { CatalogEvent, CatalogInitGiftEvent, CatalogPurchasedEvent } from '../../../../events'; -import { useCatalog, useFriends, useMessageEvent, useUiEvent } from '../../../../hooks'; - -export const CatalogGiftView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ pageId, setPageId ] = useState(0); - const [ offerId, setOfferId ] = useState(0); - const [ extraData, setExtraData ] = useState(''); - const [ receiverName, setReceiverName ] = useState(''); - const [ showMyFace, setShowMyFace ] = useState(true); - const [ message, setMessage ] = useState(''); - const [ colors, setColors ] = useState<{ id: number, color: string }[]>([]); - const [ selectedBoxIndex, setSelectedBoxIndex ] = useState(0); - const [ selectedRibbonIndex, setSelectedRibbonIndex ] = useState(0); - const [ selectedColorId, setSelectedColorId ] = useState(0); - const [ maxBoxIndex, setMaxBoxIndex ] = useState(0); - const [ maxRibbonIndex, setMaxRibbonIndex ] = useState(0); - const [ receiverNotFound, setReceiverNotFound ] = useState(false); - const { catalogOptions = null } = useCatalog(); - const { friends } = useFriends(); - const { giftConfiguration = null } = catalogOptions; - const [ boxTypes, setBoxTypes ] = useState([]); - const [ suggestions, setSuggestions ] = useState([]); - const [ isAutocompleteVisible, setIsAutocompleteVisible ] = useState(true); - - const onClose = useCallback(() => - { - setIsVisible(false); - setPageId(0); - setOfferId(0); - setExtraData(''); - setReceiverName(''); - setShowMyFace(true); - setMessage(''); - setSelectedBoxIndex(0); - setSelectedRibbonIndex(0); - setIsAutocompleteVisible(false); - setSuggestions([]); - - if(colors.length) setSelectedColorId(colors[0].id); - }, [ colors ]); - - const isBoxDefault = useMemo(() => - { - return giftConfiguration ? (giftConfiguration.defaultStuffTypes.findIndex(s => (s === boxTypes[selectedBoxIndex])) > -1) : false; - }, [ boxTypes, giftConfiguration, selectedBoxIndex ]); - - const boxExtraData = useMemo(() => - { - if (!giftConfiguration) return ''; - - return ((boxTypes[selectedBoxIndex] * 1000) + giftConfiguration.ribbonTypes[selectedRibbonIndex]).toString(); - }, [ giftConfiguration, selectedBoxIndex, selectedRibbonIndex, boxTypes ]); - - const isColorable = useMemo(() => - { - if (!giftConfiguration) return false; - - if (isBoxDefault) return false; - - const boxType = boxTypes[selectedBoxIndex]; - - return (boxType === 8 || (boxType >= 3 && boxType <= 6)) ? false : true; - }, [ giftConfiguration, selectedBoxIndex, isBoxDefault, boxTypes ]); - - const colourId = useMemo(() => - { - return isBoxDefault ? boxTypes[selectedBoxIndex] : selectedColorId; - },[ isBoxDefault, boxTypes, selectedBoxIndex, selectedColorId ]) - - const allFriends = friends.filter( (friend: MessengerFriend) => friend.id !== -1 ); - - const onTextChanged = (e: ChangeEvent) => - { - const value = e.target.value; - - let suggestions = []; - - if (value.length > 0) - { - suggestions = allFriends.sort().filter((friend: MessengerFriend) => friend.name.includes(value)); - } - - setReceiverName(value); - setIsAutocompleteVisible(true); - setSuggestions(suggestions); - }; - - const selectedReceiverName = (friendName: string) => - { - setReceiverName(friendName); - setIsAutocompleteVisible(false); - } - - const handleAction = useCallback((action: string) => - { - switch(action) - { - case 'prev_box': - setSelectedBoxIndex(value => (value === 0 ? maxBoxIndex : value - 1)); - return; - case 'next_box': - setSelectedBoxIndex(value => (value === maxBoxIndex ? 0 : value + 1)); - return; - case 'prev_ribbon': - setSelectedRibbonIndex(value => (value === 0 ? maxRibbonIndex : value - 1)); - return; - case 'next_ribbon': - setSelectedRibbonIndex(value => (value === maxRibbonIndex ? 0 : value + 1)); - return; - case 'buy': - if(!receiverName || (receiverName.length === 0)) - { - setReceiverNotFound(true); - return; - } - - SendMessageComposer(new PurchaseFromCatalogAsGiftComposer(pageId, offerId, extraData, receiverName, message, colourId , selectedBoxIndex, selectedRibbonIndex, showMyFace)); - return; - } - }, [ colourId, extraData, maxBoxIndex, maxRibbonIndex, message, offerId, pageId, receiverName, selectedBoxIndex, selectedRibbonIndex, showMyFace ]); - - useMessageEvent(GiftReceiverNotFoundEvent, event => setReceiverNotFound(true)); - - useUiEvent([ - CatalogPurchasedEvent.PURCHASE_SUCCESS, - CatalogEvent.INIT_GIFT ], event => - { - switch(event.type) - { - case CatalogPurchasedEvent.PURCHASE_SUCCESS: - onClose(); - return; - case CatalogEvent.INIT_GIFT: - const castedEvent = (event as CatalogInitGiftEvent); - - onClose(); - - setPageId(castedEvent.pageId); - setOfferId(castedEvent.offerId); - setExtraData(castedEvent.extraData); - setIsVisible(true); - return; - } - }); - - useEffect(() => - { - setReceiverNotFound(false); - }, [ receiverName ]); - - const createBoxTypes = useCallback(() => - { - if (!giftConfiguration) return; - - setBoxTypes(prev => - { - let newPrev = [ ...giftConfiguration.boxTypes ]; - - newPrev.push(giftConfiguration.defaultStuffTypes[ Math.floor((Math.random() * (giftConfiguration.defaultStuffTypes.length - 1))) ]); - - setMaxBoxIndex(newPrev.length- 1); - setMaxRibbonIndex(newPrev.length - 1); - - return newPrev; - }) - },[ giftConfiguration ]) - - useEffect(() => - { - if(!giftConfiguration) return; - - const newColors: { id: number, color: string }[] = []; - - for(const colorId of giftConfiguration.stuffTypes) - { - const giftData = GetSessionDataManager().getFloorItemData(colorId); - - if(!giftData) continue; - - if(giftData.colors && giftData.colors.length > 0) newColors.push({ id: colorId, color: ColorUtils.makeColorNumberHex(giftData.colors[0]) }); - } - - createBoxTypes(); - - if(newColors.length) - { - setSelectedColorId(newColors[0].id); - setColors(newColors); - } - }, [ giftConfiguration, createBoxTypes ]); - - useEffect(() => - { - if (!isVisible) return; - - createBoxTypes(); - },[ createBoxTypes, isVisible ]) - - if(!giftConfiguration || !giftConfiguration.isEnabled || !isVisible) return null; - - const boxName = 'catalog.gift_wrapping_new.box.' + (isBoxDefault ? 'default' : boxTypes[selectedBoxIndex]); - const ribbonName = `catalog.gift_wrapping_new.ribbon.${ selectedRibbonIndex }`; - const priceText = 'catalog.gift_wrapping_new.' + (isBoxDefault ? 'freeprice' : 'price'); - - return ( - - - - - { LocalizeText('catalog.gift_wrapping.receiver') } - onTextChanged(e) } /> - { (suggestions.length > 0 && isAutocompleteVisible) && - - { suggestions.map((friend: MessengerFriend) => ( - selectedReceiverName(friend.name) }>{ friend.name } - )) } - - } - { receiverNotFound && - { LocalizeText('catalog.gift_wrapping.receiver_not_found.title') } } - - setMessage(value) } /> - - setShowMyFace(value => !value) } /> - - - - { selectedColorId && - - - } - - - - - - - - { LocalizeText(boxName) } - - { LocalizeText(priceText, [ 'price' ], [ giftConfiguration.price.toString() ]) } - - - - - - - - - - { LocalizeText(ribbonName) } - - - - - - { LocalizeText('catalog.gift_wrapping.pick_color') } - - - { colors.map(color => - - - - - ); -}; diff --git a/src/components/catalog/views/navigation/CatalogNavigationItemView.tsx b/src/components/catalog/views/navigation/CatalogNavigationItemView.tsx deleted file mode 100644 index 45f7f43..0000000 --- a/src/components/catalog/views/navigation/CatalogNavigationItemView.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { FC } from 'react'; -import { FaCaretDown, FaCaretUp } from 'react-icons/fa'; -import { ICatalogNode } from '../../../../api'; -import { Base, LayoutGridItem, Text } from '../../../../common'; -import { useCatalog } from '../../../../hooks'; -import { CatalogIconView } from '../catalog-icon/CatalogIconView'; -import { CatalogNavigationSetView } from './CatalogNavigationSetView'; - -export interface CatalogNavigationItemViewProps -{ - node: ICatalogNode; - child?: boolean; -} - -export const CatalogNavigationItemView: FC = props => -{ - const { node = null, child = false } = props; - const { activateNode = null } = useCatalog(); - - return ( - - activateNode(node) } className={ child ? 'inset' : '' }> - - { node.localization } - { node.isBranch && - <> - { node.isOpen && } - { !node.isOpen && } - } - - { node.isOpen && node.isBranch && - } - - ); -} diff --git a/src/components/catalog/views/navigation/CatalogNavigationSetView.tsx b/src/components/catalog/views/navigation/CatalogNavigationSetView.tsx deleted file mode 100644 index 8bfdd48..0000000 --- a/src/components/catalog/views/navigation/CatalogNavigationSetView.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { FC } from 'react'; -import { ICatalogNode } from '../../../../api'; -import { CatalogNavigationItemView } from './CatalogNavigationItemView'; - -export interface CatalogNavigationSetViewProps -{ - node: ICatalogNode; - child?: boolean; -} - -export const CatalogNavigationSetView: FC = props => -{ - const { node = null, child = false } = props; - - return ( - <> - { node && (node.children.length > 0) && node.children.map((n, index) => - { - if(!n.isVisible) return null; - - return - }) } - - ); -} diff --git a/src/components/catalog/views/navigation/CatalogNavigationView.tsx b/src/components/catalog/views/navigation/CatalogNavigationView.tsx deleted file mode 100644 index 2d03f06..0000000 --- a/src/components/catalog/views/navigation/CatalogNavigationView.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { FC } from 'react'; -import { ICatalogNode } from '../../../../api'; -import { AutoGrid, Column } from '../../../../common'; -import { useCatalog } from '../../../../hooks'; -import { CatalogSearchView } from '../page/common/CatalogSearchView'; -import { CatalogNavigationItemView } from './CatalogNavigationItemView'; -import { CatalogNavigationSetView } from './CatalogNavigationSetView'; - -export interface CatalogNavigationViewProps -{ - node: ICatalogNode; -} - -export const CatalogNavigationView: FC = props => -{ - const { node = null } = props; - const { searchResult = null } = useCatalog(); - - return ( - <> - - - - { searchResult && (searchResult.filteredNodes.length > 0) && searchResult.filteredNodes.map((n, index) => - { - return ; - }) } - { !searchResult && - } - - - - ); -} diff --git a/src/components/catalog/views/page/common/CatalogGridOfferView.tsx b/src/components/catalog/views/page/common/CatalogGridOfferView.tsx deleted file mode 100644 index 507bb6c..0000000 --- a/src/components/catalog/views/page/common/CatalogGridOfferView.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { MouseEventType } from '@nitrots/nitro-renderer'; -import { FC, MouseEvent, useMemo, useState } from 'react'; -import { IPurchasableOffer, Offer, ProductTypeEnum } from '../../../../../api'; -import { LayoutAvatarImageView, LayoutGridItem, LayoutGridItemProps } from '../../../../../common'; -import { useCatalog, useInventoryFurni } from '../../../../../hooks'; - -interface CatalogGridOfferViewProps extends LayoutGridItemProps -{ - offer: IPurchasableOffer; - selectOffer: (offer: IPurchasableOffer) => void; -} - -export const CatalogGridOfferView: FC = props => -{ - const { offer = null, selectOffer = null, itemActive = false, ...rest } = props; - const [ isMouseDown, setMouseDown ] = useState(false); - const { requestOfferToMover = null } = useCatalog(); - const { isVisible = false } = useInventoryFurni(); - - const iconUrl = useMemo(() => - { - if(offer.pricingModel === Offer.PRICING_MODEL_BUNDLE) - { - return null; - } - - return offer.product.getIconUrl(offer); - }, [ offer ]); - - const onMouseEvent = (event: MouseEvent) => - { - switch(event.type) - { - case MouseEventType.MOUSE_DOWN: - selectOffer(offer); - setMouseDown(true); - return; - case MouseEventType.MOUSE_UP: - setMouseDown(false); - return; - case MouseEventType.ROLL_OUT: - if(!isMouseDown || !itemActive || !isVisible) return; - - requestOfferToMover(offer); - return; - } - } - - const product = offer.product; - - if(!product) return null; - - return ( - - { (offer.product.productType === ProductTypeEnum.ROBOT) && - } - - ); -} diff --git a/src/components/catalog/views/page/common/CatalogRedeemVoucherView.tsx b/src/components/catalog/views/page/common/CatalogRedeemVoucherView.tsx deleted file mode 100644 index 504bd4b..0000000 --- a/src/components/catalog/views/page/common/CatalogRedeemVoucherView.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { RedeemVoucherMessageComposer, VoucherRedeemErrorMessageEvent, VoucherRedeemOkMessageEvent } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { FaTag } from 'react-icons/fa'; -import { LocalizeText, SendMessageComposer } from '../../../../../api'; -import { Button, Flex } from '../../../../../common'; -import { useMessageEvent, useNotification } from '../../../../../hooks'; - -export interface CatalogRedeemVoucherViewProps -{ - text: string; -} - -export const CatalogRedeemVoucherView: FC = props => -{ - const { text = null } = props; - const [ voucher, setVoucher ] = useState(''); - const [ isWaiting, setIsWaiting ] = useState(false); - const { simpleAlert = null } = useNotification(); - - const redeemVoucher = () => - { - if(!voucher || !voucher.length || isWaiting) return; - - SendMessageComposer(new RedeemVoucherMessageComposer(voucher)); - - setIsWaiting(true); - } - - useMessageEvent(VoucherRedeemOkMessageEvent, event => - { - const parser = event.getParser(); - - let message = LocalizeText('catalog.alert.voucherredeem.ok.description'); - - if(parser.productName) message = LocalizeText('catalog.alert.voucherredeem.ok.description.furni', [ 'productName', 'productDescription' ], [ parser.productName, parser.productDescription ]); - - simpleAlert(message, null, null, null, LocalizeText('catalog.alert.voucherredeem.ok.title')); - - setIsWaiting(false); - setVoucher(''); - }); - - useMessageEvent(VoucherRedeemErrorMessageEvent, event => - { - const parser = event.getParser(); - - simpleAlert(LocalizeText(`catalog.alert.voucherredeem.error.description.${ parser.errorCode }`), null, null, null, LocalizeText('catalog.alert.voucherredeem.error.title')); - - setIsWaiting(false); - }); - - return ( - - setVoucher(event.target.value) } /> - - - ); -} diff --git a/src/components/catalog/views/page/common/CatalogSearchView.tsx b/src/components/catalog/views/page/common/CatalogSearchView.tsx deleted file mode 100644 index e117f90..0000000 --- a/src/components/catalog/views/page/common/CatalogSearchView.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import { GetSessionDataManager, IFurnitureData } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { FaSearch, FaTimes } from 'react-icons/fa'; -import { CatalogPage, CatalogType, FilterCatalogNode, FurnitureOffer, GetOfferNodes, ICatalogNode, ICatalogPage, IPurchasableOffer, LocalizeText, PageLocalization, SearchResult } from '../../../../../api'; -import { Button, Flex } from '../../../../../common'; -import { useCatalog } from '../../../../../hooks'; - -export const CatalogSearchView: FC<{}> = props => -{ - const [ searchValue, setSearchValue ] = useState(''); - const { currentType = null, rootNode = null, offersToNodes = null, searchResult = null, setSearchResult = null, setCurrentPage = null } = useCatalog(); - - useEffect(() => - { - let search = searchValue?.toLocaleLowerCase().replace(' ', ''); - - if(!search || !search.length) - { - setSearchResult(null); - - return; - } - - const timeout = setTimeout(() => - { - const furnitureDatas = GetSessionDataManager().getAllFurnitureData(); - - if(!furnitureDatas || !furnitureDatas.length) return; - - const foundFurniture: IFurnitureData[] = []; - const foundFurniLines: string[] = []; - - for(const furniture of furnitureDatas) - { - if((currentType === CatalogType.BUILDER) && !furniture.availableForBuildersClub) continue; - - if((currentType === CatalogType.NORMAL) && furniture.excludeDynamic) continue; - - const searchValues = [ furniture.className, furniture.name, furniture.description ].join(' ').replace(/ /gi, '').toLowerCase(); - - if((currentType === CatalogType.BUILDER) && (furniture.purchaseOfferId === -1) && (furniture.rentOfferId === -1)) - { - if((furniture.furniLine !== '') && (foundFurniLines.indexOf(furniture.furniLine) < 0)) - { - if(searchValues.indexOf(search) >= 0) foundFurniLines.push(furniture.furniLine); - } - } - else - { - const foundNodes = [ - ...GetOfferNodes(offersToNodes, furniture.purchaseOfferId), - ...GetOfferNodes(offersToNodes, furniture.rentOfferId) - ]; - - if(foundNodes.length) - { - if(searchValues.indexOf(search) >= 0) foundFurniture.push(furniture); - - if(foundFurniture.length === 250) break; - } - } - } - - const offers: IPurchasableOffer[] = []; - - for(const furniture of foundFurniture) offers.push(new FurnitureOffer(furniture)); - - let nodes: ICatalogNode[] = []; - - FilterCatalogNode(search, foundFurniLines, rootNode, nodes); - - setSearchResult(new SearchResult(search, offers, nodes.filter(node => (node.isVisible)))); - setCurrentPage((new CatalogPage(-1, 'default_3x3', new PageLocalization([], []), offers, false, 1) as ICatalogPage)); - }, 300); - - return () => clearTimeout(timeout); - }, [ offersToNodes, currentType, rootNode, searchValue, setCurrentPage, setSearchResult ]); - - return ( - - - setSearchValue(event.target.value) } /> - - { (!searchValue || !searchValue.length) && - } - { searchValue && !!searchValue.length && - } - - ); -} diff --git a/src/components/catalog/views/page/layout/CatalogLayout.types.ts b/src/components/catalog/views/page/layout/CatalogLayout.types.ts deleted file mode 100644 index b05bccf..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayout.types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ICatalogPage } from '../../../../../api'; - -export interface CatalogLayoutProps -{ - page: ICatalogPage; - hideNavigation: () => void; -} diff --git a/src/components/catalog/views/page/layout/CatalogLayoutBadgeDisplayView.tsx b/src/components/catalog/views/page/layout/CatalogLayoutBadgeDisplayView.tsx deleted file mode 100644 index 9b6ec6a..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayoutBadgeDisplayView.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { Base, Column, Flex, Grid, Text } from '../../../../../common'; -import { useCatalog } from '../../../../../hooks'; -import { CatalogBadgeSelectorWidgetView } from '../widgets/CatalogBadgeSelectorWidgetView'; -import { CatalogFirstProductSelectorWidgetView } from '../widgets/CatalogFirstProductSelectorWidgetView'; -import { CatalogItemGridWidgetView } from '../widgets/CatalogItemGridWidgetView'; -import { CatalogLimitedItemWidgetView } from '../widgets/CatalogLimitedItemWidgetView'; -import { CatalogPurchaseWidgetView } from '../widgets/CatalogPurchaseWidgetView'; -import { CatalogTotalPriceWidget } from '../widgets/CatalogTotalPriceWidget'; -import { CatalogViewProductWidgetView } from '../widgets/CatalogViewProductWidgetView'; -import { CatalogLayoutProps } from './CatalogLayout.types'; - -export const CatalogLayoutBadgeDisplayView: FC = props => -{ - const { page = null } = props; - const { currentOffer = null } = useCatalog(); - - return ( - <> - - - - - - { LocalizeText('catalog_selectbadge') } - - - - - { !currentOffer && - <> - { !!page.localization.getImage(1) && } - - } - { currentOffer && - <> - - - - - - { currentOffer.localizationName } - - - - - - } - - - - ); -} diff --git a/src/components/catalog/views/page/layout/CatalogLayoutColorGroupingView.tsx b/src/components/catalog/views/page/layout/CatalogLayoutColorGroupingView.tsx deleted file mode 100644 index 60ccdba..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayoutColorGroupingView.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import { ColorConverter } from '@nitrots/nitro-renderer'; -import { FC, useMemo, useState } from 'react'; -import { FaFillDrip } from 'react-icons/fa'; -import { IPurchasableOffer } from '../../../../../api'; -import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, Text } from '../../../../../common'; -import { useCatalog } from '../../../../../hooks'; -import { CatalogGridOfferView } from '../common/CatalogGridOfferView'; -import { CatalogAddOnBadgeWidgetView } from '../widgets/CatalogAddOnBadgeWidgetView'; -import { CatalogLimitedItemWidgetView } from '../widgets/CatalogLimitedItemWidgetView'; -import { CatalogPurchaseWidgetView } from '../widgets/CatalogPurchaseWidgetView'; -import { CatalogSpinnerWidgetView } from '../widgets/CatalogSpinnerWidgetView'; -import { CatalogTotalPriceWidget } from '../widgets/CatalogTotalPriceWidget'; -import { CatalogViewProductWidgetView } from '../widgets/CatalogViewProductWidgetView'; -import { CatalogLayoutProps } from './CatalogLayout.types'; - -export interface CatalogLayoutColorGroupViewProps extends CatalogLayoutProps -{ - -} - -export const CatalogLayoutColorGroupingView : FC = props => -{ - const { page = null } = props; - const [ colorableItems, setColorableItems ] = useState>(new Map()); - const { currentOffer = null, setCurrentOffer = null } = useCatalog(); - const [ colorsShowing, setColorsShowing ] = useState(false); - - const sortByColorIndex = (a: IPurchasableOffer, b: IPurchasableOffer) => - { - if (((!(a.product.furnitureData.colorIndex)) || (!(b.product.furnitureData.colorIndex)))) - { - return 1; - } - if (a.product.furnitureData.colorIndex > b.product.furnitureData.colorIndex) - { - return 1; - } - if (a == b) - { - return 0; - } - return -1; - } - - const sortyByFurnitureClassName = (a: IPurchasableOffer, b: IPurchasableOffer) => - { - if (a.product.furnitureData.className > b.product.furnitureData.className) - { - return 1; - } - if (a == b) - { - return 0; - } - return -1; - } - - const selectOffer = (offer: IPurchasableOffer) => - { - offer.activate(); - setCurrentOffer(offer); - } - - const selectColor = (colorIndex: number, productName: string) => - { - const fullName = `${ productName }*${ colorIndex }`; - const index = page.offers.findIndex(offer => offer.product.furnitureData.fullName === fullName); - if (index > -1) - { - selectOffer(page.offers[index]); - } - } - - const offers = useMemo(() => - { - const offers: IPurchasableOffer[] = []; - const addedColorableItems = new Map(); - const updatedColorableItems = new Map(); - - page.offers.sort(sortByColorIndex); - - page.offers.forEach(offer => - { - if(!offer.product) return; - - const furniData = offer.product.furnitureData; - - if(!furniData || !furniData.hasIndexedColor) - { - offers.push(offer); - } - else - { - const name = furniData.className; - const colorIndex = furniData.colorIndex; - - if(!updatedColorableItems.has(name)) - { - updatedColorableItems.set(name, []); - } - - let selectedColor = 0xFFFFFF; - - if(furniData.colors) - { - for(let color of furniData.colors) - { - if(color !== 0xFFFFFF) // skip the white colors - { - selectedColor = color; - } - } - - if(updatedColorableItems.get(name).indexOf(selectedColor) === -1) - { - updatedColorableItems.get(name)[colorIndex] = selectedColor; - } - - } - - if(!addedColorableItems.has(name)) - { - offers.push(offer); - addedColorableItems.set(name, true); - } - } - }); - offers.sort(sortyByFurnitureClassName); - setColorableItems(updatedColorableItems); - return offers; - }, [ page.offers ]); - - return ( - - - - { (!colorsShowing || !currentOffer || !colorableItems.has(currentOffer.product.furnitureData.className)) && - offers.map((offer, index) => ) - } - { (colorsShowing && currentOffer && colorableItems.has(currentOffer.product.furnitureData.className)) && - colorableItems.get(currentOffer.product.furnitureData.className).map((color, index) => selectColor(index, currentOffer.product.furnitureData.className) } />) - } - - - - { !currentOffer && - <> - { !!page.localization.getImage(1) && } - - } - { currentOffer && - <> - - - - { currentOffer.product.furnitureData.hasIndexedColor && - } - - - - { currentOffer.localizationName } - - - - - - - - - } - - - ); -} diff --git a/src/components/catalog/views/page/layout/CatalogLayoutDefaultView.tsx b/src/components/catalog/views/page/layout/CatalogLayoutDefaultView.tsx deleted file mode 100644 index f1cfab3..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayoutDefaultView.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { FC } from 'react'; -import { GetConfigurationValue, ProductTypeEnum } from '../../../../../api'; -import { Column, Flex, Grid, LayoutImage, Text } from '../../../../../common'; -import { useCatalog } from '../../../../../hooks'; -import { CatalogHeaderView } from '../../catalog-header/CatalogHeaderView'; -import { CatalogAddOnBadgeWidgetView } from '../widgets/CatalogAddOnBadgeWidgetView'; -import { CatalogItemGridWidgetView } from '../widgets/CatalogItemGridWidgetView'; -import { CatalogLimitedItemWidgetView } from '../widgets/CatalogLimitedItemWidgetView'; -import { CatalogPurchaseWidgetView } from '../widgets/CatalogPurchaseWidgetView'; -import { CatalogSpinnerWidgetView } from '../widgets/CatalogSpinnerWidgetView'; -import { CatalogTotalPriceWidget } from '../widgets/CatalogTotalPriceWidget'; -import { CatalogViewProductWidgetView } from '../widgets/CatalogViewProductWidgetView'; -import { CatalogLayoutProps } from './CatalogLayout.types'; - -export const CatalogLayoutDefaultView: FC = props => -{ - const { page = null } = props; - const { currentOffer = null, currentPage = null } = useCatalog(); - - return ( - <> - - - { GetConfigurationValue('catalog.headers') && - } - - - - { !currentOffer && - <> - { !!page.localization.getImage(1) && - } - - } - { currentOffer && - <> - - { (currentOffer.product.productType !== ProductTypeEnum.BADGE) && - <> - - - } - { (currentOffer.product.productType === ProductTypeEnum.BADGE) && } - - - - { currentOffer.localizationName } - - - - - - - - - } - - - - ); -} diff --git a/src/components/catalog/views/page/layout/CatalogLayoutGuildCustomFurniView.tsx b/src/components/catalog/views/page/layout/CatalogLayoutGuildCustomFurniView.tsx deleted file mode 100644 index cf12951..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayoutGuildCustomFurniView.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { FC } from 'react'; -import { Base, Column, Flex, Grid, Text } from '../../../../../common'; -import { useCatalog } from '../../../../../hooks'; -import { CatalogGuildBadgeWidgetView } from '../widgets/CatalogGuildBadgeWidgetView'; -import { CatalogGuildSelectorWidgetView } from '../widgets/CatalogGuildSelectorWidgetView'; -import { CatalogItemGridWidgetView } from '../widgets/CatalogItemGridWidgetView'; -import { CatalogPurchaseWidgetView } from '../widgets/CatalogPurchaseWidgetView'; -import { CatalogTotalPriceWidget } from '../widgets/CatalogTotalPriceWidget'; -import { CatalogViewProductWidgetView } from '../widgets/CatalogViewProductWidgetView'; -import { CatalogLayoutProps } from './CatalogLayout.types'; - -export const CatalogLayouGuildCustomFurniView: FC = props => -{ - const { page = null } = props; - const { currentOffer = null } = useCatalog(); - - return ( - - - - - - { !currentOffer && - <> - { !!page.localization.getImage(1) && } - - } - { currentOffer && - <> - - - - - - { currentOffer.localizationName } - - - - - - - - - } - - - ); -} diff --git a/src/components/catalog/views/page/layout/CatalogLayoutGuildForumView.tsx b/src/components/catalog/views/page/layout/CatalogLayoutGuildForumView.tsx deleted file mode 100644 index b5a89ca..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayoutGuildForumView.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { CatalogGroupsComposer } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { SendMessageComposer } from '../../../../../api'; -import { Base, Column, Flex, Grid, Text } from '../../../../../common'; -import { useCatalog } from '../../../../../hooks'; -import { CatalogFirstProductSelectorWidgetView } from '../widgets/CatalogFirstProductSelectorWidgetView'; -import { CatalogGuildSelectorWidgetView } from '../widgets/CatalogGuildSelectorWidgetView'; -import { CatalogPurchaseWidgetView } from '../widgets/CatalogPurchaseWidgetView'; -import { CatalogTotalPriceWidget } from '../widgets/CatalogTotalPriceWidget'; -import { CatalogLayoutProps } from './CatalogLayout.types'; - -export const CatalogLayouGuildForumView: FC = props => -{ - const { page = null } = props; - const [ selectedGroupIndex, setSelectedGroupIndex ] = useState(0); - const { currentOffer = null, setCurrentOffer = null, catalogOptions = null } = useCatalog(); - const { groups = null } = catalogOptions; - - useEffect(() => - { - SendMessageComposer(new CatalogGroupsComposer()); - }, [ page ]); - - return ( - <> - - - - - - - { !!currentOffer && - <> - - { currentOffer.localizationName } - - - - - - - - - } - - - - ); -} diff --git a/src/components/catalog/views/page/layout/CatalogLayoutGuildFrontpageView.tsx b/src/components/catalog/views/page/layout/CatalogLayoutGuildFrontpageView.tsx deleted file mode 100644 index 01cbcf1..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayoutGuildFrontpageView.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { CreateLinkEvent } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { Base } from '../../../../../common/Base'; -import { Button } from '../../../../../common/Button'; -import { Column } from '../../../../../common/Column'; -import { Grid } from '../../../../../common/Grid'; -import { LayoutImage } from '../../../../../common/layout/LayoutImage'; -import { CatalogLayoutProps } from './CatalogLayout.types'; - -export const CatalogLayouGuildFrontpageView: FC = props => -{ - const { page = null } = props; - - return ( - - - - - - - - - - - - ); -} diff --git a/src/components/catalog/views/page/layout/CatalogLayoutInfoLoyaltyView.tsx b/src/components/catalog/views/page/layout/CatalogLayoutInfoLoyaltyView.tsx deleted file mode 100644 index 06c4c03..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayoutInfoLoyaltyView.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { FC } from 'react'; -import { CatalogLayoutProps } from './CatalogLayout.types'; - -export const CatalogLayoutInfoLoyaltyView: FC = props => -{ - const { page = null } = props; - - return ( -
-
-
-
-
- ); -} diff --git a/src/components/catalog/views/page/layout/CatalogLayoutPets2View.tsx b/src/components/catalog/views/page/layout/CatalogLayoutPets2View.tsx deleted file mode 100644 index 38ad284..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayoutPets2View.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { CatalogLayoutProps } from './CatalogLayout.types'; -import { CatalogLayoutPets3View } from './CatalogLayoutPets3View'; - -export const CatalogLayoutPets2View: FC = props => -{ - return -} diff --git a/src/components/catalog/views/page/layout/CatalogLayoutPets3View.tsx b/src/components/catalog/views/page/layout/CatalogLayoutPets3View.tsx deleted file mode 100644 index 7aec846..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayoutPets3View.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { FC } from 'react'; -import { Base, Column, Flex } from '../../../../../common'; -import { CatalogLayoutProps } from './CatalogLayout.types'; - -export const CatalogLayoutPets3View: FC = props => -{ - const { page = null } = props; - - const imageUrl = page.localization.getImage(1); - - return ( - - - { imageUrl && } - - - - - - - - - - ); -} diff --git a/src/components/catalog/views/page/layout/CatalogLayoutRoomAdsView.tsx b/src/components/catalog/views/page/layout/CatalogLayoutRoomAdsView.tsx deleted file mode 100644 index 92dd4bf..0000000 --- a/src/components/catalog/views/page/layout/CatalogLayoutRoomAdsView.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { GetRoomAdPurchaseInfoComposer, GetUserEventCatsMessageComposer, PurchaseRoomAdMessageComposer, RoomAdPurchaseInfoEvent, RoomEntryData } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, SendMessageComposer } from '../../../../../api'; -import { Base, Button, Column, Text } from '../../../../../common'; -import { useCatalog, useMessageEvent, useNavigator, useRoomPromote } from '../../../../../hooks'; -import { CatalogLayoutProps } from './CatalogLayout.types'; - -export const CatalogLayoutRoomAdsView: FC = props => -{ - const { page = null } = props; - const [ eventName, setEventName ] = useState(''); - const [ eventDesc, setEventDesc ] = useState(''); - const [ roomId, setRoomId ] = useState(-1); - const [ availableRooms, setAvailableRooms ] = useState([]); - const [ extended, setExtended ] = useState(false); - const [ categoryId, setCategoryId ] = useState(1); - const { categories = null } = useNavigator(); - const { setIsVisible = null } = useCatalog(); - const { promoteInformation, isExtended, setIsExtended } = useRoomPromote(); - - useEffect(() => - { - if(isExtended) - { - setRoomId(promoteInformation.data.flatId); - setEventName(promoteInformation.data.eventName); - setEventDesc(promoteInformation.data.eventDescription); - setCategoryId(promoteInformation.data.categoryId); - setExtended(isExtended); // This is for sending to packet - setIsExtended(false); // This is from hook useRoomPromotte - } - - }, [ isExtended, eventName, eventDesc, categoryId ]); - - const resetData = () => - { - setRoomId(-1); - setEventName(''); - setEventDesc(''); - setCategoryId(1); - setIsExtended(false); - setIsVisible(false); - } - - const purchaseAd = () => - { - const pageId = page.pageId; - const offerId = page.offers.length >= 1 ? page.offers[0].offerId : -1; - const flatId = roomId; - const name = eventName; - const desc = eventDesc; - const catId = categoryId; - - SendMessageComposer(new PurchaseRoomAdMessageComposer(pageId, offerId, flatId, name, extended, desc, catId)); - resetData(); - } - - useMessageEvent(RoomAdPurchaseInfoEvent, event => - { - const parser = event.getParser(); - - if(!parser) return; - - setAvailableRooms(parser.rooms); - }); - - useEffect(() => - { - SendMessageComposer(new GetRoomAdPurchaseInfoComposer()); - // TODO: someone needs to fix this for morningstar - SendMessageComposer(new GetUserEventCatsMessageComposer()); - }, []); - - return (<> - { LocalizeText('roomad.catalog_header') } - - { LocalizeText('roomad.catalog_text', [ 'duration' ], [ '120' ]) } - - - { LocalizeText('navigator.category') } - - - - { LocalizeText('roomad.catalog_name') } - setEventName(event.target.value) } readOnly={ extended } /> - - - { LocalizeText('roomad.catalog_description') } - - { LocalizeText('friendlist.invite.note') } - - - - - - - ); -}; diff --git a/src/components/friends/views/friends-list/FriendsListSearchView.tsx b/src/components/friends/views/friends-list/FriendsListSearchView.tsx deleted file mode 100644 index 69073a2..0000000 --- a/src/components/friends/views/friends-list/FriendsListSearchView.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import { HabboSearchComposer, HabboSearchResultData, HabboSearchResultEvent } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, OpenMessengerChat, SendMessageComposer } from '../../../../api'; -import { Base, Column, Flex, NitroCardAccordionItemView, NitroCardAccordionSetView, NitroCardAccordionSetViewProps, Text, UserProfileIconView } from '../../../../common'; -import { useFriends, useMessageEvent } from '../../../../hooks'; - -interface FriendsSearchViewProps extends NitroCardAccordionSetViewProps -{ - -} - -export const FriendsSearchView: FC = props => -{ - const { ...rest } = props; - const [ searchValue, setSearchValue ] = useState(''); - const [ friendResults, setFriendResults ] = useState(null); - const [ otherResults, setOtherResults ] = useState(null); - const { canRequestFriend = null, requestFriend = null } = useFriends(); - - useMessageEvent(HabboSearchResultEvent, event => - { - const parser = event.getParser(); - - setFriendResults(parser.friends); - setOtherResults(parser.others); - }); - - useEffect(() => - { - if(!searchValue || !searchValue.length) return; - - const timeout = setTimeout(() => - { - if(!searchValue || !searchValue.length) return; - - SendMessageComposer(new HabboSearchComposer(searchValue)); - }, 500); - - return () => clearTimeout(timeout); - }, [ searchValue ]); - - return ( - - setSearchValue(event.target.value) } /> - - { friendResults && - <> - { (friendResults.length === 0) && - { LocalizeText('friendlist.search.nofriendsfound') } } - { (friendResults.length > 0) && - - { LocalizeText('friendlist.search.friendscaption', [ 'cnt' ], [ friendResults.length.toString() ]) } -
- - { friendResults.map(result => - { - return ( - - - -
{ result.avatarName }
-
- - { result.isAvatarOnline && - OpenMessengerChat(result.avatarId) } title={ LocalizeText('friendlist.tip.im') } /> } - -
- ) - }) } -
-
} - } - { otherResults && - <> - { (otherResults.length === 0) && - { LocalizeText('friendlist.search.noothersfound') } } - { (otherResults.length > 0) && - - { LocalizeText('friendlist.search.otherscaption', [ 'cnt' ], [ otherResults.length.toString() ]) } -
- - { otherResults.map(result => - { - return ( - - - -
{ result.avatarName }
-
- - { canRequestFriend(result.avatarId) && - requestFriend(result.avatarId, result.avatarName) } title={ LocalizeText('friendlist.tip.addfriend') } /> } - -
- ) - }) } -
-
} - } -
-
- ); -} diff --git a/src/components/friends/views/friends-list/FriendsListView.tsx b/src/components/friends/views/friends-list/FriendsListView.tsx deleted file mode 100644 index 9561d0f..0000000 --- a/src/components/friends/views/friends-list/FriendsListView.tsx +++ /dev/null @@ -1,150 +0,0 @@ -import { AddLinkEventTracker, ILinkEventTracker, RemoveFriendComposer, RemoveLinkEventTracker, SendRoomInviteComposer } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { LocalizeText, MessengerFriend, SendMessageComposer } from '../../../../api'; -import { Button, Flex, NitroCardAccordionSetView, NitroCardAccordionView, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common'; -import { useFriends } from '../../../../hooks'; -import { FriendsRemoveConfirmationView } from './FriendsListRemoveConfirmationView'; -import { FriendsRoomInviteView } from './FriendsListRoomInviteView'; -import { FriendsSearchView } from './FriendsListSearchView'; -import { FriendsListGroupView } from './friends-list-group/FriendsListGroupView'; -import { FriendsListRequestView } from './friends-list-request/FriendsListRequestView'; - -export const FriendsListView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ selectedFriendsIds, setSelectedFriendsIds ] = useState([]); - const [ showRoomInvite, setShowRoomInvite ] = useState(false); - const [ showRemoveFriendsConfirmation, setShowRemoveFriendsConfirmation ] = useState(false); - const { onlineFriends = [], offlineFriends = [], requests = [], requestFriend = null } = useFriends(); - - const removeFriendsText = useMemo(() => - { - if(!selectedFriendsIds || !selectedFriendsIds.length) return ''; - - const userNames: string[] = []; - - for(const userId of selectedFriendsIds) - { - let existingFriend: MessengerFriend = onlineFriends.find(f => f.id === userId); - - if(!existingFriend) existingFriend = offlineFriends.find(f => f.id === userId); - - if(!existingFriend) continue; - - userNames.push(existingFriend.name); - } - - return LocalizeText('friendlist.removefriendconfirm.userlist', [ 'user_names' ], [ userNames.join(', ') ]); - }, [ offlineFriends, onlineFriends, selectedFriendsIds ]); - - const selectFriend = useCallback((userId: number) => - { - if(userId < 0) return; - - setSelectedFriendsIds(prevValue => - { - const newValue = [ ...prevValue ]; - - const existingUserIdIndex: number = newValue.indexOf(userId); - - if(existingUserIdIndex > -1) - { - newValue.splice(existingUserIdIndex, 1) - } - else - { - newValue.push(userId); - } - - return newValue; - }); - }, [ setSelectedFriendsIds ]); - - const sendRoomInvite = (message: string) => - { - if(!selectedFriendsIds.length || !message || !message.length || (message.length > 255)) return; - - SendMessageComposer(new SendRoomInviteComposer(message, selectedFriendsIds)); - - setShowRoomInvite(false); - } - - const removeSelectedFriends = () => - { - if(selectedFriendsIds.length === 0) return; - - setSelectedFriendsIds(prevValue => - { - SendMessageComposer(new RemoveFriendComposer(...prevValue)); - - return []; - }); - - setShowRemoveFriendsConfirmation(false); - } - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setIsVisible(true); - return; - case 'hide': - setIsVisible(false); - return; - case 'toggle': - setIsVisible(prevValue => !prevValue); - return; - case 'request': - if(parts.length < 4) return; - - requestFriend(parseInt(parts[2]), parts[3]); - } - }, - eventUrlPrefix: 'friends/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, [ requestFriend ]); - - if(!isVisible) return null; - - return ( - <> - - setIsVisible(false) } /> - - - - - - - - - - - - { selectedFriendsIds && selectedFriendsIds.length > 0 && - - - - } - - - { showRoomInvite && - setShowRoomInvite(false) } sendRoomInvite={ sendRoomInvite } /> } - { showRemoveFriendsConfirmation && - setShowRemoveFriendsConfirmation(false) } removeSelectedFriends={ removeSelectedFriends } /> } - - ); -}; diff --git a/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupItemView.tsx b/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupItemView.tsx deleted file mode 100644 index 03cd7e9..0000000 --- a/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupItemView.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { FC, MouseEvent, useState } from 'react'; -import { LocalizeText, MessengerFriend, OpenMessengerChat } from '../../../../../api'; -import { Base, Flex, NitroCardAccordionItemView, UserProfileIconView } from '../../../../../common'; -import { useFriends } from '../../../../../hooks'; - -export const FriendsListGroupItemView: FC<{ friend: MessengerFriend, selected: boolean, selectFriend: (userId: number) => void }> = props => -{ - const { friend = null, selected = false, selectFriend = null } = props; - const [ isRelationshipOpen, setIsRelationshipOpen ] = useState(false); - const { followFriend = null, updateRelationship = null } = useFriends(); - - const clickFollowFriend = (event: MouseEvent) => - { - event.stopPropagation(); - - followFriend(friend); - } - - const openMessengerChat = (event: MouseEvent) => - { - event.stopPropagation(); - - OpenMessengerChat(friend.id); - } - - const openRelationship = (event: MouseEvent) => - { - event.stopPropagation(); - - setIsRelationshipOpen(true); - } - - const clickUpdateRelationship = (event: MouseEvent, type: number) => - { - event.stopPropagation(); - - updateRelationship(friend, type); - - setIsRelationshipOpen(false); - } - - const getCurrentRelationshipName = () => - { - if(!friend) return 'none'; - - switch(friend.relationshipStatus) - { - case MessengerFriend.RELATIONSHIP_HEART: return 'heart'; - case MessengerFriend.RELATIONSHIP_SMILE: return 'smile'; - case MessengerFriend.RELATIONSHIP_BOBBA: return 'bobba'; - default: return 'none'; - } - } - - if(!friend) return null; - - return ( - selectFriend(friend.id) }> - - event.stopPropagation() }> - - -
{ friend.name }
-
- - { !isRelationshipOpen && - <> - { friend.followingAllowed && - } - { friend.online && - } - { (friend.id > 0) && - } - } - { isRelationshipOpen && - <> - clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_HEART) } /> - clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_SMILE) } /> - clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_BOBBA) } /> - clickUpdateRelationship(event, MessengerFriend.RELATIONSHIP_NONE) } /> - } - -
- ); -} diff --git a/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupView.tsx b/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupView.tsx deleted file mode 100644 index c593003..0000000 --- a/src/components/friends/views/friends-list/friends-list-group/FriendsListGroupView.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { FC } from 'react'; -import { MessengerFriend } from '../../../../../api'; -import { FriendsListGroupItemView } from './FriendsListGroupItemView'; - -interface FriendsListGroupViewProps -{ - list: MessengerFriend[]; - selectedFriendsIds: number[]; - selectFriend: (userId: number) => void; -} - -export const FriendsListGroupView: FC = props => -{ - const { list = null, selectedFriendsIds = null, selectFriend = null } = props; - - if(!list || !list.length) return null; - - return ( - <> - { list.map((item, index) => = 0) } selectFriend={ selectFriend } />) } - - ); -} diff --git a/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestItemView.tsx b/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestItemView.tsx deleted file mode 100644 index de5d3a3..0000000 --- a/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestItemView.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { FC } from 'react'; -import { MessengerRequest } from '../../../../../api'; -import { Base, Flex, NitroCardAccordionItemView, UserProfileIconView } from '../../../../../common'; -import { useFriends } from '../../../../../hooks'; - -export const FriendsListRequestItemView: FC<{ request: MessengerRequest }> = props => -{ - const { request = null } = props; - const { requestResponse = null } = useFriends(); - - if(!request) return null; - - return ( - - - -
{ request.name }
-
- - requestResponse(request.id, true) } /> - requestResponse(request.id, false) } /> - -
- ); -} diff --git a/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestView.tsx b/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestView.tsx deleted file mode 100644 index 5f6e991..0000000 --- a/src/components/friends/views/friends-list/friends-list-request/FriendsListRequestView.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { Button, Column, Flex, NitroCardAccordionSetView, NitroCardAccordionSetViewProps } from '../../../../../common'; -import { useFriends } from '../../../../../hooks'; -import { FriendsListRequestItemView } from './FriendsListRequestItemView'; - -export const FriendsListRequestView: FC = props => -{ - const { children = null, ...rest } = props; - const { requests = [], requestResponse = null } = useFriends(); - - if(!requests.length) return null; - - return ( - - - - { requests.map((request, index) => ) } - - - - - - { children } - - ); -} diff --git a/src/components/friends/views/messenger/FriendsMessengerView.tsx b/src/components/friends/views/messenger/FriendsMessengerView.tsx deleted file mode 100644 index 932e71d..0000000 --- a/src/components/friends/views/messenger/FriendsMessengerView.tsx +++ /dev/null @@ -1,177 +0,0 @@ -import { AddLinkEventTracker, FollowFriendMessageComposer, GetSessionDataManager, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; -import { FC, KeyboardEvent, useEffect, useRef, useState } from 'react'; -import { FaTimes } from 'react-icons/fa'; -import { GetUserProfile, LocalizeText, ReportType, SendMessageComposer } from '../../../../api'; -import { Base, Button, ButtonGroup, Column, Flex, Grid, LayoutAvatarImageView, LayoutBadgeImageView, LayoutGridItem, LayoutItemCountView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; -import { useHelp, useMessenger } from '../../../../hooks'; -import { FriendsMessengerThreadView } from './messenger-thread/FriendsMessengerThreadView'; - -export const FriendsMessengerView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ lastThreadId, setLastThreadId ] = useState(-1); - const [ messageText, setMessageText ] = useState(''); - const { visibleThreads = [], activeThread = null, getMessageThread = null, sendMessage = null, setActiveThreadId = null, closeThread = null } = useMessenger(); - const { report = null } = useHelp(); - const messagesBox = useRef(); - - const followFriend = () => (activeThread && activeThread.participant && SendMessageComposer(new FollowFriendMessageComposer(activeThread.participant.id))); - const openProfile = () => (activeThread && activeThread.participant && GetUserProfile(activeThread.participant.id)); - - const send = () => - { - if(!activeThread || !messageText.length) return; - - sendMessage(activeThread, GetSessionDataManager().userId, messageText); - - setMessageText(''); - } - - const onKeyDown = (event: KeyboardEvent) => - { - if(event.key !== 'Enter') return; - - send(); - } - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length === 2) - { - if(parts[1] === 'open') - { - setIsVisible(true); - - return; - } - - if(parts[1] === 'toggle') - { - setIsVisible(prevValue => !prevValue); - - return; - } - - const thread = getMessageThread(parseInt(parts[1])); - - if(!thread) return; - - setActiveThreadId(thread.threadId); - setIsVisible(true); - } - }, - eventUrlPrefix: 'friends-messenger/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, [ getMessageThread, setActiveThreadId ]); - - useEffect(() => - { - if(!isVisible || !activeThread) return; - - messagesBox.current.scrollTop = messagesBox.current.scrollHeight; - }, [ isVisible, activeThread ]); - - useEffect(() => - { - if(isVisible && !activeThread) - { - if(lastThreadId > 0) - { - setActiveThreadId(lastThreadId); - } - else - { - if(visibleThreads.length > 0) setActiveThreadId(visibleThreads[0].threadId); - } - - return; - } - - if(!isVisible && activeThread) - { - setLastThreadId(activeThread.threadId); - setActiveThreadId(-1); - } - }, [ isVisible, activeThread, lastThreadId, visibleThreads, setActiveThreadId ]); - - if(!isVisible) return null; - - return ( - - setIsVisible(false) } /> - - - - { LocalizeText('toolbar.icon.label.messenger') } - - - { visibleThreads && (visibleThreads.length > 0) && visibleThreads.map(thread => - { - return ( - setActiveThreadId(thread.threadId) }> - { thread.unread && - } - - - { (thread.participant.id > 0) && - } - { (thread.participant.id <= 0) && - } - - { thread.participant.name } - - - ); - }) } - - - - - { activeThread && - <> - { LocalizeText('messenger.window.separator', [ 'FRIEND_NAME' ], [ activeThread.participant.name ]) } - - - - - - - - - - - - - - - - - setMessageText(event.target.value) } onKeyDown={ onKeyDown } /> - - - } - - - - - ); -} diff --git a/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadGroup.tsx b/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadGroup.tsx deleted file mode 100644 index 4ed6c99..0000000 --- a/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadGroup.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { GetSessionDataManager } from '@nitrots/nitro-renderer'; -import { FC, useMemo } from 'react'; -import { GetGroupChatData, LocalizeText, MessengerGroupType, MessengerThread, MessengerThreadChat, MessengerThreadChatGroup } from '../../../../../api'; -import { Base, Flex, LayoutAvatarImageView } from '../../../../../common'; - -export const FriendsMessengerThreadGroup: FC<{ thread: MessengerThread, group: MessengerThreadChatGroup }> = props => -{ - const { thread = null, group = null } = props; - - const groupChatData = useMemo(() => ((group.type === MessengerGroupType.GROUP_CHAT) && GetGroupChatData(group.chats[0].extraData)), [ group ]); - - const isOwnChat = useMemo(() => - { - if(!thread || !group) return false; - - if((group.type === MessengerGroupType.PRIVATE_CHAT) && (group.userId === GetSessionDataManager().userId)) return true; - - if(groupChatData && group.chats.length && (groupChatData.userId === GetSessionDataManager().userId)) return true; - - return false; - }, [ thread, group, groupChatData ]); - - if(!thread || !group) return null; - - if(!group.userId) - { - return ( - <> - { group.chats.map((chat, index) => - { - return ( - - - { (chat.type === MessengerThreadChat.SECURITY_NOTIFICATION) && - - - { chat.message } - } - { (chat.type === MessengerThreadChat.ROOM_INVITE) && - - - { (LocalizeText('messenger.invitation') + ' ') }{ chat.message } - } - - - ); - }) } - - ); - } - - return ( - - - { ((group.type === MessengerGroupType.PRIVATE_CHAT) && !isOwnChat) && - } - { (groupChatData && !isOwnChat) && - } - - - - { isOwnChat && GetSessionDataManager().userName } - { !isOwnChat && (groupChatData ? groupChatData.username : thread.participant.name) } - - { group.chats.map((chat, index) => { chat.message }) } - - { isOwnChat && - - - } - - ); -} diff --git a/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadView.tsx b/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadView.tsx deleted file mode 100644 index 962a668..0000000 --- a/src/components/friends/views/messenger/messenger-thread/FriendsMessengerThreadView.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { FC } from 'react'; -import { MessengerThread } from '../../../../../api'; -import { FriendsMessengerThreadGroup } from './FriendsMessengerThreadGroup'; - -export const FriendsMessengerThreadView: FC<{ thread: MessengerThread }> = props => -{ - const { thread = null } = props; - - thread.setRead(); - - return ( - <> - { (thread.groups.length > 0) && thread.groups.map((group, index) => ) } - - ); -} diff --git a/src/components/game-center/GameCenterView.scss b/src/components/game-center/GameCenterView.scss deleted file mode 100644 index 246278d..0000000 --- a/src/components/game-center/GameCenterView.scss +++ /dev/null @@ -1,44 +0,0 @@ -.game-center-stage { - width: 100%; - height: calc(100% - 55px); - background-color: black; - position: absolute; - inset: 0; -} -.game-center-main { - width: 1280px; - height: calc(100% - 55px); - background: #93d4f3; - - .game-view { - background-position: bottom center; - background-repeat: no-repeat; - - > div { - color: inherit; - } - } - - .gameList-container { - min-height: 107px; - - .game-icon { - width: 83px; - height: 83px; - background-position: center; - background-repeat: no-repeat; - - &.selected { - position: relative; - &::after { - content: ''; - background-image: url('@/assets/images/gamecenter/selectedIcon.png'); - width: 83px; - height: 83px; - position: absolute; - inset: 0; - } - } - } - } -} diff --git a/src/components/game-center/GameCenterView.tsx b/src/components/game-center/GameCenterView.tsx deleted file mode 100644 index 885908e..0000000 --- a/src/components/game-center/GameCenterView.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { AddLinkEventTracker, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; -import { useEffect } from 'react'; -import { Flex } from '../../common'; -import { useGameCenter } from '../../hooks'; -import { GameListView } from './views/GameListView'; -import { GameStageView } from './views/GameStageView'; -import { GameView } from './views/GameView'; - -export const GameCenterView = () => -{ - const{ isVisible, setIsVisible, games, accountStatus } = useGameCenter(); - - useEffect(() => - { - const toggleGameCenter = () => - { - setIsVisible(prev => !prev); - } - - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const value = url.split('/'); - - switch(value[1]) - { - case 'toggle': - toggleGameCenter(); - break; - } - }, - eventUrlPrefix: 'games/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, [ setIsVisible ]); - - if(!isVisible || !games || !accountStatus) return; - - return - - - - - - -} diff --git a/src/components/game-center/views/GameListView.tsx b/src/components/game-center/views/GameListView.tsx deleted file mode 100644 index 1211bc7..0000000 --- a/src/components/game-center/views/GameListView.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { GameConfigurationData } from '@nitrots/nitro-renderer'; -import { LocalizeText } from '../../../api'; -import { Base, Flex } from '../../../common'; -import { useGameCenter } from '../../../hooks'; - -export const GameListView = () => -{ - const { games,selectedGame, setSelectedGame } = useGameCenter(); - - const getClasses = (game: GameConfigurationData) => - { - let classes = [ 'game-icon' ]; - - if(selectedGame === game) classes.push('selected'); - - return classes.join(' '); - } - - const getIconImage = (game: GameConfigurationData): string => - { - return `url(${ game.assetUrl }${ game.gameNameId }_icon.png)` - } - - return - { LocalizeText('gamecenter.game_list_title') } - - { games && games.map((game,index) => - setSelectedGame(game) } style={ { backgroundImage: getIconImage(game) } }/> - ) } - - -} diff --git a/src/components/game-center/views/GameStageView.tsx b/src/components/game-center/views/GameStageView.tsx deleted file mode 100644 index 0a26fea..0000000 --- a/src/components/game-center/views/GameStageView.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Game2ExitGameMessageComposer } from '@nitrots/nitro-renderer'; -import { useEffect, useRef, useState } from 'react'; -import { SendMessageComposer } from '../../../api'; -import { Base } from '../../../common'; -import { useGameCenter } from '../../../hooks'; - -export const GameStageView = () => -{ - const { gameURL,setGameURL } = useGameCenter(); - const [ loadTimes, setLoadTimes ] = useState(0); - const ref = useRef(); - - useEffect(()=> - { - if(!ref || ref && !ref.current) return; - - setLoadTimes(0); - - let frame: HTMLIFrameElement = document.createElement('iframe'); - - frame.src = gameURL; - frame.classList.add('game-center-stage'); - frame.classList.add('h-100'); - - frame.onload = () => - { - setLoadTimes(prev => prev += 1) - } - - ref.current.innerHTML = ''; - ref.current.appendChild(frame); - - },[ ref, gameURL ]); - - useEffect(()=> - { - if(loadTimes > 1) - { - setGameURL(null); - SendMessageComposer(new Game2ExitGameMessageComposer()); - } - },[ loadTimes,setGameURL ]) - - if(!gameURL) return null; - - return -} diff --git a/src/components/game-center/views/GameView.tsx b/src/components/game-center/views/GameView.tsx deleted file mode 100644 index a9d641f..0000000 --- a/src/components/game-center/views/GameView.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Game2GetAccountGameStatusMessageComposer, GetGameStatusMessageComposer, JoinQueueMessageComposer } from '@nitrots/nitro-renderer'; -import { useEffect } from 'react'; -import { ColorUtils, LocalizeText, SendMessageComposer } from '../../../api'; -import { Base, Button, Flex, LayoutItemCountView, Text } from '../../../common'; -import { useGameCenter } from '../../../hooks'; - -export const GameView = () => -{ - const { selectedGame, accountStatus } = useGameCenter(); - - useEffect(()=> - { - if(selectedGame) - { - SendMessageComposer(new GetGameStatusMessageComposer(selectedGame.gameId)); - SendMessageComposer(new Game2GetAccountGameStatusMessageComposer(selectedGame.gameId)); - } - },[ selectedGame ]) - - const getBgColour = (): string => - { - return ColorUtils.uintHexColor(selectedGame.bgColor) - } - - const getBgImage = (): string => - { - return `url(${ selectedGame.assetUrl }${ selectedGame.gameNameId }_theme.png)` - } - - const getColor = () => - { - return ColorUtils.uintHexColor(selectedGame.textColor); - } - - const onPlay = () => - { - SendMessageComposer(new JoinQueueMessageComposer(selectedGame.gameId)); - } - - return - - { LocalizeText(`gamecenter.${ selectedGame.gameNameId }.description_title`) } - - { (accountStatus.hasUnlimitedGames || accountStatus.freeGamesLeft > 0) && <> - - } - { LocalizeText(`gamecenter.${ selectedGame.gameNameId }.description_content`) } - - - - - - -} diff --git a/src/components/groups/GroupView.scss b/src/components/groups/GroupView.scss deleted file mode 100644 index 8882b93..0000000 --- a/src/components/groups/GroupView.scss +++ /dev/null @@ -1,190 +0,0 @@ -.nitro-group-tab-image { - width: 122px; - height: 68px; - background: url('@/assets/images/groups/creator_images.png') no-repeat; - - &.tab-1 { - background-position: 0px 0px; - width: 99px; - height: 50px; - } - - &.tab-2 { - background-position: -99px 0px; - width: 98px; - height: 62px; - } - - &.tab-3 { - background-position: 0px -50px; - width: 96px; - height: 45px; - } - - &.tab-4, - &.tab-5 { - background-position: 0px -95px; - width: 114px; - height: 61px; - } -} - -.group-information { - width: 100%; - height: 100%; - display: flex; - - .group-badge { - width: 78px; - height: 78px; - - .badge-image { - background-size: contain; - } - } - - .group-description { - height: 55px; - } -} - -.nitro-group-information-standalone { - width: 500px; -} - -.nitro-group-members { - width: 400px; - max-height: 380px; - - .nitro-group-members-list-grid { - - .member-list-item { - height: 50px; - max-height: 50px; - - .avatar-head { - position: relative; - overflow: hidden; - width: 40px; - height: 50px; - - .avatar-image { - position: absolute; - left: -25px; - top: -20px; - } - } - } - } -} - -.group-badge-preview { - width: 42px; - height: 42px; - background-color: $grid-bg-color; - - &.active { - border-color: $grid-active-border-color !important; - background-color: $grid-active-bg-color; - - &:before { - position: absolute; - content: ' '; - width: 0; - height: 0; - border-top: 10px solid white; - border-left: 10px solid transparent; - border-right: 10px solid transparent; - bottom: -10px; - } - } -} - -.group-badge-color-swatch, -.group-badge-position-swatch { - position: relative; - border-radius: $border-radius; - width: 16px; - height: 16px; - background: $white; - border: 2px solid $white; - box-shadow: inset 3px 3px rgba(0, 0, 0, .1); - - &.active { - box-shadow: none; - } -} - -.group-badge-position-swatch { - box-shadow: inset 3px 3px rgba(0, 0, 0, .1); - - &.active { - background: $primary; - } -} - -.group-badge-color-swatch { - box-shadow: inset 2px 2px rgba(0, 0, 0, .2); -} - -.group-color-swatch { - width: 30px; - height: 40px; -} - -.nitro-group-manager { - height: $nitro-group-manager-height; - width: $nitro-group-manager-width; -} - -.nitro-group-creator { - height: $nitro-group-manager-height; - width: $nitro-group-manager-width; - - .creator-tabs { - - .tab { - position: relative; - margin-left: -6px; - background-image: url('@/assets/images/groups/creator_tabs.png'); - background-repeat: no-repeat; - - &:first-child { - margin-left: 0; - } - - &.tab-blue-flat { - width: 84px; - height: 24px; - background-position: 0px 0px; - - &.active { - height: 28px; - background-position: 0px -24px; - } - } - - &.tab-blue-arrow { - width: 83px; - height: 24px; - background-position: 0px -52px; - - &.active { - height: 28px; - background-position: 0px -76px; - } - } - - &.tab-yellow { - width: 133px; - height: 28px; - background-position: 0px -104px; - - &.active { - height: 33px; - background-position: 0px -132px; - } - } - } - } -} diff --git a/src/components/groups/GroupsView.tsx b/src/components/groups/GroupsView.tsx deleted file mode 100644 index a8a000b..0000000 --- a/src/components/groups/GroupsView.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { AddLinkEventTracker, GroupPurchasedEvent, GroupSettingsComposer, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { SendMessageComposer, TryVisitRoom } from '../../api'; -import { useGroup, useMessageEvent } from '../../hooks'; -import { GroupCreatorView } from './views/GroupCreatorView'; -import { GroupInformationStandaloneView } from './views/GroupInformationStandaloneView'; -import { GroupManagerView } from './views/GroupManagerView'; -import { GroupMembersView } from './views/GroupMembersView'; - -export const GroupsView: FC<{}> = props => -{ - const [ isCreatorVisible, setCreatorVisible ] = useState(false); - const {} = useGroup(); - - useMessageEvent(GroupPurchasedEvent, event => - { - const parser = event.getParser(); - - setCreatorVisible(false); - TryVisitRoom(parser.roomId); - }); - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'create': - setCreatorVisible(true); - return; - case 'manage': - if(!parts[2]) return; - - setCreatorVisible(false); - SendMessageComposer(new GroupSettingsComposer(Number(parts[2]))); - return; - } - }, - eventUrlPrefix: 'groups/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, []); - - return ( - <> - { isCreatorVisible && - setCreatorVisible(false) } /> } - { !isCreatorVisible && - } - - - - ); -}; diff --git a/src/components/groups/views/GroupBadgeCreatorView.tsx b/src/components/groups/views/GroupBadgeCreatorView.tsx deleted file mode 100644 index 8e32c92..0000000 --- a/src/components/groups/views/GroupBadgeCreatorView.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { Dispatch, FC, SetStateAction, useState } from 'react'; -import { FaPlus, FaTimes } from 'react-icons/fa'; -import { GroupBadgePart } from '../../../api'; -import { Base, Column, Flex, Grid, LayoutBadgeImageView } from '../../../common'; -import { useGroup } from '../../../hooks'; - -interface GroupBadgeCreatorViewProps -{ - badgeParts: GroupBadgePart[]; - setBadgeParts: Dispatch>; -} - -const POSITIONS: number[] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]; - -export const GroupBadgeCreatorView: FC = props => -{ - const { badgeParts = [], setBadgeParts = null } = props; - const [ selectedIndex, setSelectedIndex ] = useState(-1); - const { groupCustomize = null } = useGroup(); - - const setPartProperty = (partIndex: number, property: string, value: number) => - { - const newBadgeParts = [ ...badgeParts ]; - - newBadgeParts[partIndex][property] = value; - - setBadgeParts(newBadgeParts); - - if(property === 'key') setSelectedIndex(-1); - } - - if(!badgeParts || !badgeParts.length) return null; - - return ( - <> - { ((selectedIndex < 0) && badgeParts && (badgeParts.length > 0)) && badgeParts.map((part, index) => - { - return ( - - setSelectedIndex(index) }> - { (badgeParts[index].code && (badgeParts[index].code.length > 0)) && - } - { (!badgeParts[index].code || !badgeParts[index].code.length) && - - - } - - { (part.type !== GroupBadgePart.BASE) && - - { POSITIONS.map((position, posIndex) => - { - return setPartProperty(index, 'position', position) }> - }) } - } - - { (groupCustomize.badgePartColors.length > 0) && groupCustomize.badgePartColors.map((item, colorIndex) => - { - return setPartProperty(index, 'color', (colorIndex + 1)) }> - }) } - - - ); - }) } - { (selectedIndex >= 0) && - - { (badgeParts[selectedIndex].type === GroupBadgePart.SYMBOL) && - setPartProperty(selectedIndex, 'key', 0) }> - - - - } - { ((badgeParts[selectedIndex].type === GroupBadgePart.BASE) ? groupCustomize.badgeBases : groupCustomize.badgeSymbols).map((item, index) => - { - return ( - setPartProperty(selectedIndex, 'key', item.id) }> - - - ); - }) } - } - - ); -} diff --git a/src/components/groups/views/GroupCreatorView.tsx b/src/components/groups/views/GroupCreatorView.tsx deleted file mode 100644 index cd64ef3..0000000 --- a/src/components/groups/views/GroupCreatorView.tsx +++ /dev/null @@ -1,164 +0,0 @@ -import { GroupBuyComposer, GroupBuyDataComposer, GroupBuyDataEvent } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { HasHabboClub, IGroupData, LocalizeText, SendMessageComposer } from '../../../api'; -import { Base, Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common'; -import { useMessageEvent } from '../../../hooks'; -import { GroupTabBadgeView } from './tabs/GroupTabBadgeView'; -import { GroupTabColorsView } from './tabs/GroupTabColorsView'; -import { GroupTabCreatorConfirmationView } from './tabs/GroupTabCreatorConfirmationView'; -import { GroupTabIdentityView } from './tabs/GroupTabIdentityView'; - -interface GroupCreatorViewProps -{ - onClose: () => void; -} - -const TABS: number[] = [ 1, 2, 3, 4 ]; - -export const GroupCreatorView: FC = props => -{ - const { onClose = null } = props; - const [ currentTab, setCurrentTab ] = useState(1); - const [ closeAction, setCloseAction ] = useState<{ action: () => boolean }>(null); - const [ groupData, setGroupData ] = useState(null); - const [ availableRooms, setAvailableRooms ] = useState<{ id: number, name: string }[]>(null); - const [ purchaseCost, setPurchaseCost ] = useState(0); - - const onCloseClose = () => - { - setCloseAction(null); - setGroupData(null); - - if(onClose) onClose(); - } - - const buyGroup = () => - { - if(!groupData) return; - - const badge = []; - - groupData.groupBadgeParts.forEach(part => - { - if(part.code) - { - badge.push(part.key); - badge.push(part.color); - badge.push(part.position); - } - }); - - SendMessageComposer(new GroupBuyComposer(groupData.groupName, groupData.groupDescription, groupData.groupHomeroomId, groupData.groupColors[0], groupData.groupColors[1], badge)); - } - - const previousStep = () => - { - if(closeAction && closeAction.action) - { - if(!closeAction.action()) return; - } - - if(currentTab === 1) - { - onClose(); - - return; - } - - setCurrentTab(value => value - 1); - } - - const nextStep = () => - { - if(closeAction && closeAction.action) - { - if(!closeAction.action()) return; - } - - if(currentTab === 4) - { - buyGroup(); - - return; - } - - setCurrentTab(value => (value === 4 ? value : value + 1)); - } - - useMessageEvent(GroupBuyDataEvent, event => - { - const parser = event.getParser(); - - const rooms: { id: number, name: string }[] = []; - - parser.availableRooms.forEach((name, id) => rooms.push({ id, name })); - - setAvailableRooms(rooms); - setPurchaseCost(parser.groupCost); - }); - - useEffect(() => - { - setCurrentTab(1); - - setGroupData({ - groupId: -1, - groupName: null, - groupDescription: null, - groupHomeroomId: -1, - groupState: 1, - groupCanMembersDecorate: true, - groupColors: null, - groupBadgeParts: null - }); - - SendMessageComposer(new GroupBuyDataComposer()); - }, [ setGroupData ]); - - if(!groupData) return null; - - return ( - - - - - { TABS.map((tab, index) => - { - return ( - - { LocalizeText(`group.create.steplabel.${ tab }`) } - - ); - }) } - - - - - - { LocalizeText(`group.create.stepcaption.${ currentTab }`) } - { LocalizeText(`group.create.stepdesc.${ currentTab }`) } - - - - { (currentTab === 1) && - } - { (currentTab === 2) && - } - { (currentTab === 3) && - } - { (currentTab === 4) && - } - - - - - - - - - ); -}; diff --git a/src/components/groups/views/GroupInformationStandaloneView.tsx b/src/components/groups/views/GroupInformationStandaloneView.tsx deleted file mode 100644 index d4206d7..0000000 --- a/src/components/groups/views/GroupInformationStandaloneView.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { GroupInformationEvent, GroupInformationParser } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { LocalizeText } from '../../../api'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../common'; -import { useMessageEvent } from '../../../hooks'; -import { GroupInformationView } from './GroupInformationView'; - -export const GroupInformationStandaloneView: FC<{}> = props => -{ - const [ groupInformation, setGroupInformation ] = useState(null); - - useMessageEvent(GroupInformationEvent, event => - { - const parser = event.getParser(); - - if((groupInformation && (groupInformation.id === parser.id)) || parser.flag) setGroupInformation(parser); - }); - - if(!groupInformation) return null; - - return ( - - setGroupInformation(null) } /> - - setGroupInformation(null) } /> - - - ); -}; diff --git a/src/components/groups/views/GroupInformationView.tsx b/src/components/groups/views/GroupInformationView.tsx deleted file mode 100644 index a13408b..0000000 --- a/src/components/groups/views/GroupInformationView.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import { CreateLinkEvent, GetSessionDataManager, GroupInformationParser, GroupRemoveMemberComposer } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { CatalogPageName, GetGroupManager, GetGroupMembers, GroupMembershipType, GroupType, LocalizeText, SendMessageComposer, TryJoinGroup, TryVisitRoom } from '../../../api'; -import { Button, Column, Flex, Grid, GridProps, LayoutBadgeImageView, Text } from '../../../common'; -import { useNotification } from '../../../hooks'; - -const STATES: string[] = [ 'regular', 'exclusive', 'private' ]; - -interface GroupInformationViewProps extends GridProps -{ - groupInformation: GroupInformationParser; - onJoin?: () => void; - onClose?: () => void; -} - -export const GroupInformationView: FC = props => -{ - const { groupInformation = null, onClose = null, overflow = 'hidden', ...rest } = props; - const { showConfirm = null } = useNotification(); - - const isRealOwner = (groupInformation && (groupInformation.ownerName === GetSessionDataManager().userName)); - - const joinGroup = () => (groupInformation && TryJoinGroup(groupInformation.id)); - - const leaveGroup = () => - { - showConfirm(LocalizeText('group.leaveconfirm.desc'), () => - { - SendMessageComposer(new GroupRemoveMemberComposer(groupInformation.id, GetSessionDataManager().userId)); - - if(onClose) onClose(); - }, null); - } - - const getRoleIcon = () => - { - if(groupInformation.membershipType === GroupMembershipType.NOT_MEMBER || groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return null; - - if(isRealOwner) return ; - - if(groupInformation.isAdmin) return ; - - return ; - } - - const getButtonText = () => - { - if(isRealOwner) return 'group.youareowner'; - - if(groupInformation.type === GroupType.PRIVATE && groupInformation.membershipType !== GroupMembershipType.MEMBER) return ''; - - if(groupInformation.membershipType === GroupMembershipType.MEMBER) return 'group.leave'; - - if((groupInformation.membershipType === GroupMembershipType.NOT_MEMBER) && groupInformation.type === GroupType.REGULAR) return 'group.join'; - - if(groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return 'group.membershippending'; - - if((groupInformation.membershipType === GroupMembershipType.NOT_MEMBER) && groupInformation.type === GroupType.EXCLUSIVE) return 'group.requestmembership'; - } - - const handleButtonClick = () => - { - if((groupInformation.type === GroupType.PRIVATE) && (groupInformation.membershipType === GroupMembershipType.NOT_MEMBER)) return; - - if(groupInformation.membershipType === GroupMembershipType.MEMBER) - { - leaveGroup(); - - return; - } - - joinGroup(); - } - - const handleAction = (action: string) => - { - switch(action) - { - case 'members': - GetGroupMembers(groupInformation.id); - break; - case 'members_pending': - GetGroupMembers(groupInformation.id, 2); - break; - case 'manage': - GetGroupManager(groupInformation.id); - break; - case 'homeroom': - TryVisitRoom(groupInformation.roomId); - break; - case 'furniture': - CreateLinkEvent('catalog/open/' + CatalogPageName.GUILD_CUSTOM_FURNI); - break; - case 'popular_groups': - CreateLinkEvent('navigator/search/groups'); - break; - } - } - - if(!groupInformation) return null; - - return ( - - - - - - - handleAction('members') }>{ LocalizeText('group.membercount', [ 'totalMembers' ], [ groupInformation.membersCount.toString() ]) } - { (groupInformation.pendingRequestsCount > 0) && - handleAction('members_pending') }>{ LocalizeText('group.pendingmembercount', [ 'amount' ], [ groupInformation.pendingRequestsCount.toString() ]) } } - { groupInformation.isOwner && - handleAction('manage') }>{ LocalizeText('group.manage') } } - - { getRoleIcon() } - - - - - - { groupInformation.title } - - - { groupInformation.canMembersDecorate && - } - - - { LocalizeText('group.created', [ 'date', 'owner' ], [ groupInformation.createdAt, groupInformation.ownerName ]) } - - { groupInformation.description } - - - - handleAction('homeroom') }>{ LocalizeText('group.linktobase') } - handleAction('furniture') }>{ LocalizeText('group.buyfurni') } - handleAction('popular_groups') }>{ LocalizeText('group.showgroups') } - - { (groupInformation.type !== GroupType.PRIVATE || groupInformation.type === GroupType.PRIVATE && groupInformation.membershipType === GroupMembershipType.MEMBER) && - } - - - - ); -}; diff --git a/src/components/groups/views/GroupManagerView.tsx b/src/components/groups/views/GroupManagerView.tsx deleted file mode 100644 index 9e1d625..0000000 --- a/src/components/groups/views/GroupManagerView.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import { GroupBadgePart, GroupInformationEvent, GroupSettingsEvent } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { IGroupData, LocalizeText } from '../../../api'; -import { Base, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView, Text } from '../../../common'; -import { useMessageEvent } from '../../../hooks'; -import { GroupTabBadgeView } from './tabs/GroupTabBadgeView'; -import { GroupTabColorsView } from './tabs/GroupTabColorsView'; -import { GroupTabIdentityView } from './tabs/GroupTabIdentityView'; -import { GroupTabSettingsView } from './tabs/GroupTabSettingsView'; - -const TABS: number[] = [ 1, 2, 3, 5 ]; - -export const GroupManagerView: FC<{}> = props => -{ - const [ currentTab, setCurrentTab ] = useState(1); - const [ closeAction, setCloseAction ] = useState<{ action: () => boolean }>(null); - const [ groupData, setGroupData ] = useState(null); - - const onClose = () => - { - setCloseAction(prevValue => - { - if(prevValue && prevValue.action) prevValue.action(); - - return null; - }); - - setGroupData(null); - } - - const changeTab = (tab: number) => - { - if(closeAction && closeAction.action) closeAction.action(); - - setCurrentTab(tab); - } - - useMessageEvent(GroupInformationEvent, event => - { - const parser = event.getParser(); - - if(!groupData || (groupData.groupId !== parser.id)) return; - - setGroupData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.groupName = parser.title; - newValue.groupDescription = parser.description; - newValue.groupState = parser.type; - newValue.groupCanMembersDecorate = parser.canMembersDecorate; - - return newValue; - }); - }); - - useMessageEvent(GroupSettingsEvent, event => - { - const parser = event.getParser(); - - const groupBadgeParts: GroupBadgePart[] = []; - - parser.badgeParts.forEach((part, id) => - { - groupBadgeParts.push(new GroupBadgePart( - part.isBase ? GroupBadgePart.BASE : GroupBadgePart.SYMBOL, - part.key, - part.color, - part.position - )); - }); - - setGroupData({ - groupId: parser.id, - groupName: parser.title, - groupDescription: parser.description, - groupHomeroomId: parser.roomId, - groupState: parser.state, - groupCanMembersDecorate: parser.canMembersDecorate, - groupColors: [ parser.colorA, parser.colorB ], - groupBadgeParts - }); - }); - - if(!groupData || (groupData.groupId <= 0)) return null; - - return ( - - - - { TABS.map(tab => - { - return ( changeTab(tab) }> - { LocalizeText(`group.edit.tab.${ tab }`) } - ); - }) } - - - - - - { LocalizeText(`group.edit.tabcaption.${ currentTab }`) } - { LocalizeText(`group.edit.tabdesc.${ currentTab }`) } - - - - { (currentTab === 1) && - } - { (currentTab === 2) && - } - { (currentTab === 3) && - } - { (currentTab === 5) && - } - - - - ); -}; diff --git a/src/components/groups/views/GroupMembersView.tsx b/src/components/groups/views/GroupMembersView.tsx deleted file mode 100644 index 5cf1be8..0000000 --- a/src/components/groups/views/GroupMembersView.tsx +++ /dev/null @@ -1,210 +0,0 @@ -import { AddLinkEventTracker, GetSessionDataManager, GroupAdminGiveComposer, GroupAdminTakeComposer, GroupConfirmMemberRemoveEvent, GroupConfirmRemoveMemberComposer, GroupMemberParser, GroupMembersComposer, GroupMembersEvent, GroupMembershipAcceptComposer, GroupMembershipDeclineComposer, GroupMembersParser, GroupRank, GroupRemoveMemberComposer, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useState } from 'react'; -import { FaChevronLeft, FaChevronRight } from 'react-icons/fa'; -import { GetUserProfile, LocalizeText, SendMessageComposer } from '../../../api'; -import { Base, Button, Column, Flex, Grid, LayoutAvatarImageView, LayoutBadgeImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common'; -import { useMessageEvent, useNotification } from '../../../hooks'; - -export const GroupMembersView: FC<{}> = props => -{ - const [ groupId, setGroupId ] = useState(-1); - const [ levelId, setLevelId ] = useState(-1); - const [ membersData, setMembersData ] = useState(null); - const [ pageId, setPageId ] = useState(-1); - const [ totalPages, setTotalPages ] = useState(0); - const [ searchQuery, setSearchQuery ] = useState(''); - const [ removingMemberName, setRemovingMemberName ] = useState(null); - const { showConfirm = null } = useNotification(); - - const getRankDescription = (member: GroupMemberParser) => - { - if(member.rank === GroupRank.OWNER) return 'group.members.owner'; - - if(membersData.admin) - { - if(member.rank === GroupRank.ADMIN) return 'group.members.removerights'; - - if(member.rank === GroupRank.MEMBER) return 'group.members.giverights'; - } - - return ''; - } - - const refreshMembers = useCallback(() => - { - if((groupId === -1) || (levelId === -1) || (pageId === -1)) return; - - SendMessageComposer(new GroupMembersComposer(groupId, pageId, searchQuery, levelId)); - }, [ groupId, levelId, pageId, searchQuery ]); - - const toggleAdmin = (member: GroupMemberParser) => - { - if(!membersData.admin || (member.rank === GroupRank.OWNER)) return; - - if(member.rank !== GroupRank.ADMIN) SendMessageComposer(new GroupAdminGiveComposer(membersData.groupId, member.id)); - else SendMessageComposer(new GroupAdminTakeComposer(membersData.groupId, member.id)); - - refreshMembers(); - } - - const acceptMembership = (member: GroupMemberParser) => - { - if(!membersData.admin || (member.rank !== GroupRank.REQUESTED)) return; - - SendMessageComposer(new GroupMembershipAcceptComposer(membersData.groupId, member.id)); - - refreshMembers(); - } - - const removeMemberOrDeclineMembership = (member: GroupMemberParser) => - { - if(!membersData.admin) return; - - if(member.rank === GroupRank.REQUESTED) - { - SendMessageComposer(new GroupMembershipDeclineComposer(membersData.groupId, member.id)); - - refreshMembers(); - - return; - } - - setRemovingMemberName(member.name); - SendMessageComposer(new GroupConfirmRemoveMemberComposer(membersData.groupId, member.id)); - } - - useMessageEvent(GroupMembersEvent, event => - { - const parser = event.getParser(); - - setMembersData(parser); - setLevelId(parser.level); - setTotalPages(Math.ceil(parser.totalMembersCount / parser.pageSize)); - }); - - useMessageEvent(GroupConfirmMemberRemoveEvent, event => - { - const parser = event.getParser(); - - showConfirm(LocalizeText(((parser.furnitureCount > 0) ? 'group.kickconfirm.desc' : 'group.kickconfirm_nofurni.desc'), [ 'user', 'amount' ], [ removingMemberName, parser.furnitureCount.toString() ]), () => - { - SendMessageComposer(new GroupRemoveMemberComposer(membersData.groupId, parser.userId)); - - refreshMembers(); - }, null); - - setRemovingMemberName(null); - }); - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - const groupId = (parseInt(parts[1]) || -1); - const levelId = (parseInt(parts[2]) || 3); - - setGroupId(groupId); - setLevelId(levelId); - setPageId(0); - }, - eventUrlPrefix: 'group-members/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, []); - - useEffect(() => - { - setPageId(0); - }, [ groupId, levelId, searchQuery ]); - - useEffect(() => - { - if((groupId === -1) || (levelId === -1) || (pageId === -1)) return; - - SendMessageComposer(new GroupMembersComposer(groupId, pageId, searchQuery, levelId)); - }, [ groupId, levelId, pageId, searchQuery ]); - - useEffect(() => - { - if(groupId === -1) return; - - setLevelId(-1); - setMembersData(null); - setTotalPages(0); - setSearchQuery(''); - setRemovingMemberName(null); - }, [ groupId ]); - - if((groupId === -1) || !membersData) return null; - - return ( - - setGroupId(-1) } /> - - - - - - - setSearchQuery(event.target.value) } /> - - - - - { membersData.result.map((member, index) => - { - return ( - -
GetUserProfile(member.id) }> - -
- - GetUserProfile(member.id) }>{ member.name } - { (member.rank !== GroupRank.REQUESTED) && - { LocalizeText('group.members.since', [ 'date' ], [ member.joinedAt ]) } } - - - { (member.rank !== GroupRank.REQUESTED) && - - toggleAdmin(member) } /> - } - { membersData.admin && (member.rank === GroupRank.REQUESTED) && - - acceptMembership(member) }> - } - { membersData.admin && (member.rank !== GroupRank.OWNER) && (member.id !== GetSessionDataManager().userId) && - - removeMemberOrDeclineMembership(member) }> - } - -
- ); - }) } -
- - - - { LocalizeText('group.members.pageinfo', [ 'amount', 'page', 'totalPages' ], [ membersData.totalMembersCount.toString(), (membersData.pageIndex + 1).toString(), totalPages.toString() ]) } - - - -
-
- ); -}; diff --git a/src/components/groups/views/GroupRoomInformationView.tsx b/src/components/groups/views/GroupRoomInformationView.tsx deleted file mode 100644 index c8c8d99..0000000 --- a/src/components/groups/views/GroupRoomInformationView.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import { DesktopViewEvent, GetGuestRoomResultEvent, GetSessionDataManager, GroupInformationComposer, GroupInformationEvent, GroupInformationParser, GroupRemoveMemberComposer, HabboGroupDeactivatedMessageEvent, RoomEntryInfoMessageEvent } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { FaChevronDown, FaChevronUp } from 'react-icons/fa'; -import { GetGroupInformation, GetGroupManager, GroupMembershipType, GroupType, LocalizeText, SendMessageComposer, TryJoinGroup } from '../../../api'; -import { Base, Button, Column, Flex, LayoutBadgeImageView, Text } from '../../../common'; -import { useMessageEvent, useNotification } from '../../../hooks'; - -export const GroupRoomInformationView: FC<{}> = props => -{ - const [ expectedGroupId, setExpectedGroupId ] = useState(0); - const [ groupInformation, setGroupInformation ] = useState(null); - const [ isOpen, setIsOpen ] = useState(true); - const { showConfirm = null } = useNotification(); - - useMessageEvent(DesktopViewEvent, event => - { - setExpectedGroupId(0); - setGroupInformation(null); - }); - - useMessageEvent(RoomEntryInfoMessageEvent, event => - { - setExpectedGroupId(0); - setGroupInformation(null); - }); - - useMessageEvent(GetGuestRoomResultEvent, event => - { - const parser = event.getParser(); - - if(!parser.roomEnter) return; - - if(parser.data.habboGroupId > 0) - { - setExpectedGroupId(parser.data.habboGroupId); - SendMessageComposer(new GroupInformationComposer(parser.data.habboGroupId, false)); - } - else - { - setExpectedGroupId(0); - setGroupInformation(null); - } - }); - - useMessageEvent(HabboGroupDeactivatedMessageEvent, event => - { - const parser = event.getParser(); - - if(!groupInformation || ((parser.groupId !== groupInformation.id) && (parser.groupId !== expectedGroupId))) return; - - setExpectedGroupId(0); - setGroupInformation(null); - }); - - useMessageEvent(GroupInformationEvent, event => - { - const parser = event.getParser(); - - if(parser.id !== expectedGroupId) return; - - setGroupInformation(parser); - }); - - const leaveGroup = () => - { - showConfirm(LocalizeText('group.leaveconfirm.desc'), () => - { - SendMessageComposer(new GroupRemoveMemberComposer(groupInformation.id, GetSessionDataManager().userId)); - }, null); - } - - const isRealOwner = (groupInformation && (groupInformation.ownerName === GetSessionDataManager().userName)); - - const getButtonText = () => - { - if(isRealOwner) return 'group.manage'; - - if(groupInformation.type === GroupType.PRIVATE) return ''; - - if(groupInformation.membershipType === GroupMembershipType.MEMBER) return 'group.leave'; - - if((groupInformation.membershipType === GroupMembershipType.NOT_MEMBER) && groupInformation.type === GroupType.REGULAR) return 'group.join'; - - if(groupInformation.membershipType === GroupMembershipType.REQUEST_PENDING) return 'group.membershippending'; - - if((groupInformation.membershipType === GroupMembershipType.NOT_MEMBER) && groupInformation.type === GroupType.EXCLUSIVE) return 'group.requestmembership'; - } - - const handleButtonClick = () => - { - if(isRealOwner) return GetGroupManager(groupInformation.id); - - if((groupInformation.type === GroupType.PRIVATE) && (groupInformation.membershipType === GroupMembershipType.NOT_MEMBER)) return; - - if(groupInformation.membershipType === GroupMembershipType.MEMBER) - { - leaveGroup(); - - return; - } - - TryJoinGroup(groupInformation.id); - } - - if(!groupInformation) return null; - - return ( - - - setIsOpen(value => !value) }> - { LocalizeText('group.homeroominfo.title') } - { isOpen && } - { !isOpen && } - - { isOpen && - <> - GetGroupInformation(groupInformation.id) }> - - - - { groupInformation.title } - - { (groupInformation.type !== GroupType.PRIVATE || isRealOwner) && - - } - } - - - ); -}; diff --git a/src/components/groups/views/tabs/GroupTabBadgeView.tsx b/src/components/groups/views/tabs/GroupTabBadgeView.tsx deleted file mode 100644 index 73d65c0..0000000 --- a/src/components/groups/views/tabs/GroupTabBadgeView.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import { GroupSaveBadgeComposer } from '@nitrots/nitro-renderer'; -import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react'; -import { GroupBadgePart, IGroupData, SendMessageComposer } from '../../../../api'; -import { Column, Flex, Grid, LayoutBadgeImageView } from '../../../../common'; -import { useGroup } from '../../../../hooks'; -import { GroupBadgeCreatorView } from '../GroupBadgeCreatorView'; - -interface GroupTabBadgeViewProps -{ - skipDefault?: boolean; - setCloseAction: Dispatch boolean }>>; - groupData: IGroupData; - setGroupData: Dispatch>; -} - -export const GroupTabBadgeView: FC = props => -{ - const { groupData = null, setGroupData = null, setCloseAction = null, skipDefault = null } = props; - const [ badgeParts, setBadgeParts ] = useState(null); - const { groupCustomize = null } = useGroup(); - - const getModifiedBadgeCode = () => - { - if(!badgeParts || !badgeParts.length) return ''; - - let badgeCode = ''; - - badgeParts.forEach(part => (part.code && (badgeCode += part.code))); - - return badgeCode; - } - - const saveBadge = useCallback(() => - { - if(!groupData || !badgeParts || !badgeParts.length) return false; - - if((groupData.groupBadgeParts === badgeParts)) return true; - - if(groupData.groupId <= 0) - { - setGroupData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.groupBadgeParts = badgeParts; - - return newValue; - }); - - return true; - } - - const badge = []; - - badgeParts.forEach(part => - { - if(!part.code) return; - - badge.push(part.key); - badge.push(part.color); - badge.push(part.position); - }); - - SendMessageComposer(new GroupSaveBadgeComposer(groupData.groupId, badge)); - - return true; - }, [ groupData, badgeParts, setGroupData ]); - - useEffect(() => - { - if(groupData.groupBadgeParts) return; - - const badgeParts = [ - new GroupBadgePart(GroupBadgePart.BASE, groupCustomize.badgeBases[0].id, groupCustomize.badgePartColors[0].id), - new GroupBadgePart(GroupBadgePart.SYMBOL, 0, groupCustomize.badgePartColors[0].id), - new GroupBadgePart(GroupBadgePart.SYMBOL, 0, groupCustomize.badgePartColors[0].id), - new GroupBadgePart(GroupBadgePart.SYMBOL, 0, groupCustomize.badgePartColors[0].id), - new GroupBadgePart(GroupBadgePart.SYMBOL, 0, groupCustomize.badgePartColors[0].id) - ]; - - setGroupData(prevValue => - { - const groupBadgeParts = badgeParts; - - return { ...prevValue, groupBadgeParts }; - }); - }, [ groupData.groupBadgeParts, groupCustomize, setGroupData ]); - - useEffect(() => - { - if(groupData.groupId <= 0) - { - setBadgeParts(groupData.groupBadgeParts ? [ ...groupData.groupBadgeParts ] : null); - - return; - } - - setBadgeParts(groupData.groupBadgeParts); - }, [ groupData ]); - - useEffect(() => - { - setCloseAction({ action: saveBadge }); - - return () => setCloseAction(null); - }, [ setCloseAction, saveBadge ]); - - return ( - - - - - - - - - - - ); -}; diff --git a/src/components/groups/views/tabs/GroupTabColorsView.tsx b/src/components/groups/views/tabs/GroupTabColorsView.tsx deleted file mode 100644 index 61f3c86..0000000 --- a/src/components/groups/views/tabs/GroupTabColorsView.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { GroupSaveColorsComposer } from '@nitrots/nitro-renderer'; -import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react'; -import { IGroupData, LocalizeText, SendMessageComposer } from '../../../../api'; -import { AutoGrid, Base, classNames, Column, Flex, Grid, Text } from '../../../../common'; -import { useGroup } from '../../../../hooks'; - -interface GroupTabColorsViewProps -{ - groupData: IGroupData; - setGroupData: Dispatch>; - setCloseAction: Dispatch boolean }>>; -} - -export const GroupTabColorsView: FC = props => -{ - const { groupData = null, setGroupData = null, setCloseAction = null } = props; - const [ colors, setColors ] = useState(null); - const { groupCustomize = null } = useGroup(); - - const getGroupColor = (colorIndex: number) => - { - if(colorIndex === 0) return groupCustomize.groupColorsA.find(color => (color.id === colors[colorIndex])).color; - - return groupCustomize.groupColorsB.find(color => (color.id === colors[colorIndex])).color; - } - - const selectColor = (colorIndex: number, colorId: number) => - { - setColors(prevValue => - { - const newColors = [ ...prevValue ]; - - newColors[colorIndex] = colorId; - - return newColors; - }); - } - - const saveColors = useCallback(() => - { - if(!groupData || !colors || !colors.length) return false; - - if(groupData.groupColors === colors) return true; - - if(groupData.groupId <= 0) - { - setGroupData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.groupColors = [ ...colors ]; - - return newValue; - }); - - return true; - } - - SendMessageComposer(new GroupSaveColorsComposer(groupData.groupId, colors[0], colors[1])); - - return true; - }, [ groupData, colors, setGroupData ]); - - useEffect(() => - { - if(!groupCustomize.groupColorsA || !groupCustomize.groupColorsB || groupData.groupColors) return; - - const groupColors = [ groupCustomize.groupColorsA[0].id, groupCustomize.groupColorsB[0].id ]; - - setGroupData(prevValue => - { - return { ...prevValue, groupColors }; - }); - }, [ groupCustomize, groupData.groupColors, setGroupData ]); - - useEffect(() => - { - if(groupData.groupId <= 0) - { - setColors(groupData.groupColors ? [ ...groupData.groupColors ] : null); - - return; - } - - setColors(groupData.groupColors); - }, [ groupData ]); - - useEffect(() => - { - setCloseAction({ action: saveColors }); - - return () => setCloseAction(null); - }, [ setCloseAction, saveColors ]); - - if(!colors) return null; - - return ( - - - { LocalizeText('group.edit.color.guild.color') } - { groupData.groupColors && (groupData.groupColors.length > 0) && - - - - } - - - { LocalizeText('group.edit.color.primary.color') } - - { groupData.groupColors && groupCustomize.groupColorsA && groupCustomize.groupColorsA.map((item, index) => - { - return
selectColor(0, item.id) }>
- }) } -
-
- - { LocalizeText('group.edit.color.secondary.color') } - - { groupData.groupColors && groupCustomize.groupColorsB && groupCustomize.groupColorsB.map((item, index) => - { - return
selectColor(1, item.id) }>
- }) } -
-
-
- ); -}; diff --git a/src/components/groups/views/tabs/GroupTabCreatorConfirmationView.tsx b/src/components/groups/views/tabs/GroupTabCreatorConfirmationView.tsx deleted file mode 100644 index 3046038..0000000 --- a/src/components/groups/views/tabs/GroupTabCreatorConfirmationView.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { Dispatch, FC, SetStateAction } from 'react'; -import { IGroupData, LocalizeText } from '../../../../api'; -import { Base, Column, Flex, Grid, LayoutBadgeImageView, Text } from '../../../../common'; -import { useGroup } from '../../../../hooks'; - -interface GroupTabCreatorConfirmationViewProps -{ - groupData: IGroupData; - setGroupData: Dispatch>; - purchaseCost: number; -} - -export const GroupTabCreatorConfirmationView: FC = props => -{ - const { groupData = null, setGroupData = null, purchaseCost = 0 } = props; - const { groupCustomize = null } = useGroup(); - - const getCompleteBadgeCode = () => - { - if(!groupData || !groupData.groupBadgeParts || !groupData.groupBadgeParts.length) return ''; - - let badgeCode = ''; - - groupData.groupBadgeParts.forEach(part => (part.code && (badgeCode += part.code))); - - return badgeCode; - } - - const getGroupColor = (colorIndex: number) => - { - if(colorIndex === 0) return groupCustomize.groupColorsA.find(c => c.id === groupData.groupColors[colorIndex]).color; - - return groupCustomize.groupColorsB.find(c => c.id === groupData.groupColors[colorIndex]).color; - } - - if(!groupData) return null; - - return ( - - - - { LocalizeText('group.create.confirm.guildbadge') } - - - - { LocalizeText('group.edit.color.guild.color') } - - - - - - - - - - { groupData.groupName } - { groupData.groupDescription } - - { LocalizeText('group.create.confirm.info') } - - - { LocalizeText('group.create.confirm.buyinfo', [ 'amount' ], [ purchaseCost.toString() ]) } - - - - ); -}; diff --git a/src/components/groups/views/tabs/GroupTabIdentityView.tsx b/src/components/groups/views/tabs/GroupTabIdentityView.tsx deleted file mode 100644 index 3a35d47..0000000 --- a/src/components/groups/views/tabs/GroupTabIdentityView.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import { CreateLinkEvent, GroupDeleteComposer, GroupSaveInformationComposer } from '@nitrots/nitro-renderer'; -import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react'; -import { IGroupData, LocalizeText, SendMessageComposer } from '../../../../api'; -import { Base, Button, Column, Flex, Text } from '../../../../common'; -import { useNotification } from '../../../../hooks'; - -interface GroupTabIdentityViewProps -{ - groupData: IGroupData; - setGroupData: Dispatch>; - setCloseAction: Dispatch boolean }>>; - onClose: () => void; - isCreator?: boolean; - availableRooms?: { id: number, name: string }[]; -} - -export const GroupTabIdentityView: FC = props => -{ - const { groupData = null, setGroupData = null, setCloseAction = null, onClose = null, isCreator = false, availableRooms = [] } = props; - const [ groupName, setGroupName ] = useState(''); - const [ groupDescription, setGroupDescription ] = useState(''); - const [ groupHomeroomId, setGroupHomeroomId ] = useState(-1); - const { showConfirm = null } = useNotification(); - - const deleteGroup = () => - { - if(!groupData || (groupData.groupId <= 0)) return; - - showConfirm(LocalizeText('group.deleteconfirm.desc'), () => - { - SendMessageComposer(new GroupDeleteComposer(groupData.groupId)); - - if(onClose) onClose(); - }, null, null, null, LocalizeText('group.deleteconfirm.title')); - } - - const saveIdentity = useCallback(() => - { - if(!groupData || !groupName || !groupName.length) return false; - - if((groupName === groupData.groupName) && (groupDescription === groupData.groupDescription)) return true; - - if(groupData.groupId <= 0) - { - if(groupHomeroomId <= 0) return false; - - setGroupData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.groupName = groupName; - newValue.groupDescription = groupDescription; - newValue.groupHomeroomId = groupHomeroomId; - - return newValue; - }); - - return true; - } - - SendMessageComposer(new GroupSaveInformationComposer(groupData.groupId, groupName, (groupDescription || ''))); - - return true; - }, [ groupData, groupName, groupDescription, groupHomeroomId, setGroupData ]); - - useEffect(() => - { - setGroupName(groupData.groupName || ''); - setGroupDescription(groupData.groupDescription || ''); - setGroupHomeroomId(groupData.groupHomeroomId); - }, [ groupData ]); - - useEffect(() => - { - setCloseAction({ action: saveIdentity }); - - return () => setCloseAction(null); - }, [ setCloseAction, saveIdentity ]); - - if(!groupData) return null; - - return ( - - - - { LocalizeText('group.edit.name') } - setGroupName(event.target.value) } /> - - - { LocalizeText('group.edit.desc') } - - - - ); -}; diff --git a/src/components/guide-tool/views/GuideToolUserFeedbackView.tsx b/src/components/guide-tool/views/GuideToolUserFeedbackView.tsx deleted file mode 100644 index 9ec7280..0000000 --- a/src/components/guide-tool/views/GuideToolUserFeedbackView.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { GuideSessionFeedbackMessageComposer } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { LocalizeText, SendMessageComposer } from '../../../api'; -import { Button, Column, Flex, Text } from '../../../common'; - -interface GuideToolUserFeedbackViewProps -{ - userName: string; -} - -export const GuideToolUserFeedbackView: FC = props => -{ - const { userName = null } = props; - - const giveFeedback = (recommend: boolean) => SendMessageComposer(new GuideSessionFeedbackMessageComposer(recommend)); - - return ( - - - - { userName } - { LocalizeText('guide.help.request.user.feedback.guide.desc') } - - - - - { LocalizeText('guide.help.request.user.feedback.closed.title') } - { LocalizeText('guide.help.request.user.feedback.closed.desc') } - - { userName && (userName.length > 0) && - <> -
- - { LocalizeText('guide.help.request.user.feedback.question') } - - - - - - } -
- ); -}; diff --git a/src/components/guide-tool/views/GuideToolUserNoHelpersView.tsx b/src/components/guide-tool/views/GuideToolUserNoHelpersView.tsx deleted file mode 100644 index 6fcbfd5..0000000 --- a/src/components/guide-tool/views/GuideToolUserNoHelpersView.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText } from '../../../api'; -import { Column, Text } from '../../../common'; - -export const GuideToolUserNoHelpersView: FC<{}> = props => -{ - return ( - - { LocalizeText('guide.help.request.no_tour_guides.title') } - { LocalizeText('guide.help.request.no_tour_guides.message') } - - ); -}; \ No newline at end of file diff --git a/src/components/guide-tool/views/GuideToolUserPendingView.tsx b/src/components/guide-tool/views/GuideToolUserPendingView.tsx deleted file mode 100644 index 81faaff..0000000 --- a/src/components/guide-tool/views/GuideToolUserPendingView.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { GuideSessionRequesterCancelsMessageComposer } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { LocalizeText, SendMessageComposer } from '../../../api'; -import { Button, Column, Text } from '../../../common'; - -interface GuideToolUserPendingViewProps -{ - helpRequestDescription: string; - helpRequestAverageTime: number; -} - -export const GuideToolUserPendingView: FC = props => -{ - const { helpRequestDescription = null, helpRequestAverageTime = 0 } = props; - - const cancelRequest = () => SendMessageComposer(new GuideSessionRequesterCancelsMessageComposer()); - - return ( - - - { LocalizeText('guide.help.request.guide.accept.request.title') } - { LocalizeText('guide.help.request.type.1') } - { helpRequestDescription } - - - { LocalizeText('guide.help.request.user.pending.info.title') } - { LocalizeText('guide.help.request.user.pending.info.message') } - { LocalizeText('guide.help.request.user.pending.info.waiting', [ 'waitingtime' ], [ helpRequestAverageTime.toString() ]) } - - - - ); -}; diff --git a/src/components/guide-tool/views/GuideToolUserSomethingWrogView.tsx b/src/components/guide-tool/views/GuideToolUserSomethingWrogView.tsx deleted file mode 100644 index 1e8ec5e..0000000 --- a/src/components/guide-tool/views/GuideToolUserSomethingWrogView.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText } from '../../../api'; -import { Column, Text } from '../../../common'; - -export const GuideToolUserSomethingWrogView: FC<{}> = props => -{ - return ( - - { LocalizeText('guide.help.request.user.guide.disconnected.error.desc') } - - ); -}; \ No newline at end of file diff --git a/src/components/guide-tool/views/GuideToolUserThanksView.tsx b/src/components/guide-tool/views/GuideToolUserThanksView.tsx deleted file mode 100644 index 4953b0f..0000000 --- a/src/components/guide-tool/views/GuideToolUserThanksView.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText } from '../../../api'; -import { Column, Text } from '../../../common'; - -export const GuideToolUserThanksView: FC<{}> = props => -{ - return ( - - { LocalizeText('guide.help.request.user.thanks.info.title') } - { LocalizeText('guide.help.request.user.thanks.info.desc') } - - ); -}; diff --git a/src/components/hc-center/HcCenterView.scss b/src/components/hc-center/HcCenterView.scss deleted file mode 100644 index a6af9fa..0000000 --- a/src/components/hc-center/HcCenterView.scss +++ /dev/null @@ -1,44 +0,0 @@ -.nitro-hc-center { - width: 430px; - resize: none; - - .hc-logo { - width: 213px; - height: 37px; - background-image: url('@/assets/images/hc-center/hc_logo.gif'); - } - - .payday-special { - height: 128px; - } - - .payday { - width: 222px; - height: 150px; - background-image: url('@/assets/images/hc-center/payday.png'); - z-index: 3; - color: #6b3502; - } - - .clock { - width: 24px; - height: 24px; - background-image: url('@/assets/images/hc-center/clock.png'); - } - - .streak-info { - min-height: 64px; - line-height: 16px; - } - - .habbo-avatar { - z-index: 4; - } - - .benefits { - background-image: url('@/assets/images/hc-center/benefits.png'); - background-position: right top; - background-repeat: no-repeat; - height: 100%; - } -} diff --git a/src/components/hc-center/HcCenterView.tsx b/src/components/hc-center/HcCenterView.tsx deleted file mode 100644 index 08c6172..0000000 --- a/src/components/hc-center/HcCenterView.tsx +++ /dev/null @@ -1,204 +0,0 @@ -import { AddLinkEventTracker, ClubGiftInfoEvent, CreateLinkEvent, GetClubGiftInfo, ILinkEventTracker, RemoveLinkEventTracker, ScrGetKickbackInfoMessageComposer, ScrKickbackData, ScrSendKickbackInfoMessageEvent } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { OverlayTrigger, Popover } from 'react-bootstrap'; -import { ClubStatus, FriendlyTime, GetClubBadge, GetConfigurationValue, LocalizeText, SendMessageComposer } from '../../api'; -import { Base, Button, Column, Flex, LayoutAvatarImageView, LayoutBadgeImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common'; -import { useInventoryBadges, useMessageEvent, usePurse, useSessionInfo } from '../../hooks'; - - -export const HcCenterView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ kickbackData, setKickbackData ] = useState(null); - const [ unclaimedGifts, setUnclaimedGifts ] = useState(0); - const [ badgeCode, setBadgeCode ] = useState(null); - const { userFigure = null } = useSessionInfo(); - const { purse = null, clubStatus = null } = usePurse(); - const { badgeCodes = [], activate = null, deactivate = null } = useInventoryBadges(); - - const getClubText = () => - { - if(purse.clubDays <= 0) return LocalizeText('purse.clubdays.zero.amount.text'); - - if((purse.minutesUntilExpiration > -1) && (purse.minutesUntilExpiration < (60 * 24))) - { - return FriendlyTime.shortFormat(purse.minutesUntilExpiration * 60); - } - - return FriendlyTime.shortFormat(((purse.clubPeriods * 31) + purse.clubDays) * 86400); - } - - const getInfoText = () => - { - switch(clubStatus) - { - case ClubStatus.ACTIVE: - return LocalizeText(`hccenter.status.${ clubStatus }.info`, [ 'timeleft', 'joindate', 'streakduration' ], [ getClubText(), kickbackData?.firstSubscriptionDate, FriendlyTime.shortFormat(kickbackData?.currentHcStreak * 86400) ]); - case ClubStatus.EXPIRED: - return LocalizeText(`hccenter.status.${ clubStatus }.info`, [ 'joindate' ], [ kickbackData?.firstSubscriptionDate ]); - default: - return LocalizeText(`hccenter.status.${ clubStatus }.info`); - } - } - - const getHcPaydayTime = () => (!kickbackData || kickbackData.timeUntilPayday < 60) ? LocalizeText('hccenter.special.time.soon') : FriendlyTime.shortFormat(kickbackData.timeUntilPayday * 60); - const getHcPaydayAmount = () => LocalizeText('hccenter.special.sum', [ 'credits' ], [ (kickbackData?.creditRewardForStreakBonus + kickbackData?.creditRewardForMonthlySpent).toString() ]); - - useMessageEvent(ClubGiftInfoEvent, event => - { - const parser = event.getParser(); - - setUnclaimedGifts(parser.giftsAvailable); - }); - - useMessageEvent(ScrSendKickbackInfoMessageEvent, event => - { - const parser = event.getParser(); - - setKickbackData(parser.data); - }); - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'open': - if(parts.length > 2) - { - switch(parts[2]) - { - case 'hccenter': - setIsVisible(true); - break; - } - } - return; - } - }, - eventUrlPrefix: 'habboUI/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, []); - - useEffect(() => - { - setBadgeCode(GetClubBadge(badgeCodes)); - }, [ badgeCodes ]); - - useEffect(() => - { - if(!isVisible) return; - - const id = activate(); - - return () => deactivate(id); - }, [ isVisible, activate, deactivate ]); - - useEffect(() => - { - SendMessageComposer(new GetClubGiftInfo()); - SendMessageComposer(new ScrGetKickbackInfoMessageComposer()); - }, []); - - if(!isVisible) return null; - - const popover = ( - - -
{ LocalizeText('hccenter.breakdown.title') }
-
{ LocalizeText('hccenter.breakdown.creditsspent', [ 'credits' ], [ kickbackData?.totalCreditsSpent.toString() ]) }
-
{ LocalizeText('hccenter.breakdown.paydayfactor.percent', [ 'percent' ], [ (kickbackData?.kickbackPercentage * 100).toString() ]) }
-
{ LocalizeText('hccenter.breakdown.streakbonus', [ 'credits' ], [ kickbackData?.creditRewardForStreakBonus.toString() ]) }
-
-
{ LocalizeText('hccenter.breakdown.total', [ 'credits', 'actual' ], [ getHcPaydayAmount(), ((((kickbackData?.kickbackPercentage * kickbackData?.totalCreditsSpent) + kickbackData?.creditRewardForStreakBonus) * 100) / 100).toString() ]) }
-
CreateLinkEvent('habbopages/' + GetConfigurationValue('hc.center')['payday.habbopage']) }> - { LocalizeText('hccenter.special.infolink') } -
-
-
- ); - - return ( - - setIsVisible(false) } /> - - -
- - - - - - - - - - - - - { LocalizeText('hccenter.status.' + clubStatus) } - - - - { GetConfigurationValue('hc.center')['payday.info'] && - - - -

{ LocalizeText('hccenter.special.title') }

-
{ LocalizeText('hccenter.special.info') }
-
CreateLinkEvent('habbopages/' + GetConfigurationValue('hc.center')['payday.habbopage']) }>{ LocalizeText('hccenter.special.infolink') }
-
-
-
{ LocalizeText('hccenter.special.time.title') }
-
-
-
{ getHcPaydayTime() }
-
- { clubStatus === ClubStatus.ACTIVE && -
-
{ LocalizeText('hccenter.special.amount.title') }
-
-
{ getHcPaydayAmount() }
- -
- { LocalizeText('hccenter.breakdown.infolink') } -
-
-
-
} -
- } - { GetConfigurationValue('hc.center')['gift.info'] && -
-
-

{ LocalizeText('hccenter.gift.title') }

-
0 ? LocalizeText('hccenter.unclaimedgifts', [ 'unclaimedgifts' ], [ unclaimedGifts.toString() ]) : LocalizeText('hccenter.gift.info') } }>
-
- -
} - { GetConfigurationValue('hc.center')['benefits.info'] && -
-
{ LocalizeText('hccenter.general.title') }
-
- -
} - - - ); -} diff --git a/src/components/help/HelpView.scss b/src/components/help/HelpView.scss deleted file mode 100644 index abe4189..0000000 --- a/src/components/help/HelpView.scss +++ /dev/null @@ -1,18 +0,0 @@ -.nitro-help { - height: $help-height; - width: $help-width; - - .index-image { - background: url('@/assets/images/help/help_index.png'); - width: 126px; - height: 105px; - } -} - -.nitro-cfh-sanction-status { - width: 400px; -} - -.nitro-change-username { - width: 300px; -} diff --git a/src/components/help/HelpView.tsx b/src/components/help/HelpView.tsx deleted file mode 100644 index f37e42e..0000000 --- a/src/components/help/HelpView.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import { AddLinkEventTracker, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, ReportState } from '../../api'; -import { Base, Column, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common'; -import { useHelp } from '../../hooks'; -import { DescribeReportView } from './views/DescribeReportView'; -import { HelpIndexView } from './views/HelpIndexView'; -import { ReportSummaryView } from './views/ReportSummaryView'; -import { SanctionSatusView } from './views/SanctionStatusView'; -import { SelectReportedChatsView } from './views/SelectReportedChatsView'; -import { SelectReportedUserView } from './views/SelectReportedUserView'; -import { SelectTopicView } from './views/SelectTopicView'; -import { NameChangeView } from './views/name-change/NameChangeView'; - -export const HelpView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const { activeReport = null, setActiveReport = null, report = null } = useHelp(); - - const onClose = () => - { - setActiveReport(null); - setIsVisible(false); - } - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setIsVisible(true); - return; - case 'hide': - setIsVisible(false); - return; - case 'toggle': - setIsVisible(prevValue => !prevValue); - return; - case 'tour': - // todo: launch tour - return; - case 'report': - if((parts.length >= 5) && (parts[2] === 'room')) - { - const roomId = parseInt(parts[3]); - const unknown = unescape(parts.splice(4).join('/')); - //this.reportRoom(roomId, unknown, ""); - } - return; - } - }, - eventUrlPrefix: 'help/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, []); - - useEffect(() => - { - if(!activeReport) return; - - setIsVisible(true); - }, [ activeReport ]); - - const CurrentStepView = () => - { - if(activeReport) - { - switch(activeReport.currentStep) - { - case ReportState.SELECT_USER: - return ; - case ReportState.SELECT_CHATS: - return ; - case ReportState.SELECT_TOPICS: - return ; - case ReportState.INPUT_REPORT_MESSAGE: - return ; - case ReportState.REPORT_SUMMARY: - return ; - } - } - - return ; - } - - return ( - <> - { isVisible && - - - - - - - - - - - - - } - - - - ); -} diff --git a/src/components/help/views/DescribeReportView.tsx b/src/components/help/views/DescribeReportView.tsx deleted file mode 100644 index 5f231d3..0000000 --- a/src/components/help/views/DescribeReportView.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { FC, useState } from 'react'; -import { LocalizeText, ReportState, ReportType } from '../../../api'; -import { Button, Column, Flex, Text } from '../../../common'; -import { useHelp } from '../../../hooks'; - -export const DescribeReportView: FC<{}> = props => -{ - const [ message, setMessage ] = useState(''); - const { activeReport = null, setActiveReport = null } = useHelp(); - - const submitMessage = () => - { - if(message.length < 15) return; - - setActiveReport(prevValue => - { - const currentStep = ReportState.REPORT_SUMMARY; - - return { ...prevValue, message, currentStep }; - }); - } - - const back = () => - { - setActiveReport(prevValue => - { - return { ...prevValue, currentStep: (prevValue.currentStep - 1) }; - }); - } - - return ( - <> - - { LocalizeText('help.emergency.chat_report.subtitle') } - { LocalizeText('help.cfh.input.text') } - - - - - - - - - ); -} diff --git a/src/components/mod-tools/views/tickets/CfhChatlogView.tsx b/src/components/mod-tools/views/tickets/CfhChatlogView.tsx deleted file mode 100644 index c8bdd7b..0000000 --- a/src/components/mod-tools/views/tickets/CfhChatlogView.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { CfhChatlogData, CfhChatlogEvent, GetCfhChatlogMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { SendMessageComposer } from '../../../../api'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common'; -import { useMessageEvent } from '../../../../hooks'; -import { ChatlogView } from '../chatlog/ChatlogView'; - -interface CfhChatlogViewProps -{ - issueId: number; - onCloseClick(): void; -} - -export const CfhChatlogView: FC = props => -{ - const { onCloseClick = null, issueId = null } = props; - const [ chatlogData, setChatlogData ] = useState(null); - - useMessageEvent(CfhChatlogEvent, event => - { - const parser = event.getParser(); - - if(!parser || parser.data.issueId !== issueId) return; - - setChatlogData(parser.data); - }); - - useEffect(() => - { - SendMessageComposer(new GetCfhChatlogMessageComposer(issueId)); - }, [ issueId ]); - - return ( - - - - { chatlogData && } - - - ); -} diff --git a/src/components/mod-tools/views/tickets/ModToolsIssueInfoView.tsx b/src/components/mod-tools/views/tickets/ModToolsIssueInfoView.tsx deleted file mode 100644 index 1179d41..0000000 --- a/src/components/mod-tools/views/tickets/ModToolsIssueInfoView.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { CloseIssuesMessageComposer, ReleaseIssuesMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { GetIssueCategoryName, LocalizeText, SendMessageComposer } from '../../../../api'; -import { Button, Column, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; -import { useModTools } from '../../../../hooks'; -import { CfhChatlogView } from './CfhChatlogView'; - -interface IssueInfoViewProps -{ - issueId: number; - onIssueInfoClosed(issueId: number): void; -} - -export const ModToolsIssueInfoView: FC = props => -{ - const { issueId = null, onIssueInfoClosed = null } = props; - const [ cfhChatlogOpen, setcfhChatlogOpen ] = useState(false); - const { tickets = [], openUserInfo = null } = useModTools(); - const ticket = tickets.find(issue => (issue.issueId === issueId)); - - const releaseIssue = (issueId: number) => - { - SendMessageComposer(new ReleaseIssuesMessageComposer([ issueId ])); - - onIssueInfoClosed(issueId); - } - - const closeIssue = (resolutionType: number) => - { - SendMessageComposer(new CloseIssuesMessageComposer([ issueId ], resolutionType)); - - onIssueInfoClosed(issueId) - } - - return ( - <> - - onIssueInfoClosed(issueId) } /> - - Issue Information - - - - - - - - - - - - - - - - - - - - - - - - - -
Source{ GetIssueCategoryName(ticket.categoryId) }
Category{ LocalizeText('help.cfh.topic.' + ticket.reportedCategoryId) }
Description{ ticket.message }
Caller - openUserInfo(ticket.reporterUserId) }>{ ticket.reporterUserName } -
Reported User - openUserInfo(ticket.reportedUserId) }>{ ticket.reportedUserName } -
-
- - - - - - - -
-
-
- { cfhChatlogOpen && - setcfhChatlogOpen(false) }/> } - - ); -} diff --git a/src/components/mod-tools/views/tickets/ModToolsMyIssuesTabView.tsx b/src/components/mod-tools/views/tickets/ModToolsMyIssuesTabView.tsx deleted file mode 100644 index 2e1827a..0000000 --- a/src/components/mod-tools/views/tickets/ModToolsMyIssuesTabView.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { IssueMessageData, ReleaseIssuesMessageComposer } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { SendMessageComposer } from '../../../../api'; -import { Base, Button, Column, Grid } from '../../../../common'; - -interface ModToolsMyIssuesTabViewProps -{ - myIssues: IssueMessageData[]; - handleIssue: (issueId: number) => void; -} - -export const ModToolsMyIssuesTabView: FC = props => -{ - const { myIssues = null, handleIssue = null } = props; - - return ( - - - - Type - Room/Player - Opened - - - - - - { myIssues && (myIssues.length > 0) && myIssues.map(issue => - { - return ( - - { issue.categoryId } - { issue.reportedUserName } - { new Date(Date.now() - issue.issueAgeInMilliseconds).toLocaleTimeString() } - - - - - - - - ); - }) } - - - ); -} diff --git a/src/components/mod-tools/views/tickets/ModToolsOpenIssuesTabView.tsx b/src/components/mod-tools/views/tickets/ModToolsOpenIssuesTabView.tsx deleted file mode 100644 index 6ee23cd..0000000 --- a/src/components/mod-tools/views/tickets/ModToolsOpenIssuesTabView.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { IssueMessageData, PickIssuesMessageComposer } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { SendMessageComposer } from '../../../../api'; -import { Base, Button, Column, Grid } from '../../../../common'; - -interface ModToolsOpenIssuesTabViewProps -{ - openIssues: IssueMessageData[]; -} - -export const ModToolsOpenIssuesTabView: FC = props => -{ - const { openIssues = null } = props; - - return ( - - - - Type - Room/Player - Opened - - - - - { openIssues && (openIssues.length > 0) && openIssues.map(issue => - { - return ( - - { issue.categoryId } - { issue.reportedUserName } - { new Date(Date.now() - issue.issueAgeInMilliseconds).toLocaleTimeString() } - - - - - ); - }) } - - - ); -} diff --git a/src/components/mod-tools/views/tickets/ModToolsPickedIssuesTabView.tsx b/src/components/mod-tools/views/tickets/ModToolsPickedIssuesTabView.tsx deleted file mode 100644 index 19b899b..0000000 --- a/src/components/mod-tools/views/tickets/ModToolsPickedIssuesTabView.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { IssueMessageData } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { Base, Column, Grid } from '../../../../common'; - -interface ModToolsPickedIssuesTabViewProps -{ - pickedIssues: IssueMessageData[]; -} - -export const ModToolsPickedIssuesTabView: FC = props => -{ - const { pickedIssues = null } = props; - - return ( - - - - Type - Room/Player - Opened - Picker - - - - { pickedIssues && (pickedIssues.length > 0) && pickedIssues.map(issue => - { - return ( - - { issue.categoryId } - { issue.reportedUserName } - { new Date(Date.now() - issue.issueAgeInMilliseconds).toLocaleTimeString() } - { issue.pickerUserName } - - ); - }) } - - - ); -} diff --git a/src/components/mod-tools/views/tickets/ModToolsTicketsView.tsx b/src/components/mod-tools/views/tickets/ModToolsTicketsView.tsx deleted file mode 100644 index 76d6abd..0000000 --- a/src/components/mod-tools/views/tickets/ModToolsTicketsView.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { GetSessionDataManager, IssueMessageData } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../common'; -import { useModTools } from '../../../../hooks'; -import { ModToolsIssueInfoView } from './ModToolsIssueInfoView'; -import { ModToolsMyIssuesTabView } from './ModToolsMyIssuesTabView'; -import { ModToolsOpenIssuesTabView } from './ModToolsOpenIssuesTabView'; -import { ModToolsPickedIssuesTabView } from './ModToolsPickedIssuesTabView'; - -interface ModToolsTicketsViewProps -{ - onCloseClick: () => void; -} - -const TABS: string[] = [ - 'Open Issues', - 'My Issues', - 'Picked Issues' -]; - -export const ModToolsTicketsView: FC = props => -{ - const { onCloseClick = null } = props; - const [ currentTab, setCurrentTab ] = useState(0); - const [ issueInfoWindows, setIssueInfoWindows ] = useState([]); - const { tickets = [] } = useModTools(); - - const openIssues = tickets.filter(issue => issue.state === IssueMessageData.STATE_OPEN); - const myIssues = tickets.filter(issue => (issue.state === IssueMessageData.STATE_PICKED) && (issue.pickerUserId === GetSessionDataManager().userId)); - const pickedIssues = tickets.filter(issue => issue.state === IssueMessageData.STATE_PICKED); - - const closeIssue = (issueId: number) => - { - setIssueInfoWindows(prevValue => - { - const newValue = [ ...prevValue ]; - const existingIndex = newValue.indexOf(issueId); - - if(existingIndex >= 0) newValue.splice(existingIndex, 1); - - return newValue; - }); - } - - const handleIssue = (issueId: number) => - { - setIssueInfoWindows(prevValue => - { - const newValue = [ ...prevValue ]; - const existingIndex = newValue.indexOf(issueId); - - if(existingIndex === -1) newValue.push(issueId); - else newValue.splice(existingIndex, 1); - - return newValue; - }) - } - - const CurrentTabComponent = () => - { - switch(currentTab) - { - case 0: return ; - case 1: return ; - case 2: return ; - } - - return null; - } - - return ( - <> - - - - { TABS.map((tab, index) => - { - return ( setCurrentTab(index) }> - { tab } - ); - }) } - - - - - - { issueInfoWindows && (issueInfoWindows.length > 0) && issueInfoWindows.map(issueId => ) } - - ); -} diff --git a/src/components/mod-tools/views/user/ModToolsUserChatlogView.tsx b/src/components/mod-tools/views/user/ModToolsUserChatlogView.tsx deleted file mode 100644 index 7bfb2e1..0000000 --- a/src/components/mod-tools/views/user/ModToolsUserChatlogView.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { ChatRecordData, GetUserChatlogMessageComposer, UserChatlogEvent } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { SendMessageComposer } from '../../../../api'; -import { DraggableWindowPosition, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common'; -import { useMessageEvent } from '../../../../hooks'; -import { ChatlogView } from '../chatlog/ChatlogView'; - -interface ModToolsUserChatlogViewProps -{ - userId: number; - onCloseClick: () => void; -} - -export const ModToolsUserChatlogView: FC = props => -{ - const { userId = null, onCloseClick = null } = props; - const [ userChatlog, setUserChatlog ] = useState(null); - const [ username, setUsername ] = useState(null); - - useMessageEvent(UserChatlogEvent, event => - { - const parser = event.getParser(); - - if(!parser || parser.data.userId !== userId) return; - - setUsername(parser.data.username); - setUserChatlog(parser.data.roomChatlogs); - }); - - useEffect(() => - { - SendMessageComposer(new GetUserChatlogMessageComposer(userId)); - }, [ userId ]); - - return ( - - - - { userChatlog && - } - - - ); -} diff --git a/src/components/mod-tools/views/user/ModToolsUserModActionView.tsx b/src/components/mod-tools/views/user/ModToolsUserModActionView.tsx deleted file mode 100644 index bd4c2d5..0000000 --- a/src/components/mod-tools/views/user/ModToolsUserModActionView.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import { CallForHelpTopicData, DefaultSanctionMessageComposer, ModAlertMessageComposer, ModBanMessageComposer, ModKickMessageComposer, ModMessageMessageComposer, ModMuteMessageComposer, ModTradingLockMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useMemo, useState } from 'react'; -import { ISelectedUser, LocalizeText, ModActionDefinition, NotificationAlertType, SendMessageComposer } from '../../../../api'; -import { Button, Column, DraggableWindowPosition, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; -import { useModTools, useNotification } from '../../../../hooks'; - -interface ModToolsUserModActionViewProps -{ - user: ISelectedUser; - onCloseClick: () => void; -} - -const MOD_ACTION_DEFINITIONS = [ - new ModActionDefinition(1, 'Alert', ModActionDefinition.ALERT, 1, 0), - new ModActionDefinition(2, 'Mute 1h', ModActionDefinition.MUTE, 2, 0), - new ModActionDefinition(3, 'Ban 18h', ModActionDefinition.BAN, 3, 0), - new ModActionDefinition(4, 'Ban 7 days', ModActionDefinition.BAN, 4, 0), - new ModActionDefinition(5, 'Ban 30 days (step 1)', ModActionDefinition.BAN, 5, 0), - new ModActionDefinition(7, 'Ban 30 days (step 2)', ModActionDefinition.BAN, 7, 0), - new ModActionDefinition(6, 'Ban 100 years', ModActionDefinition.BAN, 6, 0), - new ModActionDefinition(106, 'Ban avatar-only 100 years', ModActionDefinition.BAN, 6, 0), - new ModActionDefinition(101, 'Kick', ModActionDefinition.KICK, 0, 0), - new ModActionDefinition(102, 'Lock trade 1 week', ModActionDefinition.TRADE_LOCK, 0, 168), - new ModActionDefinition(104, 'Lock trade permanent', ModActionDefinition.TRADE_LOCK, 0, 876000), - new ModActionDefinition(105, 'Message', ModActionDefinition.MESSAGE, 0, 0), -]; - -export const ModToolsUserModActionView: FC = props => -{ - const { user = null, onCloseClick = null } = props; - const [ selectedTopic, setSelectedTopic ] = useState(-1); - const [ selectedAction, setSelectedAction ] = useState(-1); - const [ message, setMessage ] = useState(''); - const { cfhCategories = null, settings = null } = useModTools(); - const { simpleAlert = null } = useNotification(); - - const topics = useMemo(() => - { - const values: CallForHelpTopicData[] = []; - - if(cfhCategories && cfhCategories.length) - { - for(const category of cfhCategories) - { - for(const topic of category.topics) values.push(topic); - } - } - - return values; - }, [ cfhCategories ]); - - const sendAlert = (message: string) => simpleAlert(message, NotificationAlertType.DEFAULT, null, null, 'Error'); - - const sendDefaultSanction = () => - { - let errorMessage: string = null; - - const category = topics[selectedTopic]; - - if(selectedTopic === -1) errorMessage = 'You must select a CFH topic'; - - if(errorMessage) return sendAlert(errorMessage); - - const messageOrDefault = (message.trim().length === 0) ? LocalizeText(`help.cfh.topic.${ category.id }`) : message; - - SendMessageComposer(new DefaultSanctionMessageComposer(user.userId, selectedTopic, messageOrDefault)); - - onCloseClick(); - } - - const sendSanction = () => - { - let errorMessage: string = null; - - const category = topics[selectedTopic]; - const sanction = MOD_ACTION_DEFINITIONS[selectedAction]; - - if((selectedTopic === -1) || (selectedAction === -1)) errorMessage = 'You must select a CFH topic and Sanction'; - else if(!settings || !settings.cfhPermission) errorMessage = 'You do not have permission to do this'; - else if(!category) errorMessage = 'You must select a CFH topic'; - else if(!sanction) errorMessage = 'You must select a sanction'; - - if(errorMessage) - { - sendAlert(errorMessage); - - return; - } - - const messageOrDefault = (message.trim().length === 0) ? LocalizeText(`help.cfh.topic.${ category.id }`) : message; - - switch(sanction.actionType) - { - case ModActionDefinition.ALERT: { - if(!settings.alertPermission) - { - sendAlert('You have insufficient permissions'); - - return; - } - - SendMessageComposer(new ModAlertMessageComposer(user.userId, messageOrDefault, category.id)); - break; - } - case ModActionDefinition.MUTE: - SendMessageComposer(new ModMuteMessageComposer(user.userId, messageOrDefault, category.id)); - break; - case ModActionDefinition.BAN: { - if(!settings.banPermission) - { - sendAlert('You have insufficient permissions'); - - return; - } - - SendMessageComposer(new ModBanMessageComposer(user.userId, messageOrDefault, category.id, selectedAction, (sanction.actionId === 106))); - break; - } - case ModActionDefinition.KICK: { - if(!settings.kickPermission) - { - sendAlert('You have insufficient permissions'); - return; - } - - SendMessageComposer(new ModKickMessageComposer(user.userId, messageOrDefault, category.id)); - break; - } - case ModActionDefinition.TRADE_LOCK: { - const numSeconds = (sanction.actionLengthHours * 60); - - SendMessageComposer(new ModTradingLockMessageComposer(user.userId, messageOrDefault, numSeconds, category.id)); - break; - } - case ModActionDefinition.MESSAGE: { - if(message.trim().length === 0) - { - sendAlert('Please write a message to user'); - - return; - } - - SendMessageComposer(new ModMessageMessageComposer(user.userId, message, category.id)); - break; - } - } - - onCloseClick(); - } - - if(!user) return null; - - return ( - - onCloseClick() } /> - - - - - Optional message type, overrides default - - - - - ); -} diff --git a/src/components/mod-tools/views/user/ModToolsUserView.tsx b/src/components/mod-tools/views/user/ModToolsUserView.tsx deleted file mode 100644 index 0ceb8a2..0000000 --- a/src/components/mod-tools/views/user/ModToolsUserView.tsx +++ /dev/null @@ -1,156 +0,0 @@ -import { CreateLinkEvent, GetModeratorUserInfoMessageComposer, ModeratorUserInfoData, ModeratorUserInfoEvent } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useMemo, useState } from 'react'; -import { FriendlyTime, LocalizeText, SendMessageComposer } from '../../../../api'; -import { Button, Column, DraggableWindowPosition, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common'; -import { useMessageEvent } from '../../../../hooks'; -import { ModToolsUserModActionView } from './ModToolsUserModActionView'; -import { ModToolsUserRoomVisitsView } from './ModToolsUserRoomVisitsView'; -import { ModToolsUserSendMessageView } from './ModToolsUserSendMessageView'; - -interface ModToolsUserViewProps -{ - userId: number; - onCloseClick: () => void; -} - -export const ModToolsUserView: FC = props => -{ - const { onCloseClick = null, userId = null } = props; - const [ userInfo, setUserInfo ] = useState(null); - const [ sendMessageVisible, setSendMessageVisible ] = useState(false); - const [ modActionVisible, setModActionVisible ] = useState(false); - const [ roomVisitsVisible, setRoomVisitsVisible ] = useState(false); - - const userProperties = useMemo(() => - { - if(!userInfo) return null; - - return [ - { - localeKey: 'modtools.userinfo.userName', - value: userInfo.userName, - showOnline: true - }, - { - localeKey: 'modtools.userinfo.cfhCount', - value: userInfo.cfhCount.toString() - }, - { - localeKey: 'modtools.userinfo.abusiveCfhCount', - value: userInfo.abusiveCfhCount.toString() - }, - { - localeKey: 'modtools.userinfo.cautionCount', - value: userInfo.cautionCount.toString() - }, - { - localeKey: 'modtools.userinfo.banCount', - value: userInfo.banCount.toString() - }, - { - localeKey: 'modtools.userinfo.lastSanctionTime', - value: userInfo.lastSanctionTime - }, - { - localeKey: 'modtools.userinfo.tradingLockCount', - value: userInfo.tradingLockCount.toString() - }, - { - localeKey: 'modtools.userinfo.tradingExpiryDate', - value: userInfo.tradingExpiryDate - }, - { - localeKey: 'modtools.userinfo.minutesSinceLastLogin', - value: FriendlyTime.format(userInfo.minutesSinceLastLogin * 60, '.ago', 2) - }, - { - localeKey: 'modtools.userinfo.lastPurchaseDate', - value: userInfo.lastPurchaseDate - }, - { - localeKey: 'modtools.userinfo.primaryEmailAddress', - value: userInfo.primaryEmailAddress - }, - { - localeKey: 'modtools.userinfo.identityRelatedBanCount', - value: userInfo.identityRelatedBanCount.toString() - }, - { - localeKey: 'modtools.userinfo.registrationAgeInMinutes', - value: FriendlyTime.format(userInfo.registrationAgeInMinutes * 60, '.ago', 2) - }, - { - localeKey: 'modtools.userinfo.userClassification', - value: userInfo.userClassification - } - ]; - }, [ userInfo ]); - - useMessageEvent(ModeratorUserInfoEvent, event => - { - const parser = event.getParser(); - - if(!parser || parser.data.userId !== userId) return; - - setUserInfo(parser.data); - }); - - useEffect(() => - { - SendMessageComposer(new GetModeratorUserInfoMessageComposer(userId)); - }, [ userId ]); - - if(!userInfo) return null; - - return ( - <> - - onCloseClick() } /> - - - - - - { userProperties.map( (property, index) => - { - - return ( - - - - - ); - }) } - -
{ LocalizeText(property.localeKey) } - { property.value } - { property.showOnline && - } -
-
- - - - - - -
-
-
- { sendMessageVisible && - setSendMessageVisible(false) } /> } - { modActionVisible && - setModActionVisible(false) } /> } - { roomVisitsVisible && - setRoomVisitsVisible(false) } /> } - - ); -} diff --git a/src/components/navigator/NavigatorView.scss b/src/components/navigator/NavigatorView.scss deleted file mode 100644 index ef235bc..0000000 --- a/src/components/navigator/NavigatorView.scss +++ /dev/null @@ -1,65 +0,0 @@ -.nitro-navigator { - width: $navigator-width; - height: $navigator-height; - - .navigator-grid { - - .navigator-item { - - .badge { - width: 35px; - min-width: 35px; - } - } - - &:not(.two-columns) { - - .navigator-item { - - &:nth-child(odd) { - background-color: $grid-active-bg-color; - } - } - } - - &.two-columns { - - .navigator-item { - - &:nth-child(4n-2), - &:nth-child(4n-3) { - background: $grid-active-bg-color; - } - } - } - } -} - -.nitro-navigator-doorbell, -.nitro-navigator-password { - width: 250px; -} - -.nitro-room-info { - width: $room-info-width; -} - -.nitro-room-link { - width: 400px; -} - -.nitro-room-settings { - width: 400px; - - .list-container { - height: 100px; - - .list-item { - background-color: $grid-active-bg-color; - } - } -} - -.room-info { - width: 275px; -} diff --git a/src/components/navigator/NavigatorView.tsx b/src/components/navigator/NavigatorView.tsx deleted file mode 100644 index e772db8..0000000 --- a/src/components/navigator/NavigatorView.tsx +++ /dev/null @@ -1,233 +0,0 @@ -import { AddLinkEventTracker, ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, LegacyExternalInterface, NavigatorInitComposer, NavigatorSearchComposer, RemoveLinkEventTracker, RoomSessionEvent } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useRef, useState } from 'react'; -import { FaPlus } from 'react-icons/fa'; -import { LocalizeText, SendMessageComposer, TryVisitRoom } from '../../api'; -import { Base, Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common'; -import { useNavigator, useNitroEvent } from '../../hooks'; -import { NavigatorDoorStateView } from './views/NavigatorDoorStateView'; -import { NavigatorRoomCreatorView } from './views/NavigatorRoomCreatorView'; -import { NavigatorRoomInfoView } from './views/NavigatorRoomInfoView'; -import { NavigatorRoomLinkView } from './views/NavigatorRoomLinkView'; -import { NavigatorRoomSettingsView } from './views/room-settings/NavigatorRoomSettingsView'; -import { NavigatorSearchResultView } from './views/search/NavigatorSearchResultView'; -import { NavigatorSearchView } from './views/search/NavigatorSearchView'; - -export const NavigatorView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ isReady, setIsReady ] = useState(false); - const [ isCreatorOpen, setCreatorOpen ] = useState(false); - const [ isRoomInfoOpen, setRoomInfoOpen ] = useState(false); - const [ isRoomLinkOpen, setRoomLinkOpen ] = useState(false); - const [ isLoading, setIsLoading ] = useState(false); - const [ needsInit, setNeedsInit ] = useState(true); - const [ needsSearch, setNeedsSearch ] = useState(false); - const { searchResult = null, topLevelContext = null, topLevelContexts = null, navigatorData = null } = useNavigator(); - const pendingSearch = useRef<{ value: string, code: string }>(null); - const elementRef = useRef(); - - useNitroEvent(RoomSessionEvent.CREATED, event => - { - setIsVisible(false); - setCreatorOpen(false); - }); - - const sendSearch = useCallback((searchValue: string, contextCode: string) => - { - setCreatorOpen(false); - - SendMessageComposer(new NavigatorSearchComposer(contextCode, searchValue)); - - setIsLoading(true); - }, []); - - const reloadCurrentSearch = useCallback(() => - { - if(!isReady) - { - setNeedsSearch(true); - - return; - } - - if(pendingSearch.current) - { - sendSearch(pendingSearch.current.value, pendingSearch.current.code); - - pendingSearch.current = null; - - return; - } - - if(searchResult) - { - sendSearch(searchResult.data, searchResult.code); - - return; - } - - if(!topLevelContext) return; - - sendSearch('', topLevelContext.code); - }, [ isReady, searchResult, topLevelContext, sendSearch ]); - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': { - setIsVisible(true); - setNeedsSearch(true); - return; - } - case 'hide': - setIsVisible(false); - return; - case 'toggle': { - if(isVisible) - { - setIsVisible(false); - - return; - } - - setIsVisible(true); - setNeedsSearch(true); - return; - } - case 'toggle-room-info': - setRoomInfoOpen(value => !value); - return; - case 'toggle-room-link': - setRoomLinkOpen(value => !value); - return; - case 'goto': - if(parts.length <= 2) return; - - switch(parts[2]) - { - case 'home': - if(navigatorData.homeRoomId <= 0) return; - - TryVisitRoom(navigatorData.homeRoomId); - break; - default: { - const roomId = parseInt(parts[2]); - - TryVisitRoom(roomId); - } - } - return; - case 'create': - setIsVisible(true); - setCreatorOpen(true); - return; - case 'search': - if(parts.length > 2) - { - const topLevelContextCode = parts[2]; - - let searchValue = ''; - - if(parts.length > 3) searchValue = parts[3]; - - pendingSearch.current = { value: searchValue, code: topLevelContextCode }; - - setIsVisible(true); - setNeedsSearch(true); - } - return; - } - }, - eventUrlPrefix: 'navigator/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, [ isVisible, navigatorData ]); - - useEffect(() => - { - if(!searchResult) return; - - setIsLoading(false); - - if(elementRef && elementRef.current) elementRef.current.scrollTop = 0; - }, [ searchResult ]); - - useEffect(() => - { - if(!isVisible || !isReady || !needsSearch) return; - - reloadCurrentSearch(); - - setNeedsSearch(false); - }, [ isVisible, isReady, needsSearch, reloadCurrentSearch ]); - - useEffect(() => - { - if(isReady || !topLevelContext) return; - - setIsReady(true); - }, [ isReady, topLevelContext ]); - - useEffect(() => - { - if(!isVisible || !needsInit) return; - - SendMessageComposer(new NavigatorInitComposer()); - - setNeedsInit(false); - }, [ isVisible, needsInit ]); - - useEffect(() => - { - LegacyExternalInterface.addCallback(HabboWebTools.OPENROOM, (k: string, _arg_2: boolean = false, _arg_3: string = null) => SendMessageComposer(new ConvertGlobalRoomIdMessageComposer(k))); - }, []); - - return ( - <> - { isVisible && - - setIsVisible(false) } /> - - { topLevelContexts && (topLevelContexts.length > 0) && topLevelContexts.map((context, index) => - { - return ( - sendSearch('', context.code) }> - { LocalizeText(('navigator.toplevelview.' + context.code)) } - - ); - }) } - setCreatorOpen(true) }> - - - - - { isLoading && - } - { !isCreatorOpen && - <> - - - { (searchResult && searchResult.results.map((result, index) => )) } - - } - { isCreatorOpen && } - - } - - { isRoomInfoOpen && setRoomInfoOpen(false) } /> } - { isRoomLinkOpen && setRoomLinkOpen(false) } /> } - - - ); -} diff --git a/src/components/navigator/views/NavigatorDoorStateView.tsx b/src/components/navigator/views/NavigatorDoorStateView.tsx deleted file mode 100644 index 4c8a3e2..0000000 --- a/src/components/navigator/views/NavigatorDoorStateView.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { CreateRoomSession, DoorStateType, GoToDesktop, LocalizeText } from '../../../api'; -import { Button, Column, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common'; -import { useNavigator } from '../../../hooks'; - -const VISIBLE_STATES = [ DoorStateType.START_DOORBELL, DoorStateType.STATE_WAITING, DoorStateType.STATE_NO_ANSWER, DoorStateType.START_PASSWORD, DoorStateType.STATE_WRONG_PASSWORD ]; -const DOORBELL_STATES = [ DoorStateType.START_DOORBELL, DoorStateType.STATE_WAITING, DoorStateType.STATE_NO_ANSWER ]; -const PASSWORD_STATES = [ DoorStateType.START_PASSWORD, DoorStateType.STATE_WRONG_PASSWORD ]; - -export const NavigatorDoorStateView: FC<{}> = props => -{ - const [ password, setPassword ] = useState(''); - const { doorData = null, setDoorData = null } = useNavigator(); - - const onClose = () => - { - if(doorData && (doorData.state === DoorStateType.STATE_WAITING)) GoToDesktop(); - - setDoorData(null); - } - - const ring = () => - { - if(!doorData || !doorData.roomInfo) return; - - CreateRoomSession(doorData.roomInfo.roomId); - - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.state = DoorStateType.STATE_PENDING_SERVER; - - return newValue; - }); - } - - const tryEntering = () => - { - if(!doorData || !doorData.roomInfo) return; - - CreateRoomSession(doorData.roomInfo.roomId, password); - - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.state = DoorStateType.STATE_PENDING_SERVER; - - return newValue; - }); - } - - useEffect(() => - { - if(!doorData || (doorData.state !== DoorStateType.STATE_NO_ANSWER)) return; - - GoToDesktop(); - }, [ doorData ]); - - if(!doorData || (doorData.state === DoorStateType.NONE) || (VISIBLE_STATES.indexOf(doorData.state) === -1)) return null; - - const isDoorbell = (DOORBELL_STATES.indexOf(doorData.state) >= 0); - - return ( - - - - - { doorData && doorData.roomInfo && doorData.roomInfo.roomName } - { (doorData.state === DoorStateType.START_DOORBELL) && - { LocalizeText('navigator.doorbell.info') } } - { (doorData.state === DoorStateType.STATE_WAITING) && - { LocalizeText('navigator.doorbell.waiting') } } - { (doorData.state === DoorStateType.STATE_NO_ANSWER) && - { LocalizeText('navigator.doorbell.no.answer') } } - { (doorData.state === DoorStateType.START_PASSWORD) && - { LocalizeText('navigator.password.info') } } - { (doorData.state === DoorStateType.STATE_WRONG_PASSWORD) && - { LocalizeText('navigator.password.retryinfo') } } - - { isDoorbell && - - { (doorData.state === DoorStateType.START_DOORBELL) && - } - - } - { !isDoorbell && - <> - - { LocalizeText('navigator.password.enter') } - setPassword(event.target.value) } /> - - - - - - } - - - ); -} diff --git a/src/components/navigator/views/NavigatorRoomCreatorView.tsx b/src/components/navigator/views/NavigatorRoomCreatorView.tsx deleted file mode 100644 index 95a5bd6..0000000 --- a/src/components/navigator/views/NavigatorRoomCreatorView.tsx +++ /dev/null @@ -1,122 +0,0 @@ -/* eslint-disable no-template-curly-in-string */ -import { CreateFlatMessageComposer, HabboClubLevelEnum } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { GetClubMemberLevel, GetConfigurationValue, IRoomModel, LocalizeText, SendMessageComposer } from '../../../api'; -import { Button, Column, Flex, Grid, LayoutCurrencyIcon, LayoutGridItem, Text } from '../../../common'; -import { useNavigator } from '../../../hooks'; - -export const NavigatorRoomCreatorView: FC<{}> = props => -{ - const [ maxVisitorsList, setMaxVisitorsList ] = useState(null); - const [ name, setName ] = useState(null); - const [ description, setDescription ] = useState(null); - const [ category, setCategory ] = useState(null); - const [ visitorsCount, setVisitorsCount ] = useState(null); - const [ tradesSetting, setTradesSetting ] = useState(0); - const [ roomModels, setRoomModels ] = useState([]); - const [ selectedModelName, setSelectedModelName ] = useState(''); - const { categories = null } = useNavigator(); - - const hcDisabled = GetConfigurationValue('hc.disabled', false); - - const getRoomModelImage = (name: string) => GetConfigurationValue('images.url') + `/navigator/models/model_${ name }.png`; - - const selectModel = (model: IRoomModel, index: number) => - { - if(!model || (model.clubLevel > GetClubMemberLevel())) return; - - setSelectedModelName(roomModels[index].name); - }; - - const createRoom = () => - { - SendMessageComposer(new CreateFlatMessageComposer(name, description, 'model_' + selectedModelName, Number(category), Number(visitorsCount), tradesSetting)); - }; - - useEffect(() => - { - if(!maxVisitorsList) - { - const list = []; - - for(let i = 10; i <= 100; i = i + 10) list.push(i); - - setMaxVisitorsList(list); - setVisitorsCount(list[0]); - } - }, [ maxVisitorsList ]); - - useEffect(() => - { - if(categories && categories.length) setCategory(categories[0].id); - }, [ categories ]); - - useEffect(() => - { - const models = GetConfigurationValue('navigator.room.models'); - - if(models && models.length) - { - setRoomModels(models); - setSelectedModelName(models[0].name); - } - }, []); - - return ( - - - - - { LocalizeText('navigator.createroom.roomnameinfo') } - setName(event.target.value) } placeholder={ LocalizeText('navigator.createroom.roomnameinfo') } /> - - - { LocalizeText('navigator.createroom.roomdescinfo') } - -
-
- - ); -} diff --git a/src/components/room/widgets/furniture/FurnitureStackHeightView.tsx b/src/components/room/widgets/furniture/FurnitureStackHeightView.tsx deleted file mode 100644 index d4d1039..0000000 --- a/src/components/room/widgets/furniture/FurnitureStackHeightView.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { FurnitureStackHeightComposer } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { LocalizeText, SendMessageComposer } from '../../../../api'; -import { Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; -import { useFurnitureStackHeightWidget } from '../../../../hooks'; - -export const FurnitureStackHeightView: FC<{}> = props => -{ - const { objectId = -1, height = 0, maxHeight = 40, onClose = null, updateHeight = null } = useFurnitureStackHeightWidget(); - const [ tempHeight, setTempHeight ] = useState(''); - - const updateTempHeight = (value: string) => - { - setTempHeight(value); - - const newValue = parseFloat(value); - - if(isNaN(newValue) || (newValue === height)) return; - - updateHeight(newValue); - } - - useEffect(() => - { - setTempHeight(height.toString()); - }, [ height ]); - - if(objectId === -1) return null; - - return ( - - - - { LocalizeText('widget.custom.stack.height.text') } - - updateHeight(event) } - renderThumb={ (props, state) =>
{ state.valueNow }
} /> - updateTempHeight(event.target.value) } /> -
- - - - -
-
- ); -} diff --git a/src/components/room/widgets/furniture/FurnitureStickieView.tsx b/src/components/room/widgets/furniture/FurnitureStickieView.tsx deleted file mode 100644 index 2f0e0fe..0000000 --- a/src/components/room/widgets/furniture/FurnitureStickieView.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { ColorUtils } from '../../../../api'; -import { DraggableWindow, DraggableWindowPosition } from '../../../../common'; -import { useFurnitureStickieWidget } from '../../../../hooks'; - -const STICKIE_COLORS = [ '9CCEFF','FF9CFF', '9CFF9C','FFFF33' ]; -const STICKIE_COLOR_NAMES = [ 'blue', 'pink', 'green', 'yellow' ]; -const STICKIE_TYPES = [ 'post_it','post_it_shakesp', 'post_it_dreams','post_it_xmas', 'post_it_vd', 'post_it_juninas' ]; -const STICKIE_TYPE_NAMES = [ 'post_it', 'shakesp', 'dreams', 'christmas', 'heart', 'juninas' ]; - -const getStickieColorName = (color: string) => -{ - let index = STICKIE_COLORS.indexOf(color); - - if(index === -1) index = 0; - - return STICKIE_COLOR_NAMES[index]; -} - -const getStickieTypeName = (type: string) => -{ - let index = STICKIE_TYPES.indexOf(type); - - if(index === -1) index = 0; - - return STICKIE_TYPE_NAMES[index]; -} - -export const FurnitureStickieView: FC<{}> = props => -{ - const { objectId = -1, color = '0', text = '', type = '', canModify = false, updateColor = null, updateText = null, trash = null, onClose = null } = useFurnitureStickieWidget(); - const [ isEditing, setIsEditing ] = useState(false); - - useEffect(() => - { - setIsEditing(false); - }, [ objectId, color, text, type ]); - - if(objectId === -1) return null; - - return ( - -
-
-
- { canModify && - <> -
- { type == 'post_it' && - <> - { STICKIE_COLORS.map(color => - { - return
updateColor(color) } style={ { backgroundColor: ColorUtils.makeColorHex(color) } } /> - }) } - } - } -
-
-
-
- { (!isEditing || !canModify) ?
(canModify && setIsEditing(true)) }>{ text }
: } -
-
- - ); -} diff --git a/src/components/room/widgets/furniture/FurnitureTrophyView.tsx b/src/components/room/widgets/furniture/FurnitureTrophyView.tsx deleted file mode 100644 index 7977097..0000000 --- a/src/components/room/widgets/furniture/FurnitureTrophyView.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { FC } from 'react'; -import { LayoutTrophyView } from '../../../../common'; -import { useFurnitureTrophyWidget } from '../../../../hooks'; - -export const FurnitureTrophyView: FC<{}> = props => -{ - const { objectId = -1, color = '1', senderName = '', date = '', message = '', onClose = null } = useFurnitureTrophyWidget(); - - if(objectId === -1) return null; - - return ; -} diff --git a/src/components/room/widgets/furniture/FurnitureWidgets.scss b/src/components/room/widgets/furniture/FurnitureWidgets.scss deleted file mode 100644 index 65b6559..0000000 --- a/src/components/room/widgets/furniture/FurnitureWidgets.scss +++ /dev/null @@ -1,526 +0,0 @@ -.nitro-room-widgets { - pointer-events: none; -} - -.nitro-widget-custom-stack-height { - width: $nitro-widget-custom-stack-height-width; - height: $nitro-widget-custom-stack-height-height; -} - -.nitro-room-widget-toner { - width: 190px; -} - -.nitro-room-widget-dimmer { - width: 275px; - - .dimmer-banner { - width: 56px; - height: 79px; - background: url('@/assets/images/room-widgets/dimmer-widget/dimmer_banner.png') - center no-repeat; - } - - .color-swatch { - height: 30px; - border: 2px solid $white; - box-shadow: inset 3px 3px rgba(0, 0, 0, 0.2); - - &.active { - box-shadow: none; - } - } -} - -.nitro-widget-crafting { - width: $nitro-widget-crafting-width; - height: $nitro-widget-crafting-height; -} - -.nitro-widget-exchange-credit { - width: $nitro-widget-exchange-credit-width; - height: $nitro-widget-exchange-credit-height; - - .exchange-image { - background-image: url('@/assets/images/room-widgets/exchange-credit/exchange-credit-image.png'); - width: 103px; - height: 103px; - } -} - -.nitro-external-image-widget { - .picture-preview { - width: 320px; - height: 320px; - } - - .picture-preview-buttons { - display: flex; - align-items: center; - justify-content: space-between; - color: black; - } - - .picture-preview-buttons-previous, - .picture-preview-buttons-next { - color: #222; - background-color: white; - padding: 10px; - border-radius: 50%; - } -} - -.nitro-gift-opening { - width: 340px; - resize: none; -} - -.nitro-mannequin { - width: 300px; - - .mannequin-preview { - display: flex; - justify-content: center; - align-items: center; - width: 83px; - height: 130px; - background-image: url('@/assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png'); - overflow: hidden; - - .avatar-image { - background-position: unset; - top: -8px; - } - } -} - -.nitro-stickie { - position: relative; - width: 185px; - height: 178px; - top: 25px; - left: 25px; - padding: 1px; - pointer-events: all; - - .stickie-header { - width: 183px; - height: 18px; - padding: 0 7px; - - .header-trash, - .header-close { - cursor: pointer; - } - - .stickie-color { - width: 10px; - height: 10px; - cursor: pointer; - } - } - - .stickie-context { - width: 183px; - height: 145px; - padding: 2px 7px; - font-size: 12px; - color: $black; - - .context-text { - width: 100%; - height: 100%; - padding: 0; - overflow-wrap: break-word; - white-space: break-spaces; - overflow-y: auto; - } - - textarea { - background: transparent; - border: 0; - outline: none; - box-shadow: none; - resize: none; - font-style: italic; - - &:active { - border: 0; - outline: none; - box-shadow: none; - } - } - } -} - -.nitro-stickie-image { - background-image: url('@/assets/images/room-widgets/stickie-widget/stickie-spritesheet.png'); - - &.stickie-blue, - &.stickie-yellow, - &.stickie-green, - &.stickie-pink { - width: 185px; - height: 178px; - } - - &.stickie-blue { - background-position: -2px -2px; - } - - &.stickie-yellow { - background-image: url('@/assets/images/room-widgets/stickie-widget/stickie-yellow.png'); - //background-position: -191px -184px; - } - - &.stickie-green { - background-position: -191px -2px; - } - - &.stickie-pink { - background-position: -2px -184px; - } - - &.stickie-christmas { - background-image: url('@/assets/images/room-widgets/stickie-widget/stickie-christmas.png'); - } - - &.stickie-shakesp { - background-image: url('@/assets/images/room-widgets/stickie-widget/stickie-shakesp.png'); - } - - &.stickie-dreams { - background-image: url('@/assets/images/room-widgets/stickie-widget/stickie-dreams.png'); - } - - &.stickie-heart { - background-image: url('@/assets/images/room-widgets/stickie-widget/stickie-heart.png'); - } - - &.stickie-juninas { - background-image: url('@/assets/images/room-widgets/stickie-widget/stickie-juninas.png'); - } - - &.stickie-close { - width: 10px; - height: 10px; - background-position: -2px -366px; - } - - &.stickie-trash { - width: 9px; - height: 10px; - background-position: -16px -366px; - } -} - -.nitro-engraving-lock { - width: 300px; - - .engraving-lock-stage-1 { - width: 31px; - height: 39px; - background-position: -380px -43px; - background-image: url('@/assets/images/room-widgets/engraving-lock-widget/engraving-lock-spritesheet.png'); - } - - .engraving-lock-stage-2 { - width: 36px; - height: 43px; - background-position: -375px 0px; - background-image: url('@/assets/images/room-widgets/engraving-lock-widget/engraving-lock-spritesheet.png'); - } -} - -.nitro-engraving-lock-view { - width: 375px; - height: 210px; - background-position: 0px 0px; - background-image: url('@/assets/images/room-widgets/engraving-lock-widget/engraving-lock-spritesheet.png'); - - color: #622e54; - font-weight: bold; - font-size: 16px; - text-shadow: 0px 1px white; - - &.engraving-lock-3 { - background-position: 0px -210px; - color: #614110; - } - - &.engraving-lock-4 { - background-position: 0px -420px; - color: #f1dcc8; - text-shadow: 0px 2px rgba(0, 0, 0, 0.4); - - .engraving-lock-avatar { - margin-bottom: 10px; - } - } - - .engraving-lock-close { - position: absolute; - cursor: pointer; - width: 15px; - height: 15px; - top: 34px; - right: 27px; - } - - .engraving-lock-avatar { - width: 70px; - height: 120px; - - div { - position: absolute; - margin-top: -5px; - } - - &:nth-child(1) { - div { - margin-left: -10px; - } - } - - &:nth-child(2) { - div { - margin-left: -15px; - } - } - } -} - -.nitro-widget-high-score { - width: 250px; - max-width: 250px; - height: 200px; -} - -.youtube-tv-widget { - width: 600px; - height: 380px; - - .youtube-video-container { - .empty-video { - background-color: black; - color: white; - width: 100%; - height: 100%; - text-align: center; - } - - .youtubeContainer { - position: relative; - width: 100%; - height: 100%; - overflow: hidden; - margin-bottom: 50px; - } - - .youtubeContainer iframe { - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - } - } - - .playlist-container { - overflow-y: auto; - margin-right: -10px; - color: black; - height: 100%; - - .playlist-controls { - width: 100%; - .icon { - margin-right: 10px; - margin-bottom: 10px; - } - } - - .playlist-grid { - height: 100%; - width: 100%; - } - } -} - -.nitro-playlist-editor-widget { - width: 625px; - height: 440px; - - img.my-music { - position: absolute; - top: -4px; - left: -4px; - z-index: 0; - } - - img.playlist-img { - position: absolute; - top: -4px; - left: 0; - z-index: 0; - } - - img.get-more, - img.add-songs { - position: absolute; - bottom: 0; - left: 0; - z-index: 0; - } - - .playlist-bottom { - z-index: 3; - } - - .move-disk { - width: 22px; - height: 18px; - background-image: url('@/assets/images/room-widgets/playlist-editor/move.png'); - } - - .disk-2, - .disk-image { - background-blend-mode: multiply; - } - - .disk-2 { - width: 38px; - height: 38px; - background-image: url('@/assets/images/room-widgets/playlist-editor/disk_2.png'); - background-position: center; - background-repeat: no-repeat; - - &.playing-song { - background-image: url('@/assets/images/room-widgets/playlist-editor/playing.png'); - } - - &.selected-song { - background-image: url('@/assets/images/room-widgets/playlist-editor/move.png'); - transform: scaleX(-1); - } - - &:not(.playing-song):not(.selected-song) { - -webkit-mask-image: url('@/assets/images/room-widgets/playlist-editor/disk_2.png'); - mask-image: url('@/assets/images/room-widgets/playlist-editor/disk_2.png'); - } - } - - .pause-song { - width: 18px; - height: 20px; - background-image: url('@/assets/images/room-widgets/playlist-editor/pause.png'); - } - - .pause-btn { - width: 16px; - height: 16px; - - background-image: url('@/assets/images/room-widgets/playlist-editor/pause-btn.png'); - } - - .music-note { - width: 38px; - height: 38px; - background-image: url('@/assets/images/room-widgets/playlist-editor/playing.png'); - } - - .preview-song { - width: 16px; - height: 16px; - background-image: url('@/assets/images/room-widgets/playlist-editor/preview.png'); - } - - .layout-grid-item { - min-height: 95px; - min-width: 95px; - position: relative; - - .disk-image { - background: url('@/assets/images/room-widgets/playlist-editor/disk_image.png'); - -webkit-mask-image: url('@/assets/images/room-widgets/playlist-editor/disk_image.png'); - mask-image: url('@/assets/images/room-widgets/playlist-editor/disk_image.png'); - height: 76px; - width: 76px; - } - } -} - -.nitro-mysterybox-dialog { - width: 375px; - height: 210px; - - .prize-container { - height: 80px; - width: 81px; - background-image: url('@/assets/images/prize/prize_background.png'); - background-repeat: no-repeat; - background-position: center; - } -} - -.nitro-mysterytrophy-dialog -{ - .mysterytrophy-dialog-top - { - width: 400px; - height: 120px; - border-radius: 2px; - background-color: #0E3F52; - - .mysterytrophy-image - { - width: 80px; - height: 84px; - position: relative; - background-image: url('@/assets/images/mysterytrophy/frank_mystery_trophy.png'); - background-repeat: no-repeat; - } - - .mysterytrophy-text-big - { - font-size: 16px; - } - } - - .mysterytrophy-dialog-bottom - { - display: flex; - justify-content: center; - width: 400px; - height: 120px; - border-radius: 2px; - background-color: #E9E9E1; - - .input-mysterytrophy-dialog - { - width: 380px; - border: 1px solid black; - - .input-mysterytrophy - { - width: 350px; - border: 0; - outline: 0; - } - - .mysterytrophy-pencil-image - { - width: 16px; - height: 16px; - position: relative; - background-image: url('@/assets/images/infostand/pencil-icon.png'); - background-repeat: no-repeat; - } - } - - .text-decoration - { - text-decoration: underline; - } - } -} diff --git a/src/components/room/widgets/furniture/FurnitureWidgetsView.tsx b/src/components/room/widgets/furniture/FurnitureWidgetsView.tsx deleted file mode 100644 index d0e4066..0000000 --- a/src/components/room/widgets/furniture/FurnitureWidgetsView.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { FC } from 'react'; -import { Base } from '../../../../common'; -import { FurnitureContextMenuView } from './context-menu/FurnitureContextMenuView'; -import { FurnitureBackgroundColorView } from './FurnitureBackgroundColorView'; -import { FurnitureBadgeDisplayView } from './FurnitureBadgeDisplayView'; -import { FurnitureCraftingView } from './FurnitureCraftingView'; -import { FurnitureDimmerView } from './FurnitureDimmerView'; -import { FurnitureExchangeCreditView } from './FurnitureExchangeCreditView'; -import { FurnitureExternalImageView } from './FurnitureExternalImageView'; -import { FurnitureFriendFurniView } from './FurnitureFriendFurniView'; -import { FurnitureGiftOpeningView } from './FurnitureGiftOpeningView'; -import { FurnitureHighScoreView } from './FurnitureHighScoreView'; -import { FurnitureInternalLinkView } from './FurnitureInternalLinkView'; -import { FurnitureMannequinView } from './FurnitureMannequinView'; -import { FurnitureRoomLinkView } from './FurnitureRoomLinkView'; -import { FurnitureSpamWallPostItView } from './FurnitureSpamWallPostItView'; -import { FurnitureStackHeightView } from './FurnitureStackHeightView'; -import { FurnitureStickieView } from './FurnitureStickieView'; -import { FurnitureTrophyView } from './FurnitureTrophyView'; -import { FurnitureYoutubeDisplayView } from './FurnitureYoutubeDisplayView'; -import { FurniturePlaylistEditorWidgetView } from './playlist-editor/FurniturePlaylistEditorWidgetView'; - -export const FurnitureWidgetsView: FC<{}> = props => -{ - return ( - - - - - - - - - - - - - - - - - - - - - - ); -} diff --git a/src/components/room/widgets/furniture/FurnitureYoutubeDisplayView.tsx b/src/components/room/widgets/furniture/FurnitureYoutubeDisplayView.tsx deleted file mode 100644 index fba0f67..0000000 --- a/src/components/room/widgets/furniture/FurnitureYoutubeDisplayView.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import YouTube, { Options } from 'react-youtube'; -import { YouTubePlayer } from 'youtube-player/dist/types'; -import { LocalizeText, YoutubeVideoPlaybackStateEnum } from '../../../../api'; -import { AutoGrid, AutoGridProps, LayoutGridItem, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common'; -import { useFurnitureYoutubeWidget } from '../../../../hooks'; - -interface FurnitureYoutubeDisplayViewProps extends AutoGridProps -{ - -} - -export const FurnitureYoutubeDisplayView: FC<{}> = FurnitureYoutubeDisplayViewProps => -{ - const [ player, setPlayer ] = useState(null); - const { objectId = -1, videoId = null, videoStart = 0, videoEnd = 0, currentVideoState = null, selectedVideo = null, playlists = [], onClose = null, previous = null, next = null, pause = null, play = null, selectVideo = null } = useFurnitureYoutubeWidget(); - - const onStateChange = (event: { target: YouTubePlayer; data: number }) => - { - setPlayer(event.target); - - if(objectId === -1) return; - - switch(event.target.getPlayerState()) - { - case -1: - case 1: - if(currentVideoState === 2) - { - //event.target.pauseVideo(); - } - - if(currentVideoState !== 1) play(); - return; - case 2: - if(currentVideoState !== 2) pause(); - } - } - - useEffect(() => - { - if((currentVideoState === null) || !player) return; - - if((currentVideoState === YoutubeVideoPlaybackStateEnum.PLAYING) && (player.getPlayerState() !== YoutubeVideoPlaybackStateEnum.PLAYING)) - { - player.playVideo(); - - return; - } - - if((currentVideoState === YoutubeVideoPlaybackStateEnum.PAUSED) && (player.getPlayerState() !== YoutubeVideoPlaybackStateEnum.PAUSED)) - { - player.pauseVideo(); - - return; - } - }, [ currentVideoState, player ]); - - if(objectId === -1) return null; - - const youtubeOptions: Options = { - height: '375', - width: '500', - playerVars: { - autoplay: 1, - disablekb: 1, - controls: 0, - origin: window.origin, - modestbranding: 1, - start: videoStart, - end: videoEnd - } - } - - return ( - - - -
-
- { (videoId && videoId.length > 0) && - setPlayer(event.target) } onStateChange={ onStateChange } containerClassName={ 'youtubeContainer' } /> - } - { (!videoId || videoId.length === 0) && -
{ LocalizeText('widget.furni.video_viewer.no_videos') }
- } -
-
- - - - -
{ LocalizeText('widget.furni.video_viewer.playlists') }
- - { playlists && playlists.map((entry, index) => - { - return ( - selectVideo(entry.video) } itemActive={ (entry.video === selectedVideo) }> - { entry.title } - - ) - }) } - -
-
-
-
- ) -} diff --git a/src/components/room/widgets/furniture/context-menu/EffectBoxConfirmView.tsx b/src/components/room/widgets/furniture/context-menu/EffectBoxConfirmView.tsx deleted file mode 100644 index f7e35b9..0000000 --- a/src/components/room/widgets/furniture/context-menu/EffectBoxConfirmView.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common'; -import { useRoom } from '../../../../../hooks'; - -interface EffectBoxConfirmViewProps -{ - objectId: number; - onClose: () => void; -} - -export const EffectBoxConfirmView: FC = props => -{ - const { objectId = -1, onClose = null } = props; - const { roomSession = null } = useRoom(); - - const useProduct = () => - { - roomSession.useMultistateItem(objectId); - - onClose(); - } - - return ( - - - - - - { LocalizeText('effectbox.header.description') } - - - - - - - - - ); -} diff --git a/src/components/room/widgets/furniture/context-menu/FurnitureContextMenuView.tsx b/src/components/room/widgets/furniture/context-menu/FurnitureContextMenuView.tsx deleted file mode 100644 index d58d369..0000000 --- a/src/components/room/widgets/furniture/context-menu/FurnitureContextMenuView.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import { ContextMenuEnum, CustomUserNotificationMessageEvent, GetSessionDataManager, RoomObjectCategory } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { GetGroupInformation, LocalizeText } from '../../../../../api'; -import { EFFECTBOX_OPEN, GROUP_FURNITURE, MONSTERPLANT_SEED_CONFIRMATION, MYSTERYTROPHY_OPEN_DIALOG, PURCHASABLE_CLOTHING_CONFIRMATION, useFurnitureContextMenuWidget, useMessageEvent, useNotification } from '../../../../../hooks'; -import { ContextMenuHeaderView } from '../../context-menu/ContextMenuHeaderView'; -import { ContextMenuListItemView } from '../../context-menu/ContextMenuListItemView'; -import { ContextMenuView } from '../../context-menu/ContextMenuView'; -import { FurnitureMysteryBoxOpenDialogView } from '../FurnitureMysteryBoxOpenDialogView'; -import { FurnitureMysteryTrophyOpenDialogView } from '../FurnitureMysteryTrophyOpenDialogView'; -import { EffectBoxConfirmView } from './EffectBoxConfirmView'; -import { MonsterPlantSeedConfirmView } from './MonsterPlantSeedConfirmView'; -import { PurchasableClothingConfirmView } from './PurchasableClothingConfirmView'; - -export const FurnitureContextMenuView: FC<{}> = props => -{ - const { closeConfirm = null, processAction = null, onClose = null, objectId = -1, mode = null, confirmMode = null, confirmingObjectId = -1, groupData = null, isGroupMember = false, objectOwnerId = -1 } = useFurnitureContextMenuWidget(); - const { simpleAlert = null } = useNotification(); - - useMessageEvent(CustomUserNotificationMessageEvent, event => - { - const parser = event.getParser(); - - if(!parser) return; - - // HOPPER_NO_COSTUME = 1; HOPPER_NO_HC = 2; GATE_NO_HC = 3; STARS_NOT_CANDIDATE = 4 (not coded in Emulator); STARS_NOT_ENOUGH_USERS = 5 (not coded in Emulator); - - switch(parser.count) - { - case 1: - simpleAlert(LocalizeText('costumehopper.costumerequired.bodytext'), null, 'catalog/open/temporary_effects' , LocalizeText('costumehopper.costumerequired.buy'), LocalizeText('costumehopper.costumerequired.header'), null); - break; - case 2: - simpleAlert(LocalizeText('viphopper.viprequired.bodytext'), null, 'catalog/open/habbo_club' , LocalizeText('viprequired.buy.vip'), LocalizeText('viprequired.header'), null); - break; - case 3: - simpleAlert(LocalizeText('gate.viprequired.bodytext'), null, 'catalog/open/habbo_club' , LocalizeText('viprequired.buy.vip'), LocalizeText('gate.viprequired.title'), null); - break; - } - }); - - const isOwner = GetSessionDataManager().userId === objectOwnerId; - - return ( - <> - { (confirmMode === MONSTERPLANT_SEED_CONFIRMATION) && - } - { (confirmMode === PURCHASABLE_CLOTHING_CONFIRMATION) && - } - { (confirmMode === EFFECTBOX_OPEN) && - } - { (confirmMode === MYSTERYTROPHY_OPEN_DIALOG) && - } - - { (objectId >= 0) && mode && - - { (mode === ContextMenuEnum.FRIEND_FURNITURE) && - <> - - { LocalizeText('friendfurni.context.title') } - - processAction('use_friend_furni') }> - { LocalizeText('friendfurni.context.use') } - - } - { (mode === ContextMenuEnum.MONSTERPLANT_SEED) && - <> - - { LocalizeText('furni.mnstr_seed.name') } - - processAction('use_monsterplant_seed') }> - { LocalizeText('widget.monsterplant_seed.button.use') } - - } - { (mode === ContextMenuEnum.RANDOM_TELEPORT) && - <> - - { LocalizeText('furni.random_teleport.name') } - - processAction('use_random_teleport') }> - { LocalizeText('widget.random_teleport.button.use') } - - } - { (mode === ContextMenuEnum.PURCHASABLE_CLOTHING) && - <> - - { LocalizeText('furni.generic_usable.name') } - - processAction('use_purchaseable_clothing') }> - { LocalizeText('widget.generic_usable.button.use') } - - } - { (mode === ContextMenuEnum.MYSTERY_BOX) && - <> - - { LocalizeText('mysterybox.context.title') } - - processAction('use_mystery_box') }> - { LocalizeText('mysterybox.context.' + ((isOwner) ? 'owner' : 'other') + '.use') } - - } - { (mode === ContextMenuEnum.MYSTERY_TROPHY) && - <> - - { LocalizeText('mysterytrophy.header.title') } - - processAction('use_mystery_trophy') }> - { LocalizeText('friendfurni.context.use') } - - } - { (mode === GROUP_FURNITURE) && groupData && - <> - GetGroupInformation(groupData.guildId) }> - { groupData.guildName } - - { !isGroupMember && - processAction('join_group') }> - { LocalizeText('widget.furniture.button.join.group') } - } - processAction('go_to_group_homeroom') }> - { LocalizeText('widget.furniture.button.go.to.group.home.room') } - - { groupData.guildHasReadableForum && - processAction('open_forum') }> - { LocalizeText('widget.furniture.button.open_group_forum') } - } - } - } - - ) -} diff --git a/src/components/room/widgets/furniture/context-menu/MonsterPlantSeedConfirmView.tsx b/src/components/room/widgets/furniture/context-menu/MonsterPlantSeedConfirmView.tsx deleted file mode 100644 index b7163cc..0000000 --- a/src/components/room/widgets/furniture/context-menu/MonsterPlantSeedConfirmView.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { IFurnitureData, RoomObjectCategory } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { FurniCategory, GetFurnitureDataForRoomObject, LocalizeText } from '../../../../../api'; -import { Base, Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common'; -import { useRoom } from '../../../../../hooks'; - -interface MonsterPlantSeedConfirmViewProps -{ - objectId: number; - onClose: () => void; -} - -const MODE_DEFAULT: number = -1; -const MODE_MONSTERPLANT_SEED: number = 0; - -export const MonsterPlantSeedConfirmView: FC = props => -{ - const { objectId = -1, onClose = null } = props; - const [ furniData, setFurniData ] = useState(null); - const [ mode, setMode ] = useState(MODE_DEFAULT); - const { roomSession = null } = useRoom(); - - const useProduct = () => - { - roomSession.useMultistateItem(objectId); - - onClose(); - } - - useEffect(() => - { - if(!roomSession || (objectId === -1)) return; - - const furniData = GetFurnitureDataForRoomObject(roomSession.roomId, objectId, RoomObjectCategory.FLOOR); - - if(!furniData) return; - - setFurniData(furniData); - - let mode = MODE_DEFAULT; - - switch(furniData.specialType) - { - case FurniCategory.MONSTERPLANT_SEED: - mode = MODE_MONSTERPLANT_SEED; - break; - } - - if(mode === MODE_DEFAULT) - { - onClose(); - - return; - } - - setMode(mode); - }, [ roomSession, objectId, onClose ]); - - if(mode === MODE_DEFAULT) return null; - - return ( - - - - - - - - - - - - { LocalizeText('useproduct.widget.text.plant_seed', [ 'productName' ], [ furniData.name ] ) } - { LocalizeText('useproduct.widget.info.plant_seed') } - - - - - - - - - - ); -} diff --git a/src/components/room/widgets/furniture/context-menu/PurchasableClothingConfirmView.tsx b/src/components/room/widgets/furniture/context-menu/PurchasableClothingConfirmView.tsx deleted file mode 100644 index 5ba9905..0000000 --- a/src/components/room/widgets/furniture/context-menu/PurchasableClothingConfirmView.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { GetAvatarRenderManager, GetSessionDataManager, RedeemItemClothingComposer, RoomObjectCategory, UserFigureComposer } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { FigureData, FurniCategory, GetFurnitureDataForRoomObject, LocalizeText, SendMessageComposer } from '../../../../../api'; -import { Base, Button, Column, Flex, LayoutAvatarImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common'; -import { useRoom } from '../../../../../hooks'; - -interface PurchasableClothingConfirmViewProps -{ - objectId: number; - onClose: () => void; -} - -const MODE_DEFAULT: number = -1; -const MODE_PURCHASABLE_CLOTHING: number = 0; - -export const PurchasableClothingConfirmView: FC = props => -{ - const { objectId = -1, onClose = null } = props; - const [ mode, setMode ] = useState(MODE_DEFAULT); - const [ gender, setGender ] = useState(FigureData.MALE); - const [ newFigure, setNewFigure ] = useState(null); - const { roomSession = null } = useRoom(); - - const useProduct = () => - { - SendMessageComposer(new RedeemItemClothingComposer(objectId)); - SendMessageComposer(new UserFigureComposer(gender, newFigure)); - - onClose(); - } - - useEffect(() => - { - let mode = MODE_DEFAULT; - - const figure = GetSessionDataManager().figure; - const gender = GetSessionDataManager().gender; - const validSets: number[] = []; - - if(roomSession && (objectId >= 0)) - { - const furniData = GetFurnitureDataForRoomObject(roomSession.roomId, objectId, RoomObjectCategory.FLOOR); - - if(furniData) - { - switch(furniData.specialType) - { - case FurniCategory.FIGURE_PURCHASABLE_SET: - mode = MODE_PURCHASABLE_CLOTHING; - - const setIds = furniData.customParams.split(',').map(part => parseInt(part)); - - for(const setId of setIds) - { - if(GetAvatarRenderManager().isValidFigureSetForGender(setId, gender)) validSets.push(setId); - } - - break; - } - } - } - - if(mode === MODE_DEFAULT) - { - onClose(); - - return; - } - - setGender(gender); - setNewFigure(GetAvatarRenderManager().getFigureStringWithFigureIds(figure, gender, validSets)); - - // if owns clothing, change to it - - setMode(mode); - }, [ roomSession, objectId, onClose ]); - - if(mode === MODE_DEFAULT) return null; - - return ( - - - - - - - - - - - - { LocalizeText('useproduct.widget.text.bind_clothing') } - { LocalizeText('useproduct.widget.info.bind_clothing') } - - - - - - - - - - ); -} diff --git a/src/components/room/widgets/furniture/playlist-editor/DiskInventoryView.tsx b/src/components/room/widgets/furniture/playlist-editor/DiskInventoryView.tsx deleted file mode 100644 index baf1bbf..0000000 --- a/src/components/room/widgets/furniture/playlist-editor/DiskInventoryView.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import { CreateLinkEvent, GetSoundManager, IAdvancedMap, MusicPriorities } from '@nitrots/nitro-renderer'; -import { FC, MouseEvent, useCallback, useEffect, useState } from 'react'; -import { CatalogPageName, GetConfigurationValue, GetDiskColor, LocalizeText } from '../../../../../api'; -import { AutoGrid, Base, Button, Flex, LayoutGridItem, Text } from '../../../../../common'; - -export interface DiskInventoryViewProps -{ - diskInventory: IAdvancedMap; - addToPlaylist: (diskId: number, slotNumber: number) => void; -} - -export const DiskInventoryView: FC = props => -{ - const { diskInventory = null, addToPlaylist = null } = props; - const [ selectedItem, setSelectedItem ] = useState(-1); - const [ previewSongId, setPreviewSongId ] = useState(-1); - - const previewSong = useCallback((event: MouseEvent, songId: number) => - { - event.stopPropagation(); - - setPreviewSongId(prevValue => (prevValue === songId) ? -1 : songId); - }, []); - - const addSong = useCallback((event: MouseEvent, diskId: number) => - { - event.stopPropagation(); - - addToPlaylist(diskId, GetSoundManager().musicController?.getRoomItemPlaylist()?.length) - }, [ addToPlaylist ]); - - const openCatalogPage = () => - { - CreateLinkEvent('catalog/open/' + CatalogPageName.TRAX_SONGS); - } - - useEffect(() => - { - if(previewSongId === -1) return; - - GetSoundManager().musicController?.playSong(previewSongId, MusicPriorities.PRIORITY_SONG_PLAY, 0, 0, 0, 0); - - return () => - { - GetSoundManager().musicController?.stop(MusicPriorities.PRIORITY_SONG_PLAY); - } - }, [ previewSongId ]); - - useEffect(() => - { - return () => setPreviewSongId(-1); - }, []); - - return (<> -
- -

{ LocalizeText('playlist.editor.my.music') }

-
-
- - { diskInventory && diskInventory.getKeys().map( (key, index) => - { - const diskId = diskInventory.getKey(index); - const songId = diskInventory.getWithIndex(index); - const songInfo = GetSoundManager().musicController?.getSongInfo(songId); - - return ( - setSelectedItem(prev => prev === index ? -1 : index) } classNames={ [ 'text-black' ] }> -
-
- { songInfo?.name } - { (selectedItem === index) && - - - - - } -
) - }) } -
-
-
-
{ LocalizeText('playlist.editor.text.get.more.music') }
-
{ LocalizeText('playlist.editor.text.you.have.no.songdisks.available') }
-
{ LocalizeText('playlist.editor.text.you.can.buy.some.from.the.catalogue') }
- -
- - ); -} diff --git a/src/components/room/widgets/furniture/playlist-editor/FurniturePlaylistEditorWidgetView.tsx b/src/components/room/widgets/furniture/playlist-editor/FurniturePlaylistEditorWidgetView.tsx deleted file mode 100644 index ceb0db9..0000000 --- a/src/components/room/widgets/furniture/playlist-editor/FurniturePlaylistEditorWidgetView.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../common'; -import { useFurniturePlaylistEditorWidget } from '../../../../../hooks'; -import { DiskInventoryView } from './DiskInventoryView'; -import { SongPlaylistView } from './SongPlaylistView'; - -export const FurniturePlaylistEditorWidgetView: FC<{}> = props => -{ - const { objectId = -1, currentPlayingIndex = -1, playlist = null, diskInventory = null, onClose = null, togglePlayPause = null, removeFromPlaylist = null, addToPlaylist = null } = useFurniturePlaylistEditorWidget(); - - if(objectId === -1) return null; - - return ( - - - -
-
- -
-
- -
-
-
-
- ); -} diff --git a/src/components/room/widgets/furniture/playlist-editor/SongPlaylistView.tsx b/src/components/room/widgets/furniture/playlist-editor/SongPlaylistView.tsx deleted file mode 100644 index 3e88329..0000000 --- a/src/components/room/widgets/furniture/playlist-editor/SongPlaylistView.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { ISongInfo } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { GetConfigurationValue, GetDiskColor, LocalizeText } from '../../../../../api'; -import { Base, Button, Flex, Text } from '../../../../../common'; - -export interface SongPlaylistViewProps -{ - furniId: number; - playlist: ISongInfo[]; - currentPlayingIndex: number; - removeFromPlaylist(slotNumber: number): void; - togglePlayPause(furniId: number, position: number): void; -} - -export const SongPlaylistView: FC = props => -{ - const { furniId = -1, playlist = null, currentPlayingIndex = -1, removeFromPlaylist = null, togglePlayPause = null } = props; - const [ selectedItem, setSelectedItem ] = useState(-1); - - const action = (index: number) => - { - if(selectedItem === index) removeFromPlaylist(index); - } - - const playPause = (furniId: number, selectedItem: number) => - { - togglePlayPause(furniId, selectedItem !== -1 ? selectedItem : 0 ) - } - - return (<> -
- -

{ LocalizeText('playlist.editor.playlist') }

-
-
- - { playlist && playlist.map( (songInfo, index) => - { - return setSelectedItem(prev => prev === index ? -1 : index) }> - action(index) } className={ 'disk-2 ' + (selectedItem === index ? 'selected-song' : '') } style={ { backgroundColor: (selectedItem === index ? '' : GetDiskColor(songInfo.songData)) } }/> - { songInfo.name } - - }) } - - -
- { (!playlist || playlist.length === 0 ) && - <>
-
{ LocalizeText('playlist.editor.add.songs.to.your.playlist') }
-
{ LocalizeText('playlist.editor.text.click.song.to.choose.click.again.to.move') }
-
- - } - { (playlist && playlist.length > 0) && - <> - { (currentPlayingIndex === -1) && - - } - { (currentPlayingIndex !== -1) && - - - - { LocalizeText('playlist.editor.text.now.playing.in.your.room') } - - { playlist[currentPlayingIndex]?.name + ' - ' + playlist[currentPlayingIndex]?.creator } - - - - - } - - } - - ); -} diff --git a/src/components/room/widgets/mysterybox/MysteryBoxExtensionView.scss b/src/components/room/widgets/mysterybox/MysteryBoxExtensionView.scss deleted file mode 100644 index 254821c..0000000 --- a/src/components/room/widgets/mysterybox/MysteryBoxExtensionView.scss +++ /dev/null @@ -1,52 +0,0 @@ -.mysterybox-extension { - - .mysterybox-container { - max-width: 50px; - max-height: 50px; - width: 50px; - height: 50px; - - background-color: rgba(28, 28, 32, 0.95); - box-shadow: inset 0px 5px rgb(34 34 39 / 60%), inset 0 -4px rgb(18 18 21 / 60%); - border-color: #5b5a57; - } - - .box-image { - width: 31px; - height: 36px; - position: relative; - background-image: url('@/assets/images/mysterybox/mystery_box.png'); - -webkit-mask-image: url('@/assets/images/mysterybox/mystery_box.png'); - mask-image: url('@/assets/images/mysterybox/mystery_box.png'); - - .chain-overlay-image { - width: 31px; - height: 36px; - position: absolute; - background-image: url('@/assets/images/mysterybox/chain_mysterybox_box_overlay.png'); - } - } - - .key-image { - width: 39px; - height: 39px; - position: relative; - background-image: url('@/assets/images/mysterybox/mystery_box_key.png'); - -webkit-mask-image: url('@/assets/images/mysterybox/mystery_box_key.png'); - mask-image: url('@/assets/images/mysterybox/mystery_box_key.png'); - - .key-overlay-image { - width: 39px; - height: 39px; - position: absolute; - background-image: url('@/assets/images/mysterybox/key_overlay.png'); - } - } - - .box-image, - .key-image { - background-blend-mode: multiply; - background-position: center; - background-repeat: no-repeat; - } -} diff --git a/src/components/room/widgets/mysterybox/MysteryBoxExtensionView.tsx b/src/components/room/widgets/mysterybox/MysteryBoxExtensionView.tsx deleted file mode 100644 index 3f69826..0000000 --- a/src/components/room/widgets/mysterybox/MysteryBoxExtensionView.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { MysteryBoxKeysUpdateEvent } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { FaChevronDown, FaChevronUp } from 'react-icons/fa'; -import { ColorUtils, LocalizeText } from '../../../../api'; -import { Base, Column, Flex, LayoutGridItem, Text } from '../../../../common'; -import { useNitroEvent } from '../../../../hooks'; - -const colorMap = { - 'purple': 9452386, - 'blue': 3891856, - 'green': 6459451, - 'yellow': 10658089, - 'lilac': 6897548, - 'orange': 10841125, - 'turquoise': 2661026, - 'red': 10104881 -} - -export const MysteryBoxExtensionView: FC<{}> = props => -{ - const [ isOpen, setIsOpen ] = useState(true); - const [ keyColor, setKeyColor ] = useState(''); - const [ boxColor, setBoxColor ] = useState(''); - - useNitroEvent(MysteryBoxKeysUpdateEvent.MYSTERY_BOX_KEYS_UPDATE, event => - { - setKeyColor(event.keyColor); - setBoxColor(event.boxColor); - }); - - const getRgbColor = (color: string) => - { - const colorInt = colorMap[color]; - - return ColorUtils.int2rgb(colorInt); - } - - if(keyColor === '' && boxColor === '') return null; - - return ( - - - setIsOpen(value => !value) }> - { LocalizeText('mysterybox.tracker.title') } - { isOpen && } - { !isOpen && } - - { isOpen && - <> - { LocalizeText('mysterybox.tracker.description') } - - -
-
-
- - -
-
-
- - - } - - - ); -} diff --git a/src/components/room/widgets/object-location/ObjectLocationView.tsx b/src/components/room/widgets/object-location/ObjectLocationView.tsx deleted file mode 100644 index 237090b..0000000 --- a/src/components/room/widgets/object-location/ObjectLocationView.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { GetTicker } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useRef, useState } from 'react'; -import { GetRoomObjectBounds, GetRoomSession } from '../../../../api'; -import { Base, BaseProps } from '../../../../common'; - -interface ObjectLocationViewProps extends BaseProps -{ - objectId: number; - category: number; - noFollow?: boolean; -} - -export const ObjectLocationView: FC = props => -{ - const { objectId = -1, category = -1, noFollow = false, position = 'absolute', ...rest } = props; - const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: -1, y: -1 }); - const elementRef = useRef(); - - useEffect(() => - { - let remove = false; - - const getObjectLocation = () => - { - const roomSession = GetRoomSession(); - const objectBounds = GetRoomObjectBounds(roomSession.roomId, objectId, category, 1); - - return objectBounds; - } - - const updatePosition = () => - { - const bounds = getObjectLocation(); - - if(!bounds || !elementRef.current) return; - - setPos({ - x: Math.round(((bounds.left + (bounds.width / 2)) - (elementRef.current.offsetWidth / 2))), - y: Math.round((bounds.top - elementRef.current.offsetHeight) + 10) - }); - } - - if(noFollow) - { - updatePosition(); - } - else - { - remove = true; - - GetTicker().add(updatePosition); - } - - return () => - { - if(remove) GetTicker().remove(updatePosition); - } - }, [ objectId, category, noFollow ]); - - return -1 } className="object-location" style={ { left: pos.x, top: pos.y } } { ...rest } />; -} diff --git a/src/components/room/widgets/pet-package/PetPackageWidgetView.scss b/src/components/room/widgets/pet-package/PetPackageWidgetView.scss deleted file mode 100644 index 97a6d2e..0000000 --- a/src/components/room/widgets/pet-package/PetPackageWidgetView.scss +++ /dev/null @@ -1,106 +0,0 @@ -.nitro-pet-package -{ - .pet-package-container-top - { - width: 400px; - height: 120px; - border-radius: 2px; - background-color: #0E3F52; - - .package-image-gnome_box - { - width: 80px; - height: 84px; - position: relative; - background-image: url('@/assets/images/pets/pet-package/gnome.png'); - background-repeat: no-repeat; - } - - .package-image-leprechaun_box - { - width: 80px; - height: 84px; - position: relative; - background-image: url('@/assets/images/pets/pet-package/leprechaun_box.png'); - background-repeat: no-repeat; - } - - .package-image-val11_present - { - width: 80px; - height: 84px; - position: relative; - background-image: url('@/assets/images/pets/pet-package/val11_present.png'); - background-repeat: no-repeat; - } - - .package-image-velociraptor_egg - { - width: 80px; - height: 84px; - position: relative; - background-image: url('@/assets/images/pets/pet-package/velociraptor_egg.png'); - background-repeat: no-repeat; - } - - .package-image-pterosaur_egg - { - width: 80px; - height: 84px; - position: relative; - background-image: url('@/assets/images/pets/pet-package/pterosaur_egg.png'); - background-repeat: no-repeat; - } - - .package-image-petbox_epic - { - width: 80px; - height: 84px; - position: relative; - background-image: url('@/assets/images/pets/pet-package/petbox_epic.png'); - background-repeat: no-repeat; - } - - .package-text-big - { - font-size: 16px; - } - } - - .pet-package-container-bottom - { - display: flex; - justify-content: center; - width: 400px; - height: 120px; - border-radius: 2px; - background-color: #E9E9E1; - - .input-pet-package-container - { - width: 380px; - border: 1px solid black; - - .input-pet-package - { - width: 350px; - border: 0; - outline: 0; - } - - .package-pencil-image - { - width: 16px; - height: 16px; - position: relative; - background-image: url('@/assets/images/infostand/pencil-icon.png'); - background-repeat: no-repeat; - } - } - - .text-decoration - { - text-decoration: underline; - } - } -} diff --git a/src/components/room/widgets/pet-package/PetPackageWidgetView.tsx b/src/components/room/widgets/pet-package/PetPackageWidgetView.tsx deleted file mode 100644 index e204f5e..0000000 --- a/src/components/room/widgets/pet-package/PetPackageWidgetView.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { FC } from 'react'; -import { Button } from 'react-bootstrap'; -import { GetConfigurationValue, LocalizeText } from '../../../../api'; -import { Base, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; -import { usePetPackageWidget } from '../../../../hooks'; - -export const PetPackageWidgetView: FC<{}> = props => -{ - const { isVisible = false, errorResult = null, petName = null, objectType = null, onChangePetName = null, onConfirm = null, onClose = null } = usePetPackageWidget(); - - return ( - <> - { isVisible && - - onClose() } /> - - -
-
- { objectType === 'gnome_box' ? LocalizeText('widgets.gnomepackage.name.title') : LocalizeText('furni.petpackage') } -
-
- - - - onChangePetName(event.target.value) } /> -
-
- { (errorResult.length > 0) && - { errorResult } } - - onClose() }>{ LocalizeText('cancel') } - - -
-
-
-
- } - - ); -} diff --git a/src/components/room/widgets/room-filter-words/RoomFilterWordsWidgetView.tsx b/src/components/room/widgets/room-filter-words/RoomFilterWordsWidgetView.tsx deleted file mode 100644 index 4f7825f..0000000 --- a/src/components/room/widgets/room-filter-words/RoomFilterWordsWidgetView.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { UpdateRoomFilterMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { LocalizeText, SendMessageComposer } from '../../../../api'; -import { Button, classNames, Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; -import { useFilterWordsWidget, useNavigator } from '../../../../hooks'; - -export const RoomFilterWordsWidgetView: FC<{}> = props => -{ - const [ word, setWord ] = useState('bobba'); - const [ selectedWord, setSelectedWord ] = useState(''); - const [ isSelectingWord, setIsSelectingWord ] = useState(false); - const { wordsFilter = [], isVisible = null, setWordsFilter, onClose = null } = useFilterWordsWidget(); - const { navigatorData = null } = useNavigator(); - - const processAction = (isAddingWord: boolean) => - { - if ((isSelectingWord) ? (!selectedWord) : (!word)) return; - - SendMessageComposer(new UpdateRoomFilterMessageComposer(navigatorData.enteredGuestRoom.roomId, isAddingWord, (isSelectingWord ? selectedWord : word))); - setSelectedWord(''); - setWord('bobba'); - setIsSelectingWord(false); - - if (isAddingWord && wordsFilter.includes((isSelectingWord ? selectedWord : word))) return; - - setWordsFilter(prevValue => - { - const newWords = [ ...prevValue ]; - - isAddingWord ? newWords.push((isSelectingWord ? selectedWord : word)) : newWords.splice(newWords.indexOf((isSelectingWord ? selectedWord : word)), 1); - - return newWords; - }); - } - - const onTyping = (word: string) => - { - setWord(word); - setIsSelectingWord(false); - } - - const onSelectedWord = (word: string) => - { - setSelectedWord(word); - setIsSelectingWord(true); - } - - if (!isVisible) return null; - - return ( - - onClose() } /> - - - onTyping(event.target.value) } /> - - - - { wordsFilter && (wordsFilter.length > 0) && wordsFilter.map((word, index) => - { - return ( - onSelectedWord(word) }> - { word } - - ) - }) } - - - - - - - ); -}; diff --git a/src/components/room/widgets/room-promotes/RoomPromotesWidgetView.tsx b/src/components/room/widgets/room-promotes/RoomPromotesWidgetView.tsx deleted file mode 100644 index b97b35a..0000000 --- a/src/components/room/widgets/room-promotes/RoomPromotesWidgetView.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { DesktopViewEvent, GetSessionDataManager } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { FaChevronDown, FaChevronUp } from 'react-icons/fa'; -import { Base, Column, Flex, Text } from '../../../../common'; -import { useMessageEvent, useRoomPromote } from '../../../../hooks'; -import { RoomPromoteEditWidgetView, RoomPromoteMyOwnEventWidgetView, RoomPromoteOtherEventWidgetView } from './views'; - -export const RoomPromotesWidgetView: FC<{}> = props => -{ - const [ isEditingPromote, setIsEditingPromote ] = useState(false); - const [ isOpen, setIsOpen ] = useState(true); - const { promoteInformation, setPromoteInformation } = useRoomPromote(); - - useMessageEvent(DesktopViewEvent, event => - { - setPromoteInformation(null); - }); - - if(!promoteInformation) return null; - - return ( - <> - { promoteInformation.data.adId !== -1 && - - - setIsOpen(value => !value) }> - { promoteInformation.data.eventName } - { isOpen && } - { !isOpen && } - - { (isOpen && GetSessionDataManager().userId !== promoteInformation.data.ownerAvatarId) && - - } - { (isOpen && GetSessionDataManager().userId === promoteInformation.data.ownerAvatarId) && - setIsEditingPromote(true) } - /> - } - { isEditingPromote && - setIsEditingPromote(false) } - /> - } - - - } - - ); -}; diff --git a/src/components/room/widgets/room-promotes/views/RoomPromoteEditWidgetView.tsx b/src/components/room/widgets/room-promotes/views/RoomPromoteEditWidgetView.tsx deleted file mode 100644 index f9b8462..0000000 --- a/src/components/room/widgets/room-promotes/views/RoomPromoteEditWidgetView.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { EditEventMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { LocalizeText, SendMessageComposer } from '../../../../../api'; -import { Button, Column, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common'; - -interface RoomPromoteEditWidgetViewProps -{ - eventId: number; - eventName: string; - eventDescription: string; - setIsEditingPromote: (value: boolean) => void; -} - -export const RoomPromoteEditWidgetView: FC = props => -{ - const { eventId = -1, eventName = '', eventDescription = '', setIsEditingPromote = null } = props; - const [ newEventName, setNewEventName ] = useState(eventName); - const [ newEventDescription, setNewEventDescription ] = useState(eventDescription); - - const updatePromote = () => - { - SendMessageComposer(new EditEventMessageComposer(eventId, newEventName, newEventDescription)); - setIsEditingPromote(false); - } - - return ( - - setIsEditingPromote(false) } /> - - - { LocalizeText('navigator.eventsettings.name') } - setNewEventName(event.target.value) } /> - - - { LocalizeText('navigator.eventsettings.desc') } - - - - - - - - ); -}; diff --git a/src/components/room/widgets/room-promotes/views/RoomPromoteMyOwnEventWidgetView.tsx b/src/components/room/widgets/room-promotes/views/RoomPromoteMyOwnEventWidgetView.tsx deleted file mode 100644 index 01a5f78..0000000 --- a/src/components/room/widgets/room-promotes/views/RoomPromoteMyOwnEventWidgetView.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { CreateLinkEvent } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { Button, Flex, Grid, Text } from '../../../../../common'; -import { useRoomPromote } from '../../../../../hooks'; - -interface RoomPromoteMyOwnEventWidgetViewProps -{ - eventDescription: string; - setIsEditingPromote: (value: boolean) => void; -} - -export const RoomPromoteMyOwnEventWidgetView: FC = props => -{ - const { eventDescription = '', setIsEditingPromote = null } = props; - const { setIsExtended } = useRoomPromote(); - - const extendPromote = () => - { - setIsExtended(true); - CreateLinkEvent('catalog/open/room_event'); - } - - return ( - <> - - { eventDescription } - -

- - - - - - ); -}; diff --git a/src/components/room/widgets/room-promotes/views/RoomPromoteOtherEventWidgetView.tsx b/src/components/room/widgets/room-promotes/views/RoomPromoteOtherEventWidgetView.tsx deleted file mode 100644 index 5adb517..0000000 --- a/src/components/room/widgets/room-promotes/views/RoomPromoteOtherEventWidgetView.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText } from '../../../../../api'; -import { Base, Column, Flex, Text } from '../../../../../common'; - -interface RoomPromoteOtherEventWidgetViewProps -{ - eventDescription: string; -} - -export const RoomPromoteOtherEventWidgetView: FC = props => -{ - const { eventDescription = '' } = props; - - return ( - <> - - { eventDescription } - -

- - - - { LocalizeText('navigator.eventinprogress') } - -   - - - - ); -}; diff --git a/src/components/room/widgets/room-promotes/views/index.ts b/src/components/room/widgets/room-promotes/views/index.ts deleted file mode 100644 index da74691..0000000 --- a/src/components/room/widgets/room-promotes/views/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './RoomPromoteEditWidgetView'; -export * from './RoomPromoteMyOwnEventWidgetView'; -export * from './RoomPromoteOtherEventWidgetView'; diff --git a/src/components/room/widgets/room-thumbnail/RoomThumbnailWidgetView.tsx b/src/components/room/widgets/room-thumbnail/RoomThumbnailWidgetView.tsx deleted file mode 100644 index edcb3ec..0000000 --- a/src/components/room/widgets/room-thumbnail/RoomThumbnailWidgetView.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { GetRoomEngine, NitroRenderTexture } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { LayoutMiniCameraView } from '../../../../common'; -import { RoomWidgetThumbnailEvent } from '../../../../events'; -import { useRoom, useUiEvent } from '../../../../hooks'; - -export const RoomThumbnailWidgetView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const { roomSession = null } = useRoom(); - - useUiEvent([ - RoomWidgetThumbnailEvent.SHOW_THUMBNAIL, - RoomWidgetThumbnailEvent.HIDE_THUMBNAIL, - RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL ], event => - { - switch(event.type) - { - case RoomWidgetThumbnailEvent.SHOW_THUMBNAIL: - setIsVisible(true); - return; - case RoomWidgetThumbnailEvent.HIDE_THUMBNAIL: - setIsVisible(false); - return; - case RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL: - setIsVisible(value => !value); - return; - } - }); - - const receiveTexture = async (texture: NitroRenderTexture) => - { - await GetRoomEngine().saveTextureAsScreenshot(texture, true); - - setIsVisible(false); - } - - if(!isVisible) return null; - - return setIsVisible(false) } /> -}; diff --git a/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx b/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx deleted file mode 100644 index 76fd022..0000000 --- a/src/components/room/widgets/room-tools/RoomToolsWidgetView.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { CreateLinkEvent, GetGuestRoomResultEvent, GetRoomEngine, NavigatorSearchComposer, RateFlatMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, SendMessageComposer } from '../../../../api'; -import { Base, Column, Flex, Text, TransitionAnimation, TransitionAnimationTypes, classNames } from '../../../../common'; -import { useMessageEvent, useNavigator, useRoom } from '../../../../hooks'; - -export const RoomToolsWidgetView: FC<{}> = props => -{ - const [ isZoomedIn, setIsZoomedIn ] = useState(false); - const [ roomName, setRoomName ] = useState(null); - const [ roomOwner, setRoomOwner ] = useState(null); - const [ roomTags, setRoomTags ] = useState(null); - const [ isOpen, setIsOpen ] = useState(false); - const { navigatorData = null } = useNavigator(); - const { roomSession = null } = useRoom(); - - const handleToolClick = (action: string, value?: string) => - { - switch(action) - { - case 'settings': - CreateLinkEvent('navigator/toggle-room-info'); - return; - case 'zoom': - setIsZoomedIn(prevValue => - { - let scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomSession.roomId, 1); - - if(!prevValue) scale /= 2; - else scale *= 2; - - GetRoomEngine().setRoomInstanceRenderingCanvasScale(roomSession.roomId, 1, scale); - - return !prevValue; - }); - return; - case 'chat_history': - CreateLinkEvent('chat-history/toggle'); - return; - case 'like_room': - SendMessageComposer(new RateFlatMessageComposer(1)); - return; - case 'toggle_room_link': - CreateLinkEvent('navigator/toggle-room-link'); - return; - case 'navigator_search_tag': - CreateLinkEvent(`navigator/search/${ value }`); - SendMessageComposer(new NavigatorSearchComposer('hotel_view', `tag:${ value }`)); - return; - } - } - - useMessageEvent(GetGuestRoomResultEvent, event => - { - const parser = event.getParser(); - - if(!parser.roomEnter || (parser.data.roomId !== roomSession.roomId)) return; - - if(roomName !== parser.data.roomName) setRoomName(parser.data.roomName); - if(roomOwner !== parser.data.ownerName) setRoomOwner(parser.data.ownerName); - if(roomTags !== parser.data.tags) setRoomTags(parser.data.tags); - }); - - useEffect(() => - { - setIsOpen(true); - - const timeout = setTimeout(() => setIsOpen(false), 5000); - - return () => clearTimeout(timeout); - }, [ roomName, roomOwner, roomTags ]); - - return ( - - - handleToolClick('settings') } /> - handleToolClick('zoom') } className={ classNames('icon', (!isZoomedIn && 'icon-zoom-less'), (isZoomedIn && 'icon-zoom-more')) } /> - handleToolClick('chat_history') } className="icon icon-chat-history" /> - { navigatorData.canRate && - handleToolClick('like_room') } className="icon icon-like-room" /> } - - - - - - - { roomName } - { roomOwner } - - { roomTags && roomTags.length > 0 && - - { roomTags.map((tag, index) => handleToolClick('navigator_search_tag', tag) }>#{ tag }) } - } - - - - - - ); -} diff --git a/src/components/room/widgets/user-location/UserLocationView.tsx b/src/components/room/widgets/user-location/UserLocationView.tsx deleted file mode 100644 index ca281ec..0000000 --- a/src/components/room/widgets/user-location/UserLocationView.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { RoomObjectCategory } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { BaseProps } from '../../../../common'; -import { useRoom } from '../../../../hooks'; -import { ObjectLocationView } from '../object-location/ObjectLocationView'; - -interface UserLocationViewProps extends BaseProps -{ - userId: number; -} - -export const UserLocationView: FC = props => -{ - const { userId = -1, ...rest } = props; - const { roomSession = null } = useRoom(); - - if((userId === -1) || !roomSession) return null; - - const userData = roomSession.userDataManager.getUserData(userId); - - if(!userData) return null; - - return ; -} diff --git a/src/components/room/widgets/word-quiz/WordQuizQuestionView.tsx b/src/components/room/widgets/word-quiz/WordQuizQuestionView.tsx deleted file mode 100644 index 3b4d051..0000000 --- a/src/components/room/widgets/word-quiz/WordQuizQuestionView.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { FC } from 'react'; -import { VALUE_KEY_DISLIKE, VALUE_KEY_LIKE } from '../../../../api'; -import { Base, Column, Flex, Text } from '../../../../common'; - -interface WordQuizQuestionViewProps -{ - question: string; - canVote: boolean; - vote(value: string): void; - noVotes: number; - yesVotes: number; -} - -export const WordQuizQuestionView: FC = props => -{ - const { question = null, canVote = null, vote = null, noVotes = null, yesVotes = null } = props; - - return ( - - { !canVote && - - - { noVotes } - - { question } - - { yesVotes } - - } - { canVote && - - { question } - - vote(VALUE_KEY_DISLIKE) }> - - - vote(VALUE_KEY_LIKE) }> - - - - } - - ); -} diff --git a/src/components/room/widgets/word-quiz/WordQuizVoteView.tsx b/src/components/room/widgets/word-quiz/WordQuizVoteView.tsx deleted file mode 100644 index 8437d76..0000000 --- a/src/components/room/widgets/word-quiz/WordQuizVoteView.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { RoomObjectCategory } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { VALUE_KEY_DISLIKE } from '../../../../api'; -import { Base, BaseProps, Flex } from '../../../../common'; -import { ObjectLocationView } from '../object-location/ObjectLocationView'; - -interface WordQuizVoteViewProps extends BaseProps -{ - userIndex: number; - vote: string; -} - -export const WordQuizVoteView: FC = props => -{ - const { userIndex = null, vote = null, ...rest } = props; - - return ( - - - - - - ); -} diff --git a/src/components/room/widgets/word-quiz/WordQuizWidgetView.tsx b/src/components/room/widgets/word-quiz/WordQuizWidgetView.tsx deleted file mode 100644 index a04cfd8..0000000 --- a/src/components/room/widgets/word-quiz/WordQuizWidgetView.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { FC } from 'react'; -import { VALUE_KEY_DISLIKE, VALUE_KEY_LIKE } from '../../../../api'; -import { useWordQuizWidget } from '../../../../hooks'; -import { WordQuizQuestionView } from './WordQuizQuestionView'; -import { WordQuizVoteView } from './WordQuizVoteView'; - -export const WordQuizWidgetView: FC<{}> = props => -{ - const { question = null, answerSent = false, answerCounts = null, userAnswers = null, vote = null } = useWordQuizWidget(); - - return ( - <> - { question && - } - { userAnswers && - Array.from(userAnswers.entries()).map(([ key, value ], index) => ) } - - ); -} diff --git a/src/components/toolbar/ToolbarMeView.tsx b/src/components/toolbar/ToolbarMeView.tsx deleted file mode 100644 index d0329cc..0000000 --- a/src/components/toolbar/ToolbarMeView.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { CreateLinkEvent, GetRoomEngine, GetSessionDataManager, MouseEventType, RoomObjectCategory } from '@nitrots/nitro-renderer'; -import { Dispatch, FC, PropsWithChildren, SetStateAction, useEffect, useRef } from 'react'; -import { DispatchUiEvent, GetConfigurationValue, GetRoomSession, GetUserProfile } from '../../api'; -import { Base, Flex, LayoutItemCountView } from '../../common'; -import { GuideToolEvent } from '../../events'; - -interface ToolbarMeViewProps -{ - useGuideTool: boolean; - unseenAchievementCount: number; - setMeExpanded: Dispatch>; -} - -export const ToolbarMeView: FC> = props => -{ - const { useGuideTool = false, unseenAchievementCount = 0, setMeExpanded = null, children = null, ...rest } = props; - const elementRef = useRef(); - - useEffect(() => - { - const roomSession = GetRoomSession(); - - if(!roomSession) return; - - GetRoomEngine().selectRoomObject(roomSession.roomId, roomSession.ownRoomIndex, RoomObjectCategory.UNIT); - }, []); - - useEffect(() => - { - const onClick = (event: MouseEvent) => setMeExpanded(false); - - document.addEventListener('click', onClick); - - return () => document.removeEventListener(MouseEventType.MOUSE_CLICK, onClick); - }, [ setMeExpanded ]); - - return ( - - { (GetConfigurationValue('guides.enabled') && useGuideTool) && - DispatchUiEvent(new GuideToolEvent(GuideToolEvent.TOGGLE_GUIDE_TOOL)) } /> } - CreateLinkEvent('achievements/toggle') }> - { (unseenAchievementCount > 0) && - } - - GetUserProfile(GetSessionDataManager().userId) } /> - CreateLinkEvent('navigator/search/myworld_view') } /> - CreateLinkEvent('avatar-editor/toggle') } /> - CreateLinkEvent('user-settings/toggle') } /> - { children } - - ); -} diff --git a/src/components/toolbar/ToolbarView.scss b/src/components/toolbar/ToolbarView.scss deleted file mode 100644 index 6e7f651..0000000 --- a/src/components/toolbar/ToolbarView.scss +++ /dev/null @@ -1,81 +0,0 @@ -.nitro-toolbar { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: $toolbar-height; - z-index: $toolbar-zindex; - pointer-events: all; - background: rgba($dark, 0.95); - box-shadow: inset 0px 5px lighten(rgba($dark, 0.6), 2.5), - inset 0 -4px darken(rgba($dark, 0.6), 4); - - .navigation-item { - position: relative; - - &.item-avatar { - width: 50px; - height: 45px; - overflow: hidden; - - .avatar-image { - margin-left: -5px; - margin-top: 25px; - } - } - - &:hover { - -webkit-transform: translate(-1px, -1px); - transform: translate(-1px, -1px); - filter: drop-shadow(2px 2px 0 rgba($black, 0.8)); - } - - &.active, - &:active { - -webkit-transform: unset; - transform: unset; - filter: none; - } - } - - #toolbar-chat-input-container { - - @include media-breakpoint-down(sm) { - width: 0px; - height: 0px; - } - } -} - -.nitro-toolbar-me { - position: absolute; - bottom: 60px; - left: 15px; - z-index: $toolbar-memenu-zindex; - background: rgba(20, 20, 20, .95); - border: 1px solid #101010; - box-shadow: inset 2px 2px rgba(255, 255, 255, .1), inset -2px -2px rgba(255, 255, 255, .1); - border-radius: $border-radius; - - .navigation-item { - transition: filter .2s ease-out; - filter: grayscale(1); - - &:hover { - filter: grayscale(0) drop-shadow(2px 2px 0 rgba($black, 0.8)); - } - } -} - -.toolbar-icon-animation { - position: absolute; - object-fit: cover; - height: auto; - width: auto; - max-width: 120px; - max-height: 150px; - z-index: 500; - filter: drop-shadow(2px 1px 0 rgba($white, 1)) - drop-shadow(-2px 1px 0 rgba($white, 1)) - drop-shadow(0 -2px 0 rgba($white, 1)); -} diff --git a/src/components/toolbar/ToolbarView.tsx b/src/components/toolbar/ToolbarView.tsx deleted file mode 100644 index 1fd6d2d..0000000 --- a/src/components/toolbar/ToolbarView.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import { CreateLinkEvent, Dispose, DropBounce, EaseOut, GetSessionDataManager, JumpBy, Motions, NitroToolbarAnimateIconEvent, PerkAllowancesMessageEvent, PerkEnum, Queue, Wait } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { GetConfigurationValue, MessengerIconState, OpenMessengerChat, VisitDesktop } from '../../api'; -import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common'; -import { useAchievements, useFriends, useInventoryUnseenTracker, useMessageEvent, useMessenger, useNitroEvent, useSessionInfo } from '../../hooks'; -import { ToolbarMeView } from './ToolbarMeView'; - -export const ToolbarView: FC<{ isInRoom: boolean }> = props => -{ - const { isInRoom } = props; - const [ isMeExpanded, setMeExpanded ] = useState(false); - const [ useGuideTool, setUseGuideTool ] = useState(false); - const { userFigure = null } = useSessionInfo(); - const { getFullCount = 0 } = useInventoryUnseenTracker(); - const { getTotalUnseen = 0 } = useAchievements(); - const { requests = [] } = useFriends(); - const { iconState = MessengerIconState.HIDDEN } = useMessenger(); - const isMod = GetSessionDataManager().isModerator; - - useMessageEvent(PerkAllowancesMessageEvent, event => - { - const parser = event.getParser(); - - setUseGuideTool(parser.isAllowed(PerkEnum.USE_GUIDE_TOOL)); - }); - - useNitroEvent(NitroToolbarAnimateIconEvent.ANIMATE_ICON, event => - { - const animationIconToToolbar = (iconName: string, image: HTMLImageElement, x: number, y: number) => - { - const target = (document.body.getElementsByClassName(iconName)[0] as HTMLElement); - - if(!target) return; - - image.className = 'toolbar-icon-animation'; - image.style.visibility = 'visible'; - image.style.left = (x + 'px'); - image.style.top = (y + 'px'); - - document.body.append(image); - - const targetBounds = target.getBoundingClientRect(); - const imageBounds = image.getBoundingClientRect(); - - const left = (imageBounds.x - targetBounds.x); - const top = (imageBounds.y - targetBounds.y); - const squared = Math.sqrt(((left * left) + (top * top))); - const wait = (500 - Math.abs(((((1 / squared) * 100) * 500) * 0.5))); - const height = 20; - - const motionName = (`ToolbarBouncing[${ iconName }]`); - - if(!Motions.getMotionByTag(motionName)) - { - Motions.runMotion(new Queue(new Wait((wait + 8)), new DropBounce(target, 400, 12))).tag = motionName; - } - - const motion = new Queue(new EaseOut(new JumpBy(image, wait, ((targetBounds.x - imageBounds.x) + height), (targetBounds.y - imageBounds.y), 100, 1), 1), new Dispose(image)); - - Motions.runMotion(motion); - } - - animationIconToToolbar('icon-inventory', event.image, event.x, event.y); - }); - - return ( - <> - - - - - - - setMeExpanded(!isMeExpanded) }> - - { (getTotalUnseen > 0) && - } - - { isInRoom && - VisitDesktop() } /> } - { !isInRoom && - CreateLinkEvent('navigator/goto/home') } /> } - CreateLinkEvent('navigator/toggle') } /> - { GetConfigurationValue('game.center.enabled') && CreateLinkEvent('games/toggle') } /> } - CreateLinkEvent('catalog/toggle') } /> - CreateLinkEvent('inventory/toggle') }> - { (getFullCount > 0) && - } - - { isInRoom && - CreateLinkEvent('camera/toggle') } /> } - { isMod && - CreateLinkEvent('mod-tools/toggle') } /> } - - - - - - CreateLinkEvent('friends/toggle') }> - { (requests.length > 0) && - } - - { ((iconState === MessengerIconState.SHOW) || (iconState === MessengerIconState.UNREAD)) && - OpenMessengerChat() } /> } - - - - - - ); -} diff --git a/src/components/user-profile/UserProfileVew.scss b/src/components/user-profile/UserProfileVew.scss deleted file mode 100644 index edcfde6..0000000 --- a/src/components/user-profile/UserProfileVew.scss +++ /dev/null @@ -1,67 +0,0 @@ -.user-profile { - width: $user-profile-width; - height: $user-profile-height; - - .user-container { - border-right: 1px solid gray; - - .avatar-container { - width: 75px; - height: 120px; - } - } - - .rooms-button-container { - border-top: 1px solid gray; - border-bottom: 1px solid gray; - } - - .user-relationship { - height: 25px; - - .avatar-image-container { - width: 50px; - height: 50px; - - .avatar-image { - top: 20px; - right: -8pxpx; - } - } - } - - .user-relationship-count { - margin-top: 2px; - margin-left: 5px; - color: #939392 !important; - } - - .user-groups-container { - - .layout-grid-item { - width: 50px; - } - } - - .no-group-spritesheet { - background: transparent url('@/assets/images/groups/no-group-spritesheet.png') no-repeat; - - &.image-1 { - width: 95px; - height: 136px; - background-position: -3px -3px; - } - - &.image-2 { - width: 95px; - height: 136px; - background-position: -104px -3px; - } - - &.image-3 { - width: 95px; - height: 136px; - background-position: -205px -3px; - } - } -} diff --git a/src/components/user-profile/UserProfileView.tsx b/src/components/user-profile/UserProfileView.tsx deleted file mode 100644 index 64349b2..0000000 --- a/src/components/user-profile/UserProfileView.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { CreateLinkEvent, ExtendedProfileChangedMessageEvent, GetSessionDataManager, RelationshipStatusInfoEvent, RelationshipStatusInfoMessageParser, RoomEngineObjectEvent, RoomObjectCategory, RoomObjectType, UserCurrentBadgesComposer, UserCurrentBadgesEvent, UserProfileEvent, UserProfileParser, UserRelationshipsComposer } from '@nitrots/nitro-renderer'; -import { FC, useState } from 'react'; -import { GetRoomSession, GetUserProfile, LocalizeText, SendMessageComposer } from '../../api'; -import { Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common'; -import { useMessageEvent, useNitroEvent } from '../../hooks'; -import { BadgesContainerView } from './views/BadgesContainerView'; -import { FriendsContainerView } from './views/FriendsContainerView'; -import { GroupsContainerView } from './views/GroupsContainerView'; -import { UserContainerView } from './views/UserContainerView'; - -export const UserProfileView: FC<{}> = props => -{ - const [ userProfile, setUserProfile ] = useState(null); - const [ userBadges, setUserBadges ] = useState([]); - const [ userRelationships, setUserRelationships ] = useState(null); - - const onClose = () => - { - setUserProfile(null); - setUserBadges([]); - setUserRelationships(null); - } - - const onLeaveGroup = () => - { - if(!userProfile || (userProfile.id !== GetSessionDataManager().userId)) return; - - GetUserProfile(userProfile.id); - } - - useMessageEvent(UserCurrentBadgesEvent, event => - { - const parser = event.getParser(); - - if(!userProfile || (parser.userId !== userProfile.id)) return; - - setUserBadges(parser.badges); - }); - - useMessageEvent(RelationshipStatusInfoEvent, event => - { - const parser = event.getParser(); - - if(!userProfile || (parser.userId !== userProfile.id)) return; - - setUserRelationships(parser); - }); - - useMessageEvent(UserProfileEvent, event => - { - const parser = event.getParser(); - - let isSameProfile = false; - - setUserProfile(prevValue => - { - if(prevValue && prevValue.id) isSameProfile = (prevValue.id === parser.id); - - return parser; - }); - - if(!isSameProfile) - { - setUserBadges([]); - setUserRelationships(null); - } - - SendMessageComposer(new UserCurrentBadgesComposer(parser.id)); - SendMessageComposer(new UserRelationshipsComposer(parser.id)); - }); - - useMessageEvent(ExtendedProfileChangedMessageEvent, event => - { - const parser = event.getParser(); - - if(parser.userId != userProfile?.id) return; - - GetUserProfile(parser.userId); - }); - - useNitroEvent(RoomEngineObjectEvent.SELECTED, event => - { - if(!userProfile) return; - - if(event.category !== RoomObjectCategory.UNIT) return; - - const userData = GetRoomSession().userDataManager.getUserDataByIndex(event.objectId); - - if(userData.type !== RoomObjectType.USER) return; - - GetUserProfile(userData.webID); - }); - - if(!userProfile) return null; - - return ( - - - - - - - - - - - - { userRelationships && - } - - - - CreateLinkEvent(`navigator/search/hotel_view/owner:${ userProfile.username }`) }> - - { LocalizeText('extendedprofile.rooms') } - - - - - - ) -} diff --git a/src/components/user-profile/views/BadgesContainerView.tsx b/src/components/user-profile/views/BadgesContainerView.tsx deleted file mode 100644 index ca59fc2..0000000 --- a/src/components/user-profile/views/BadgesContainerView.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { FC } from 'react'; -import { Column, FlexProps, LayoutBadgeImageView } from '../../../common'; - -interface BadgesContainerViewProps extends FlexProps -{ - badges: string[]; -} - -export const BadgesContainerView: FC = props => -{ - const { badges = null, gap = 1, justifyContent = 'between', ...rest } = props; - - return ( - <> - { badges && (badges.length > 0) && badges.map((badge, index) => - { - return ( - - - - ); - }) } - - ); -} diff --git a/src/components/user-profile/views/FriendsContainerView.tsx b/src/components/user-profile/views/FriendsContainerView.tsx deleted file mode 100644 index f5449d1..0000000 --- a/src/components/user-profile/views/FriendsContainerView.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { RelationshipStatusInfoMessageParser } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { LocalizeText } from '../../../api'; -import { Column, Text } from '../../../common'; -import { RelationshipsContainerView } from './RelationshipsContainerView'; - -interface FriendsContainerViewProps -{ - relationships: RelationshipStatusInfoMessageParser; - friendsCount: number; -} - -export const FriendsContainerView: FC = props => -{ - const { relationships = null, friendsCount = null } = props; - - return ( - - - { LocalizeText('extendedprofile.friends.count') } { friendsCount } - - { LocalizeText('extendedprofile.relstatus') } - - - - - ) -} diff --git a/src/components/user-profile/views/GroupsContainerView.tsx b/src/components/user-profile/views/GroupsContainerView.tsx deleted file mode 100644 index bd598ee..0000000 --- a/src/components/user-profile/views/GroupsContainerView.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { GroupInformationComposer, GroupInformationEvent, GroupInformationParser, HabboGroupEntryData } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { SendMessageComposer, ToggleFavoriteGroup } from '../../../api'; -import { AutoGrid, Base, Column, Flex, Grid, GridProps, LayoutBadgeImageView, LayoutGridItem } from '../../../common'; -import { useMessageEvent } from '../../../hooks'; -import { GroupInformationView } from '../../groups/views/GroupInformationView'; - -interface GroupsContainerViewProps extends GridProps -{ - itsMe: boolean; - groups: HabboGroupEntryData[]; - onLeaveGroup: () => void; -} - -export const GroupsContainerView: FC = props => -{ - const { itsMe = null, groups = null, onLeaveGroup = null, overflow = 'hidden', gap = 2, ...rest } = props; - const [ selectedGroupId, setSelectedGroupId ] = useState(null); - const [ groupInformation, setGroupInformation ] = useState(null); - - useMessageEvent(GroupInformationEvent, event => - { - const parser = event.getParser(); - - if(!selectedGroupId || (selectedGroupId !== parser.id) || parser.flag) return; - - setGroupInformation(parser); - }); - - useEffect(() => - { - if(!selectedGroupId) return; - - SendMessageComposer(new GroupInformationComposer(selectedGroupId, false)); - }, [ selectedGroupId ]); - - useEffect(() => - { - setGroupInformation(null); - - if(groups.length > 0) - { - setSelectedGroupId(prevValue => - { - if(prevValue === groups[0].groupId) - { - SendMessageComposer(new GroupInformationComposer(groups[0].groupId, false)); - } - - return groups[0].groupId; - }); - } - }, [ groups ]); - - if(!groups || !groups.length) - { - return ( - - - - - - - - ); - } - - return ( - - - - { groups.map((group, index) => - { - return ( - setSelectedGroupId(group.groupId) } className="p-1"> - { itsMe && - ToggleFavoriteGroup(group) } /> } - - - ) - }) } - - - - { groupInformation && - } - - - ); -} diff --git a/src/components/user-profile/views/RelationshipsContainerView.tsx b/src/components/user-profile/views/RelationshipsContainerView.tsx deleted file mode 100644 index 9b698ec..0000000 --- a/src/components/user-profile/views/RelationshipsContainerView.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { RelationshipStatusEnum, RelationshipStatusInfoMessageParser } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { GetUserProfile, LocalizeText } from '../../../api'; -import { Column, Flex, LayoutAvatarImageView, Text } from '../../../common'; - -interface RelationshipsContainerViewProps -{ - relationships: RelationshipStatusInfoMessageParser; -} - -interface RelationshipsContainerRelationshipViewProps -{ - type: number; -} - -export const RelationshipsContainerView: FC = props => -{ - const { relationships = null } = props; - - const RelationshipComponent = ({ type }: RelationshipsContainerRelationshipViewProps) => - { - const relationshipInfo = (relationships && relationships.relationshipStatusMap.hasKey(type)) ? relationships.relationshipStatusMap.getValue(type) : null; - const relationshipName = RelationshipStatusEnum.RELATIONSHIP_NAMES[type].toLocaleLowerCase(); - - return ( - - - - - - - (relationshipInfo && (relationshipInfo.randomFriendId >= 1) && GetUserProfile(relationshipInfo.randomFriendId)) }> - { (!relationshipInfo || (relationshipInfo.friendCount === 0)) && - LocalizeText('extendedprofile.add.friends') } - { (relationshipInfo && (relationshipInfo.friendCount >= 1)) && - relationshipInfo.randomFriendName } - - { (relationshipInfo && (relationshipInfo.friendCount >= 1)) && - - - } - - - { (!relationshipInfo || (relationshipInfo.friendCount === 0)) && - LocalizeText('extendedprofile.no.friends.in.this.category') } - { (relationshipInfo && (relationshipInfo.friendCount > 1)) && - LocalizeText(`extendedprofile.relstatus.others.${ relationshipName }`, [ 'count' ], [ (relationshipInfo.friendCount - 1).toString() ]) } -   - - - - ); - } - - return ( - <> - - - - - ); -} diff --git a/src/components/user-profile/views/UserContainerView.tsx b/src/components/user-profile/views/UserContainerView.tsx deleted file mode 100644 index a83fb96..0000000 --- a/src/components/user-profile/views/UserContainerView.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { GetSessionDataManager, RequestFriendComposer, UserProfileParser } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { FriendlyTime, LocalizeText, SendMessageComposer } from '../../../api'; -import { Column, Flex, LayoutAvatarImageView, Text } from '../../../common'; - -interface UserContainerViewProps -{ - userProfile: UserProfileParser; -} - -export const UserContainerView: FC = props => -{ - const { userProfile = null } = props; - const [ requestSent, setRequestSent ] = useState(userProfile.requestSent); - const isOwnProfile = (userProfile.id === GetSessionDataManager().userId); - const canSendFriendRequest = !requestSent && (!isOwnProfile && !userProfile.isMyFriend && !userProfile.requestSent); - - const addFriend = () => - { - setRequestSent(true); - - SendMessageComposer(new RequestFriendComposer(userProfile.username)); - } - - useEffect(() => - { - setRequestSent(userProfile.requestSent); - }, [ userProfile ]) - - return ( - - - - - - - { userProfile.username } - { userProfile.motto }  - - - - { LocalizeText('extendedprofile.created') } { userProfile.registration } - - - { LocalizeText('extendedprofile.last.login') } { FriendlyTime.format(userProfile.secondsSinceLastVisit, '.ago', 2) } - - - { LocalizeText('extendedprofile.achievementscore') } { userProfile.achievementPoints } - - - - { userProfile.isOnline && - } - { !userProfile.isOnline && - } - - { canSendFriendRequest && - { LocalizeText('extendedprofile.addasafriend') } } - { !canSendFriendRequest && - <> - - { isOwnProfile && - { LocalizeText('extendedprofile.me') } } - { userProfile.isMyFriend && - { LocalizeText('extendedprofile.friend') } } - { (requestSent || userProfile.requestSent) && - { LocalizeText('extendedprofile.friendrequestsent') } } - } - - - - - ) -} diff --git a/src/components/user-settings/UserSettingsView.tsx b/src/components/user-settings/UserSettingsView.tsx deleted file mode 100644 index 43a4f51..0000000 --- a/src/components/user-settings/UserSettingsView.tsx +++ /dev/null @@ -1,187 +0,0 @@ -import { AddLinkEventTracker, ILinkEventTracker, NitroSettingsEvent, RemoveLinkEventTracker, UserSettingsCameraFollowComposer, UserSettingsEvent, UserSettingsOldChatComposer, UserSettingsRoomInvitesComposer, UserSettingsSoundComposer } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { FaVolumeDown, FaVolumeMute, FaVolumeUp } from 'react-icons/fa'; -import { DispatchMainEvent, DispatchUiEvent, LocalizeText, SendMessageComposer } from '../../api'; -import { Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, classNames } from '../../common'; -import { useCatalogPlaceMultipleItems, useCatalogSkipPurchaseConfirmation, useMessageEvent } from '../../hooks'; - -export const UserSettingsView: FC<{}> = props => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ userSettings, setUserSettings ] = useState(null); - const [ catalogPlaceMultipleObjects, setCatalogPlaceMultipleObjects ] = useCatalogPlaceMultipleItems(); - const [ catalogSkipPurchaseConfirmation, setCatalogSkipPurchaseConfirmation ] = useCatalogSkipPurchaseConfirmation(); - - const processAction = (type: string, value?: boolean | number | string) => - { - let doUpdate = true; - - const clone = userSettings.clone(); - - switch(type) - { - case 'close_view': - setIsVisible(false); - doUpdate = false; - return; - case 'oldchat': - clone.oldChat = value as boolean; - SendMessageComposer(new UserSettingsOldChatComposer(clone.oldChat)); - break; - case 'room_invites': - clone.roomInvites = value as boolean; - SendMessageComposer(new UserSettingsRoomInvitesComposer(clone.roomInvites)); - break; - case 'camera_follow': - clone.cameraFollow = value as boolean; - SendMessageComposer(new UserSettingsCameraFollowComposer(clone.cameraFollow)); - break; - case 'system_volume': - clone.volumeSystem = value as number; - clone.volumeSystem = Math.max(0, clone.volumeSystem); - clone.volumeSystem = Math.min(100, clone.volumeSystem); - break; - case 'furni_volume': - clone.volumeFurni = value as number; - clone.volumeFurni = Math.max(0, clone.volumeFurni); - clone.volumeFurni = Math.min(100, clone.volumeFurni); - break; - case 'trax_volume': - clone.volumeTrax = value as number; - clone.volumeTrax = Math.max(0, clone.volumeTrax); - clone.volumeTrax = Math.min(100, clone.volumeTrax); - break; - } - - if(doUpdate) setUserSettings(clone); - - DispatchMainEvent(clone) - } - - const saveRangeSlider = (type: string) => - { - switch(type) - { - case 'volume': - SendMessageComposer(new UserSettingsSoundComposer(Math.round(userSettings.volumeSystem), Math.round(userSettings.volumeFurni), Math.round(userSettings.volumeTrax))); - break; - } - } - - useMessageEvent(UserSettingsEvent, event => - { - const parser = event.getParser(); - const settingsEvent = new NitroSettingsEvent(); - - settingsEvent.volumeSystem = parser.volumeSystem; - settingsEvent.volumeFurni = parser.volumeFurni; - settingsEvent.volumeTrax = parser.volumeTrax; - settingsEvent.oldChat = parser.oldChat; - settingsEvent.roomInvites = parser.roomInvites; - settingsEvent.cameraFollow = parser.cameraFollow; - settingsEvent.flags = parser.flags; - settingsEvent.chatType = parser.chatType; - - setUserSettings(settingsEvent); - DispatchMainEvent(settingsEvent); - }); - - useEffect(() => - { - const linkTracker: ILinkEventTracker = { - linkReceived: (url: string) => - { - const parts = url.split('/'); - - if(parts.length < 2) return; - - switch(parts[1]) - { - case 'show': - setIsVisible(true); - return; - case 'hide': - setIsVisible(false); - return; - case 'toggle': - setIsVisible(prevValue => !prevValue); - return; - } - }, - eventUrlPrefix: 'user-settings/' - }; - - AddLinkEventTracker(linkTracker); - - return () => RemoveLinkEventTracker(linkTracker); - }, []); - - useEffect(() => - { - if(!userSettings) return; - - DispatchUiEvent(userSettings); - }, [ userSettings ]); - - if(!isVisible || !userSettings) return null; - - return ( - - processAction('close_view') } /> - - - - processAction('oldchat', event.target.checked) } /> - { LocalizeText('memenu.settings.chat.prefer.old.chat') } - - - processAction('room_invites', event.target.checked) } /> - { LocalizeText('memenu.settings.other.ignore.room.invites') } - - - processAction('camera_follow', event.target.checked) } /> - { LocalizeText('memenu.settings.other.disable.room.camera.follow') } - - - setCatalogPlaceMultipleObjects(event.target.checked) } /> - { LocalizeText('memenu.settings.other.place.multiple.objects') } - - - setCatalogSkipPurchaseConfirmation(event.target.checked) } /> - { LocalizeText('memenu.settings.other.skip.purchase.confirmation') } - - - - { LocalizeText('widget.memenu.settings.volume') } - - { LocalizeText('widget.memenu.settings.volume.ui') } - - { (userSettings.volumeSystem === 0) && = 50) && 'text-muted', 'fa-icon') } /> } - { (userSettings.volumeSystem > 0) && = 50) && 'text-muted', 'fa-icon') } /> } - processAction('system_volume', event.target.value) } onMouseUp={ () => saveRangeSlider('volume') }/> - - - - - { LocalizeText('widget.memenu.settings.volume.furni') } - - { (userSettings.volumeFurni === 0) && = 50) && 'text-muted', 'fa-icon') } /> } - { (userSettings.volumeFurni > 0) && = 50) && 'text-muted', 'fa-icon') } /> } - processAction('furni_volume', event.target.value) } onMouseUp={ () => saveRangeSlider('volume') }/> - - - - - { LocalizeText('widget.memenu.settings.volume.trax') } - - { (userSettings.volumeTrax === 0) && = 50) && 'text-muted', 'fa-icon') } /> } - { (userSettings.volumeTrax > 0) && = 50) && 'text-muted', 'fa-icon') } /> } - processAction('trax_volume', event.target.value) } onMouseUp={ () => saveRangeSlider('volume') }/> - - - - - - - ); -} diff --git a/src/components/wired/WiredView.scss b/src/components/wired/WiredView.scss deleted file mode 100644 index 06569ad..0000000 --- a/src/components/wired/WiredView.scss +++ /dev/null @@ -1,175 +0,0 @@ -.nitro-wired { - width: 300px; - - .icon { - background-repeat: no-repeat; - background-position: center; - - &.icon-mv-1 { - width: 16px; - height: 9px; - background-image: url('@/assets/images/wired/icon_wired_around.png'); - } - &.icon-mv-2 { - width: 16px; - height: 9px; - background-image: url('@/assets/images/wired/icon_wired_up_down.png'); - } - &.icon-mv-3 { - width: 16px; - height: 9px; - background-image: url('@/assets/images/wired/icon_wired_left_right.png'); - } - &.icon-ne { - width: 16px; - height: 9px; - background-image: url('@/assets/images/wired/icon_wired_north_east.png'); - } - &.icon-se { - width: 16px; - height: 9px; - background-image: url('@/assets/images/wired/icon_wired_south_east.png'); - } - &.icon-sw { - width: 16px; - height: 9px; - background-image: url('@/assets/images/wired/icon_wired_south_west.png'); - } - &.icon-nw { - width: 16px; - height: 9px; - background-image: url('@/assets/images/wired/icon_wired_north_west.png'); - } - &.icon-rot-1 { - width: 16px; - height: 9px; - background-image: url('@/assets/images/wired/icon_wired_rotate_clockwise.png'); - } - &.icon-rot-2 { - width: 16px; - height: 9px; - background-image: url('@/assets/images/wired/icon_wired_rotate_counter_clockwise.png'); - } - } - - .nitro-wired-header { - color: #000; - margin-bottom:3px; - - .nitro-wired-title, .nitro-wired-close { - border:1px solid rgba($black,.8); - background-image: linear-gradient(45deg, #00d9cb 25%, #00bdb0 25%, #00bdb0 50%, #00d9cb 50%, #00d9cb 75%, #00bdb0 75%, #00bdb0 100%); - background-size: 197.99px 197.99px; - animation: wiredSlider 3s linear infinite; - text-align: center; - box-shadow:inset 0 0 0 2px rgba($white,.6), 0 2px rgba($black,.4); - } - - .nitro-wired-title { - margin-right:3px; - } - - .nitro-wired-close { - min-width: 23px; - } - } - - &.nitro-wired-trigger { - background-color: #3b2516 !important; - border: 1px solid #000 !important; - box-shadow: inset 0px -2px #50321f, - inset 0px -3px #86583b, - inset 0 0 0 1px #86583b, - inset 0 0 0 3px #644029, - inset 0 0 0 4px rgba($black,.4) !important; - - .bg-light,.bg-primary { - background-color: transparent !important; - } - - .bg-dark { - background-color: #000 !important; - } - } - - &.nitro-wired-action { - background-color: #686868 !important; - border: 1px solid #000 !important; - box-shadow: inset 0px -2px #9d9d9d, - inset 0px -3px #c5c5c5, - inset 0 0 0 1px #c5c5c5, - inset 0 0 0 3px #9d9d9d, - inset 0 0 0 4px rgba($black,.4) !important; - - .bg-light,.bg-primary { - background-color: transparent !important; - } - - .bg-dark { - background-color: #000 !important; - } - - &::before, - &::after, - .content-area::before, - .content-area::after { - content: ''; - height: 6px; - width: 6px; - position: absolute; - background-image: url('@/assets/images/wired/card-action-corners.png'); - } - - &::before { - background-position: 0 0; - top: 0; - left: 0; - } - - &::after { - background-position: 6px 0; - top: 0; - right: 0; - } - - .content-area { - &::before { - background-position: 0 6px; - bottom: 0; - left: 0; - } - - &::after { - background-position: 6px 6px; - bottom: 0; - right: 0; - } - } - } - - &.nitro-wired-condition { - background-color: #cfd2dd !important; - border: 1px solid #000 !important; - box-shadow: inset 0 0 0 3px #efefef, inset 4px 4px #abaeb9 !important; - color: #000; - - .bg-light,.bg-primary { - background-color: transparent !important; - } - - .bg-dark { - background-color: #000 !important; - } - } -} - - -@keyframes wiredSlider { - 0% { - background-position: 0 0; - } - - 100% { - background-position: 0 -197.99px; - } -} diff --git a/src/components/wired/WiredView.tsx b/src/components/wired/WiredView.tsx deleted file mode 100644 index cb3b4ba..0000000 --- a/src/components/wired/WiredView.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { ConditionDefinition, TriggerDefinition, WiredActionDefinition } from '@nitrots/nitro-renderer'; -import { FC } from 'react'; -import { useWired } from '../../hooks'; -import { WiredActionLayoutView } from './views/actions/WiredActionLayoutView'; -import { WiredConditionLayoutView } from './views/conditions/WiredConditionLayoutView'; -import { WiredTriggerLayoutView } from './views/triggers/WiredTriggerLayoutView'; - -export const WiredView: FC<{}> = props => -{ - const { trigger = null } = useWired(); - - if(!trigger) return null; - - if(trigger instanceof WiredActionDefinition) return WiredActionLayoutView(trigger.code); - - if(trigger instanceof TriggerDefinition) return WiredTriggerLayoutView(trigger.code); - - if(trigger instanceof ConditionDefinition) return WiredConditionLayoutView(trigger.code); - - return null; -}; diff --git a/src/components/wired/views/WiredBaseView.tsx b/src/components/wired/views/WiredBaseView.tsx deleted file mode 100644 index df5adc1..0000000 --- a/src/components/wired/views/WiredBaseView.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { GetSessionDataManager } from '@nitrots/nitro-renderer'; -import { FC, PropsWithChildren, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType, WiredSelectionVisualizer } from '../../../api'; -import { Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common'; -import { useWired } from '../../../hooks'; -import { WiredFurniSelectorView } from './WiredFurniSelectorView'; - -export interface WiredBaseViewProps -{ - wiredType: string; - requiresFurni: number; - hasSpecialInput: boolean; - save: () => void; - validate?: () => boolean; -} - -export const WiredBaseView: FC> = props => -{ - const { wiredType = '', requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, validate = null, children = null, hasSpecialInput = false } = props; - const [ wiredName, setWiredName ] = useState(null); - const [ wiredDescription, setWiredDescription ] = useState(null); - const [ needsSave, setNeedsSave ] = useState(false); - const { trigger = null, setTrigger = null, setIntParams = null, setStringParam = null, setFurniIds = null, setAllowsFurni = null, saveWired = null } = useWired(); - - const onClose = () => setTrigger(null); - - const onSave = () => - { - if(validate && !validate()) return; - - if(save) save(); - - setNeedsSave(true); - } - - useEffect(() => - { - if(!needsSave) return; - - saveWired(); - - setNeedsSave(false); - }, [ needsSave, saveWired ]); - - useEffect(() => - { - if(!trigger) return; - - const spriteId = (trigger.spriteId || -1); - const furniData = GetSessionDataManager().getFloorItemData(spriteId); - - if(!furniData) - { - setWiredName(('NAME: ' + spriteId)); - setWiredDescription(('NAME: ' + spriteId)); - } - else - { - setWiredName(furniData.name); - setWiredDescription(furniData.description); - } - - if(hasSpecialInput) - { - setIntParams(trigger.intData); - setStringParam(trigger.stringData); - } - - if(requiresFurni > WiredFurniType.STUFF_SELECTION_OPTION_NONE) - { - setFurniIds(prevValue => - { - if(prevValue && prevValue.length) WiredSelectionVisualizer.clearSelectionShaderFromFurni(prevValue); - - if(trigger.selectedItems && trigger.selectedItems.length) - { - WiredSelectionVisualizer.applySelectionShaderToFurni(trigger.selectedItems); - - return trigger.selectedItems; - } - - return []; - }); - } - - setAllowsFurni(requiresFurni); - }, [ trigger, hasSpecialInput, requiresFurni, setIntParams, setStringParam, setFurniIds, setAllowsFurni ]); - - return ( - - - - - - - { wiredName } - - { wiredDescription } - - { !!children &&
} - { children } - { (requiresFurni > WiredFurniType.STUFF_SELECTION_OPTION_NONE) && - <> -
- - } - - - - -
-
- ); -} diff --git a/src/components/wired/views/WiredFurniSelectorView.tsx b/src/components/wired/views/WiredFurniSelectorView.tsx deleted file mode 100644 index 9b38f97..0000000 --- a/src/components/wired/views/WiredFurniSelectorView.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { FC } from 'react'; -import { LocalizeText } from '../../../api'; -import { Column, Text } from '../../../common'; -import { useWired } from '../../../hooks'; - -export const WiredFurniSelectorView: FC<{}> = props => -{ - const { trigger = null, furniIds = [] } = useWired(); - - return ( - - { LocalizeText('wiredfurni.pickfurnis.caption', [ 'count', 'limit' ], [ furniIds.length.toString(), trigger.maximumItemSelectionCount.toString() ]) } - { LocalizeText('wiredfurni.pickfurnis.desc') } - - ); -} diff --git a/src/components/wired/views/actions/WiredActionBaseView.tsx b/src/components/wired/views/actions/WiredActionBaseView.tsx deleted file mode 100644 index 6c7a86e..0000000 --- a/src/components/wired/views/actions/WiredActionBaseView.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { WiredActionDefinition } from '@nitrots/nitro-renderer'; -import { FC, PropsWithChildren, useEffect } from 'react'; -import ReactSlider from 'react-slider'; -import { GetWiredTimeLocale, LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredBaseView } from '../WiredBaseView'; - -export interface WiredActionBaseViewProps -{ - hasSpecialInput: boolean; - requiresFurni: number; - save: () => void; -} - -export const WiredActionBaseView: FC> = props => -{ - const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, hasSpecialInput = false, children = null } = props; - const { trigger = null, actionDelay = 0, setActionDelay = null } = useWired(); - - useEffect(() => - { - setActionDelay((trigger as WiredActionDefinition).delayInPulses); - }, [ trigger, setActionDelay ]); - - return ( - - { children } - { !!children &&
} - - { LocalizeText('wiredfurni.params.delay', [ 'seconds' ], [ GetWiredTimeLocale(actionDelay) ]) } - setActionDelay(event) } /> - -
- ); -} diff --git a/src/components/wired/views/actions/WiredActionBotChangeFigureView.tsx b/src/components/wired/views/actions/WiredActionBotChangeFigureView.tsx deleted file mode 100644 index 783e00a..0000000 --- a/src/components/wired/views/actions/WiredActionBotChangeFigureView.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { GetSessionDataManager } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WIRED_STRING_DELIMETER, WiredFurniType } from '../../../../api'; -import { Button, Column, Flex, LayoutAvatarImageView, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -const DEFAULT_FIGURE: string = 'hd-180-1.ch-210-66.lg-270-82.sh-290-81'; - -export const WiredActionBotChangeFigureView: FC<{}> = props => -{ - const [ botName, setBotName ] = useState(''); - const [ figure, setFigure ] = useState(''); - const { trigger = null, setStringParam = null } = useWired(); - - const save = () => setStringParam((botName + WIRED_STRING_DELIMETER + figure)); - - useEffect(() => - { - const data = trigger.stringData.split(WIRED_STRING_DELIMETER); - - if(data.length > 0) setBotName(data[0]); - if(data.length > 1) setFigure(data[1].length > 0 ? data[1] : DEFAULT_FIGURE); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.bot.name') } - setBotName(event.target.value) } /> - - - - - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionBotFollowAvatarView.tsx b/src/components/wired/views/actions/WiredActionBotFollowAvatarView.tsx deleted file mode 100644 index 2acb5cc..0000000 --- a/src/components/wired/views/actions/WiredActionBotFollowAvatarView.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionBotFollowAvatarView: FC<{}> = props => -{ - const [ botName, setBotName ] = useState(''); - const [ followMode, setFollowMode ] = useState(-1); - const { trigger = null, setStringParam = null, setIntParams = null } = useWired(); - - const save = () => - { - setStringParam(botName); - setIntParams([ followMode ]); - } - - useEffect(() => - { - setBotName(trigger.stringData); - setFollowMode((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.bot.name') } - setBotName(event.target.value) } /> - - - - setFollowMode(1) } /> - { LocalizeText('wiredfurni.params.start.following') } - - - setFollowMode(0) } /> - { LocalizeText('wiredfurni.params.stop.following') } - - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionBotGiveHandItemView.tsx b/src/components/wired/views/actions/WiredActionBotGiveHandItemView.tsx deleted file mode 100644 index c93d0de..0000000 --- a/src/components/wired/views/actions/WiredActionBotGiveHandItemView.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -const ALLOWED_HAND_ITEM_IDS: number[] = [ 2, 5, 7, 8, 9, 10, 27 ]; - -export const WiredActionBotGiveHandItemView: FC<{}> = props => -{ - const [ botName, setBotName ] = useState(''); - const [ handItemId, setHandItemId ] = useState(-1); - const { trigger = null, setStringParam = null, setIntParams = null } = useWired(); - - const save = () => - { - setStringParam(botName); - setIntParams([ handItemId ]); - } - - useEffect(() => - { - setBotName(trigger.stringData); - setHandItemId((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.bot.name') } - setBotName(event.target.value) } /> - - - { LocalizeText('wiredfurni.params.handitem') } - - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionBotMoveView.tsx b/src/components/wired/views/actions/WiredActionBotMoveView.tsx deleted file mode 100644 index d09a359..0000000 --- a/src/components/wired/views/actions/WiredActionBotMoveView.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionBotMoveView: FC<{}> = props => -{ - const [ botName, setBotName ] = useState(''); - const { trigger = null, setStringParam = null } = useWired(); - - const save = () => setStringParam(botName); - - useEffect(() => - { - setBotName(trigger.stringData); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.bot.name') } - setBotName(event.target.value) } /> - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionBotTalkToAvatarView.tsx b/src/components/wired/views/actions/WiredActionBotTalkToAvatarView.tsx deleted file mode 100644 index d32cc17..0000000 --- a/src/components/wired/views/actions/WiredActionBotTalkToAvatarView.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { GetConfigurationValue, LocalizeText, WIRED_STRING_DELIMETER, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionBotTalkToAvatarView: FC<{}> = props => -{ - const [ botName, setBotName ] = useState(''); - const [ message, setMessage ] = useState(''); - const [ talkMode, setTalkMode ] = useState(-1); - const { trigger = null, setStringParam = null, setIntParams = null } = useWired(); - - const save = () => - { - setStringParam(botName + WIRED_STRING_DELIMETER + message); - setIntParams([ talkMode ]); - } - - useEffect(() => - { - const data = trigger.stringData.split(WIRED_STRING_DELIMETER); - - if(data.length > 0) setBotName(data[0]); - if(data.length > 1) setMessage(data[1].length > 0 ? data[1] : ''); - - setTalkMode((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.bot.name') } - setBotName(event.target.value) } /> - - - { LocalizeText('wiredfurni.params.message') } - ('wired.action.bot.talk.to.avatar.max.length', 64) } value={ message } onChange={ event => setMessage(event.target.value) } /> - - - - setTalkMode(0) } /> - { LocalizeText('wiredfurni.params.talk') } - - - setTalkMode(1) } /> - { LocalizeText('wiredfurni.params.whisper') } - - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionBotTalkView.tsx b/src/components/wired/views/actions/WiredActionBotTalkView.tsx deleted file mode 100644 index 18e6467..0000000 --- a/src/components/wired/views/actions/WiredActionBotTalkView.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { GetConfigurationValue, LocalizeText, WIRED_STRING_DELIMETER, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionBotTalkView: FC<{}> = props => -{ - const [ botName, setBotName ] = useState(''); - const [ message, setMessage ] = useState(''); - const [ talkMode, setTalkMode ] = useState(-1); - const { trigger = null, setStringParam = null, setIntParams = null } = useWired(); - - const save = () => - { - setStringParam(botName + WIRED_STRING_DELIMETER + message); - setIntParams([ talkMode ]); - } - - useEffect(() => - { - const data = trigger.stringData.split(WIRED_STRING_DELIMETER); - - if(data.length > 0) setBotName(data[0]); - if(data.length > 1) setMessage(data[1].length > 0 ? data[1] : ''); - - setTalkMode((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.bot.name') } - setBotName(event.target.value) } /> - - - { LocalizeText('wiredfurni.params.message') } - ('wired.action.bot.talk.max.length', 64) } value={ message } onChange={ event => setMessage(event.target.value) } /> - - - - setTalkMode(0) } /> - { LocalizeText('wiredfurni.params.talk') } - - - setTalkMode(1) } /> - { LocalizeText('wiredfurni.params.shout') } - - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionBotTeleportView.tsx b/src/components/wired/views/actions/WiredActionBotTeleportView.tsx deleted file mode 100644 index 5d767b1..0000000 --- a/src/components/wired/views/actions/WiredActionBotTeleportView.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionBotTeleportView: FC<{}> = props => -{ - const [ botName, setBotName ] = useState(''); - const { trigger = null, setStringParam = null } = useWired(); - - const save = () => setStringParam(botName); - - useEffect(() => - { - setBotName(trigger.stringData); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.bot.name') } - setBotName(event.target.value) } /> - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionCallAnotherStackView.tsx b/src/components/wired/views/actions/WiredActionCallAnotherStackView.tsx deleted file mode 100644 index ee6d547..0000000 --- a/src/components/wired/views/actions/WiredActionCallAnotherStackView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionCallAnotherStackView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/actions/WiredActionChaseView.tsx b/src/components/wired/views/actions/WiredActionChaseView.tsx deleted file mode 100644 index c494503..0000000 --- a/src/components/wired/views/actions/WiredActionChaseView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionChaseView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/actions/WiredActionChatView.tsx b/src/components/wired/views/actions/WiredActionChatView.tsx deleted file mode 100644 index 62d9519..0000000 --- a/src/components/wired/views/actions/WiredActionChatView.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { GetConfigurationValue, LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionChatView: FC<{}> = props => -{ - const [ message, setMessage ] = useState(''); - const { trigger = null, setStringParam = null } = useWired(); - - const save = () => setStringParam(message); - - useEffect(() => - { - setMessage(trigger.stringData); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.message') } - setMessage(event.target.value) } maxLength={ GetConfigurationValue('wired.action.chat.max.length', 100) } /> - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionFleeView.tsx b/src/components/wired/views/actions/WiredActionFleeView.tsx deleted file mode 100644 index a80ab43..0000000 --- a/src/components/wired/views/actions/WiredActionFleeView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionFleeView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/actions/WiredActionGiveRewardView.tsx b/src/components/wired/views/actions/WiredActionGiveRewardView.tsx deleted file mode 100644 index a255fe3..0000000 --- a/src/components/wired/views/actions/WiredActionGiveRewardView.tsx +++ /dev/null @@ -1,160 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { FaPlus, FaTrash } from 'react-icons/fa'; -import ReactSlider from 'react-slider'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Button, Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionGiveRewardView: FC<{}> = props => -{ - const [ limitEnabled, setLimitEnabled ] = useState(false); - const [ rewardTime, setRewardTime ] = useState(1); - const [ uniqueRewards, setUniqueRewards ] = useState(false); - const [ rewardsLimit, setRewardsLimit ] = useState(1); - const [ limitationInterval, setLimitationInterval ] = useState(1); - const [ rewards, setRewards ] = useState<{ isBadge: boolean, itemCode: string, probability: number }[]>([]); - const { trigger = null, setIntParams = null, setStringParam = null } = useWired(); - - const addReward = () => setRewards(rewards => [ ...rewards, { isBadge: false, itemCode: '', probability: null } ]); - - const removeReward = (index: number) => - { - setRewards(prevValue => - { - const newValues = Array.from(prevValue); - - newValues.splice(index, 1); - - return newValues; - }); - } - - const updateReward = (index: number, isBadge: boolean, itemCode: string, probability: number) => - { - const rewardsClone = Array.from(rewards); - const reward = rewardsClone[index]; - - if(!reward) return; - - reward.isBadge = isBadge; - reward.itemCode = itemCode; - reward.probability = probability; - - setRewards(rewardsClone); - } - - const save = () => - { - let stringRewards = []; - - for(const reward of rewards) - { - if(!reward.itemCode) continue; - - const rewardsString = [ reward.isBadge ? '0' : '1', reward.itemCode, reward.probability.toString() ]; - stringRewards.push(rewardsString.join(',')); - } - - if(stringRewards.length > 0) - { - setStringParam(stringRewards.join(';')); - setIntParams([ rewardTime, uniqueRewards ? 1 : 0, rewardsLimit, limitationInterval ]); - } - } - - useEffect(() => - { - const readRewards: { isBadge: boolean, itemCode: string, probability: number }[] = []; - - if(trigger.stringData.length > 0 && trigger.stringData.includes(';')) - { - const splittedRewards = trigger.stringData.split(';'); - - for(const rawReward of splittedRewards) - { - const reward = rawReward.split(','); - - if(reward.length !== 3) continue; - - readRewards.push({ isBadge: reward[0] === '0', itemCode: reward[1], probability: Number(reward[2]) }); - } - } - - if(readRewards.length === 0) readRewards.push({ isBadge: false, itemCode: '', probability: null }); - - setRewardTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); - setUniqueRewards((trigger.intData.length > 1) ? (trigger.intData[1] === 1) : false); - setRewardsLimit((trigger.intData.length > 2) ? trigger.intData[2] : 0); - setLimitationInterval((trigger.intData.length > 3) ? trigger.intData[3] : 0); - setLimitEnabled((trigger.intData.length > 3) ? trigger.intData[3] > 0 : false); - setRewards(readRewards); - }, [ trigger ]); - - return ( - - - setLimitEnabled(event.target.checked) } /> - { LocalizeText('wiredfurni.params.prizelimit', [ 'amount' ], [ limitEnabled ? rewardsLimit.toString() : '' ]) } - - { !limitEnabled && - - Reward limit not set. Make sure rewards are badges or non-tradeable items. - } - { limitEnabled && - setRewardsLimit(event) } /> } -
- - How often can a user be rewarded? - - - { (rewardTime > 0) && setLimitationInterval(Number(event.target.value)) } /> } - - -
- - setUniqueRewards(e.target.checked) } /> - Unique rewards - - - If checked each reward will be given once to each user. This will disable the probabilities option. - -
- - Rewards - - - - { rewards && rewards.map((reward, index) => - { - return ( - - - updateReward(index, e.target.checked, reward.itemCode, reward.probability) } /> - Badge? - - updateReward(index, reward.isBadge, e.target.value, reward.probability) } placeholder="Item Code" /> - updateReward(index, reward.isBadge, reward.itemCode, Number(e.target.value)) } placeholder="Probability" /> - { (index > 0) && - } - - ) - }) } - -
- ); -} diff --git a/src/components/wired/views/actions/WiredActionGiveScoreToPredefinedTeamView.tsx b/src/components/wired/views/actions/WiredActionGiveScoreToPredefinedTeamView.tsx deleted file mode 100644 index 43ab240..0000000 --- a/src/components/wired/views/actions/WiredActionGiveScoreToPredefinedTeamView.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionGiveScoreToPredefinedTeamView: FC<{}> = props => -{ - const [ points, setPoints ] = useState(1); - const [ time, setTime ] = useState(1); - const [ selectedTeam, setSelectedTeam ] = useState(1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ points, time, selectedTeam ]); - - useEffect(() => - { - if(trigger.intData.length >= 2) - { - setPoints(trigger.intData[0]); - setTime(trigger.intData[1]); - setSelectedTeam(trigger.intData[2]); - } - else - { - setPoints(1); - setTime(1); - setSelectedTeam(1); - } - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.setpoints', [ 'points' ], [ points.toString() ]) } - setPoints(event) } /> - - - { LocalizeText('wiredfurni.params.settimesingame', [ 'times' ], [ time.toString() ]) } - setTime(event) } /> - - - { LocalizeText('wiredfurni.params.team') } - { [ 1, 2, 3, 4 ].map(value => - { - return ( - - setSelectedTeam(value) } /> - { LocalizeText('wiredfurni.params.team.' + value) } - - ); - }) } - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionGiveScoreView.tsx b/src/components/wired/views/actions/WiredActionGiveScoreView.tsx deleted file mode 100644 index 28bfb0b..0000000 --- a/src/components/wired/views/actions/WiredActionGiveScoreView.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionGiveScoreView: FC<{}> = props => -{ - const [ points, setPoints ] = useState(1); - const [ time, setTime ] = useState(1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ points, time ]); - - useEffect(() => - { - if(trigger.intData.length >= 2) - { - setPoints(trigger.intData[0]); - setTime(trigger.intData[1]); - } - else - { - setPoints(1); - setTime(1); - } - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.setpoints', [ 'points' ], [ points.toString() ]) } - setPoints(event) } /> - - - { LocalizeText('wiredfurni.params.settimesingame', [ 'times' ], [ time.toString() ]) } - setTime(event) } /> - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionJoinTeamView.tsx b/src/components/wired/views/actions/WiredActionJoinTeamView.tsx deleted file mode 100644 index 7580564..0000000 --- a/src/components/wired/views/actions/WiredActionJoinTeamView.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionJoinTeamView: FC<{}> = props => -{ - const [ selectedTeam, setSelectedTeam ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ selectedTeam ]); - - useEffect(() => - { - setSelectedTeam((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.team') } - { [ 1, 2, 3, 4 ].map(team => - { - return ( - - setSelectedTeam(team) } /> - { LocalizeText(`wiredfurni.params.team.${ team }`) } - - ) - }) } - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionKickFromRoomView.tsx b/src/components/wired/views/actions/WiredActionKickFromRoomView.tsx deleted file mode 100644 index ba6033f..0000000 --- a/src/components/wired/views/actions/WiredActionKickFromRoomView.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { GetConfigurationValue, LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionKickFromRoomView: FC<{}> = props => -{ - const [ message, setMessage ] = useState(''); - const { trigger = null, setStringParam = null } = useWired(); - - const save = () => setStringParam(message); - - useEffect(() => - { - setMessage(trigger.stringData); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.message') } - setMessage(event.target.value) } maxLength={ GetConfigurationValue('wired.action.kick.from.room.max.length', 100) } /> - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionLayoutView.tsx b/src/components/wired/views/actions/WiredActionLayoutView.tsx deleted file mode 100644 index f43666a..0000000 --- a/src/components/wired/views/actions/WiredActionLayoutView.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { WiredActionLayoutCode } from '../../../../api'; -import { WiredActionBotChangeFigureView } from './WiredActionBotChangeFigureView'; -import { WiredActionBotFollowAvatarView } from './WiredActionBotFollowAvatarView'; -import { WiredActionBotGiveHandItemView } from './WiredActionBotGiveHandItemView'; -import { WiredActionBotMoveView } from './WiredActionBotMoveView'; -import { WiredActionBotTalkToAvatarView } from './WiredActionBotTalkToAvatarView'; -import { WiredActionBotTalkView } from './WiredActionBotTalkView'; -import { WiredActionBotTeleportView } from './WiredActionBotTeleportView'; -import { WiredActionCallAnotherStackView } from './WiredActionCallAnotherStackView'; -import { WiredActionChaseView } from './WiredActionChaseView'; -import { WiredActionChatView } from './WiredActionChatView'; -import { WiredActionFleeView } from './WiredActionFleeView'; -import { WiredActionGiveRewardView } from './WiredActionGiveRewardView'; -import { WiredActionGiveScoreToPredefinedTeamView } from './WiredActionGiveScoreToPredefinedTeamView'; -import { WiredActionGiveScoreView } from './WiredActionGiveScoreView'; -import { WiredActionJoinTeamView } from './WiredActionJoinTeamView'; -import { WiredActionKickFromRoomView } from './WiredActionKickFromRoomView'; -import { WiredActionLeaveTeamView } from './WiredActionLeaveTeamView'; -import { WiredActionMoveAndRotateFurniView } from './WiredActionMoveAndRotateFurniView'; -import { WiredActionMoveFurniToView } from './WiredActionMoveFurniToView'; -import { WiredActionMoveFurniView } from './WiredActionMoveFurniView'; -import { WiredActionMuteUserView } from './WiredActionMuteUserView'; -import { WiredActionResetView } from './WiredActionResetView'; -import { WiredActionSetFurniStateToView } from './WiredActionSetFurniStateToView'; -import { WiredActionTeleportView } from './WiredActionTeleportView'; -import { WiredActionToggleFurniStateView } from './WiredActionToggleFurniStateView'; - -export const WiredActionLayoutView = (code: number) => -{ - switch(code) - { - case WiredActionLayoutCode.BOT_CHANGE_FIGURE: - return ; - case WiredActionLayoutCode.BOT_FOLLOW_AVATAR: - return ; - case WiredActionLayoutCode.BOT_GIVE_HAND_ITEM: - return ; - case WiredActionLayoutCode.BOT_MOVE: - return ; - case WiredActionLayoutCode.BOT_TALK: - return ; - case WiredActionLayoutCode.BOT_TALK_DIRECT_TO_AVTR: - return ; - case WiredActionLayoutCode.BOT_TELEPORT: - return ; - case WiredActionLayoutCode.CALL_ANOTHER_STACK: - return ; - case WiredActionLayoutCode.CHASE: - return ; - case WiredActionLayoutCode.CHAT: - return ; - case WiredActionLayoutCode.FLEE: - return ; - case WiredActionLayoutCode.GIVE_REWARD: - return ; - case WiredActionLayoutCode.GIVE_SCORE: - return ; - case WiredActionLayoutCode.GIVE_SCORE_TO_PREDEFINED_TEAM: - return ; - case WiredActionLayoutCode.JOIN_TEAM: - return ; - case WiredActionLayoutCode.KICK_FROM_ROOM: - return ; - case WiredActionLayoutCode.LEAVE_TEAM: - return ; - case WiredActionLayoutCode.MOVE_FURNI: - return ; - case WiredActionLayoutCode.MOVE_AND_ROTATE_FURNI: - return ; - case WiredActionLayoutCode.MOVE_FURNI_TO: - return ; - case WiredActionLayoutCode.MUTE_USER: - return ; - case WiredActionLayoutCode.RESET: - return ; - case WiredActionLayoutCode.SET_FURNI_STATE: - return ; - case WiredActionLayoutCode.TELEPORT: - return ; - case WiredActionLayoutCode.TOGGLE_FURNI_STATE: - return ; - } - - return null; -} diff --git a/src/components/wired/views/actions/WiredActionLeaveTeamView.tsx b/src/components/wired/views/actions/WiredActionLeaveTeamView.tsx deleted file mode 100644 index eaa834f..0000000 --- a/src/components/wired/views/actions/WiredActionLeaveTeamView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionLeaveTeamView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/actions/WiredActionMoveAndRotateFurniView.tsx b/src/components/wired/views/actions/WiredActionMoveAndRotateFurniView.tsx deleted file mode 100644 index 62801af..0000000 --- a/src/components/wired/views/actions/WiredActionMoveAndRotateFurniView.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -const directionOptions: { value: number, icon: string }[] = [ - { - value: 0, - icon: 'ne' - }, - { - value: 2, - icon: 'se' - }, - { - value: 4, - icon: 'sw' - }, - { - value: 6, - icon: 'nw' - } -]; - -const rotationOptions: number[] = [ 0, 1, 2, 3, 4, 5, 6 ]; - -export const WiredActionMoveAndRotateFurniView: FC<{}> = props => -{ - const [ movement, setMovement ] = useState(-1); - const [ rotation, setRotation ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ movement, rotation ]); - - useEffect(() => - { - if(trigger.intData.length >= 2) - { - setMovement(trigger.intData[0]); - setRotation(trigger.intData[1]); - } - else - { - setMovement(-1); - setRotation(-1); - } - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.startdir') } - - { directionOptions.map(option => - { - return ( - - setMovement(option.value) } /> - - - - - ) - }) } - - - - { LocalizeText('wiredfurni.params.turn') } - { rotationOptions.map(option => - { - return ( - - setRotation(option) } /> - { LocalizeText(`wiredfurni.params.turn.${ option }`) } - - ) - }) } - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionMoveFurniToView.tsx b/src/components/wired/views/actions/WiredActionMoveFurniToView.tsx deleted file mode 100644 index 56bdb6b..0000000 --- a/src/components/wired/views/actions/WiredActionMoveFurniToView.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -const directionOptions: { value: number, icon: string }[] = [ - { - value: 0, - icon: 'ne' - }, - { - value: 2, - icon: 'se' - }, - { - value: 4, - icon: 'sw' - }, - { - value: 6, - icon: 'nw' - } -]; - -export const WiredActionMoveFurniToView: FC<{}> = props => -{ - const [ spacing, setSpacing ] = useState(-1); - const [ movement, setMovement ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ movement, spacing ]); - - useEffect(() => - { - if(trigger.intData.length >= 2) - { - setSpacing(trigger.intData[1]); - setMovement(trigger.intData[0]); - } - else - { - setSpacing(-1); - setMovement(-1); - } - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.emptytiles', [ 'tiles' ], [ spacing.toString() ]) } - setSpacing(event) } /> - - - { LocalizeText('wiredfurni.params.startdir') } - - { directionOptions.map(value => - { - return ( - - setMovement(value.value) } /> - - - ) - }) } - - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionMoveFurniView.tsx b/src/components/wired/views/actions/WiredActionMoveFurniView.tsx deleted file mode 100644 index b5a0888..0000000 --- a/src/components/wired/views/actions/WiredActionMoveFurniView.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -const directionOptions: { value: number, icon: string }[] = [ - { - value: 4, - icon: 'ne' - }, - { - value: 5, - icon: 'se' - }, - { - value: 6, - icon: 'sw' - }, - { - value: 7, - icon: 'nw' - }, - { - value: 2, - icon: 'mv-2' - }, - { - value: 3, - icon: 'mv-3' - }, - { - value: 1, - icon: 'mv-1' - } -]; - -const rotationOptions: number[] = [ 0, 1, 2, 3 ]; - -export const WiredActionMoveFurniView: FC<{}> = props => -{ - const [ movement, setMovement ] = useState(-1); - const [ rotation, setRotation ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ movement, rotation ]); - - useEffect(() => - { - if(trigger.intData.length >= 2) - { - setMovement(trigger.intData[0]); - setRotation(trigger.intData[1]); - } - else - { - setMovement(-1); - setRotation(-1); - } - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.movefurni') } - - setMovement(0) } /> - { LocalizeText('wiredfurni.params.movefurni.0') } - - - { directionOptions.map(option => - { - return ( - - setMovement(option.value) } /> - - - ) - }) } -
- - - - { LocalizeText('wiredfurni.params.rotatefurni') } - { rotationOptions.map(option => - { - return ( - - setRotation(option) } /> - - { [ 1, 2 ].includes(option) && } - { LocalizeText(`wiredfurni.params.rotatefurni.${ option }`) } - - - ) - }) } - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionMuteUserView.tsx b/src/components/wired/views/actions/WiredActionMuteUserView.tsx deleted file mode 100644 index 15ecfd5..0000000 --- a/src/components/wired/views/actions/WiredActionMuteUserView.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { GetConfigurationValue, LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionMuteUserView: FC<{}> = props => -{ - const [ time, setTime ] = useState(-1); - const [ message, setMessage ] = useState(''); - const { trigger = null, setIntParams = null, setStringParam = null } = useWired(); - - const save = () => - { - setIntParams([ time ]); - setStringParam(message); - } - - useEffect(() => - { - setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); - setMessage(trigger.stringData); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.length.minutes', [ 'minutes' ], [ time.toString() ]) } - setTime(event) } /> - - - { LocalizeText('wiredfurni.params.message') } - setMessage(event.target.value) } maxLength={ GetConfigurationValue('wired.action.mute.user.max.length', 100) } /> - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionResetView.tsx b/src/components/wired/views/actions/WiredActionResetView.tsx deleted file mode 100644 index 9245c67..0000000 --- a/src/components/wired/views/actions/WiredActionResetView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionResetView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/actions/WiredActionSetFurniStateToView.tsx b/src/components/wired/views/actions/WiredActionSetFurniStateToView.tsx deleted file mode 100644 index 587254c..0000000 --- a/src/components/wired/views/actions/WiredActionSetFurniStateToView.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionSetFurniStateToView: FC<{}> = props => -{ - const [ stateFlag, setStateFlag ] = useState(0); - const [ directionFlag, setDirectionFlag ] = useState(0); - const [ positionFlag, setPositionFlag ] = useState(0); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ stateFlag, directionFlag, positionFlag ]); - - useEffect(() => - { - setStateFlag(trigger.getBoolean(0) ? 1 : 0); - setDirectionFlag(trigger.getBoolean(1) ? 1 : 0); - setPositionFlag(trigger.getBoolean(2) ? 1 : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.conditions') } - - setStateFlag(event.target.checked ? 1 : 0) } /> - { LocalizeText('wiredfurni.params.condition.state') } - - - setDirectionFlag(event.target.checked ? 1 : 0) } /> - { LocalizeText('wiredfurni.params.condition.direction') } - - - setPositionFlag(event.target.checked ? 1 : 0) } /> - { LocalizeText('wiredfurni.params.condition.position') } - - - - ); -} diff --git a/src/components/wired/views/actions/WiredActionTeleportView.tsx b/src/components/wired/views/actions/WiredActionTeleportView.tsx deleted file mode 100644 index 652da61..0000000 --- a/src/components/wired/views/actions/WiredActionTeleportView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionTeleportView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/actions/WiredActionToggleFurniStateView.tsx b/src/components/wired/views/actions/WiredActionToggleFurniStateView.tsx deleted file mode 100644 index 37b5d2e..0000000 --- a/src/components/wired/views/actions/WiredActionToggleFurniStateView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredActionBaseView } from './WiredActionBaseView'; - -export const WiredActionToggleFurniStateView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/conditions/WiredConditionActorHasHandItem.tsx b/src/components/wired/views/conditions/WiredConditionActorHasHandItem.tsx deleted file mode 100644 index 24e89ed..0000000 --- a/src/components/wired/views/conditions/WiredConditionActorHasHandItem.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -const ALLOWED_HAND_ITEM_IDS: number[] = [ 2, 5, 7, 8, 9, 10, 27 ]; - -export const WiredConditionActorHasHandItemView: FC<{}> = props => -{ - const [ handItemId, setHandItemId ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ handItemId ]); - - useEffect(() => - { - setHandItemId((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.handitem') } - - - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionActorIsGroupMemberView.tsx b/src/components/wired/views/conditions/WiredConditionActorIsGroupMemberView.tsx deleted file mode 100644 index e278eab..0000000 --- a/src/components/wired/views/conditions/WiredConditionActorIsGroupMemberView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionActorIsGroupMemberView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/conditions/WiredConditionActorIsOnFurniView.tsx b/src/components/wired/views/conditions/WiredConditionActorIsOnFurniView.tsx deleted file mode 100644 index 10cddf5..0000000 --- a/src/components/wired/views/conditions/WiredConditionActorIsOnFurniView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionActorIsOnFurniView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/conditions/WiredConditionActorIsTeamMemberView.tsx b/src/components/wired/views/conditions/WiredConditionActorIsTeamMemberView.tsx deleted file mode 100644 index 20db3ac..0000000 --- a/src/components/wired/views/conditions/WiredConditionActorIsTeamMemberView.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -const teamIds: number[] = [ 1, 2, 3, 4 ]; - -export const WiredConditionActorIsTeamMemberView: FC<{}> = props => -{ - const [ selectedTeam, setSelectedTeam ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ selectedTeam ]); - - useEffect(() => - { - setSelectedTeam((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.team') } - { teamIds.map(value => - { - return ( - - setSelectedTeam(value) } /> - { LocalizeText(`wiredfurni.params.team.${ value }`) } - - ) - }) } - - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionActorIsWearingBadgeView.tsx b/src/components/wired/views/conditions/WiredConditionActorIsWearingBadgeView.tsx deleted file mode 100644 index 01e6d3b..0000000 --- a/src/components/wired/views/conditions/WiredConditionActorIsWearingBadgeView.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionActorIsWearingBadgeView: FC<{}> = props => -{ - const [ badge, setBadge ] = useState(''); - const { trigger = null, setStringParam = null } = useWired(); - - const save = () => setStringParam(badge); - - useEffect(() => - { - setBadge(trigger.stringData); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.badgecode') } - setBadge(event.target.value) } /> - - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionActorIsWearingEffectView.tsx b/src/components/wired/views/conditions/WiredConditionActorIsWearingEffectView.tsx deleted file mode 100644 index 00d7fa6..0000000 --- a/src/components/wired/views/conditions/WiredConditionActorIsWearingEffectView.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionActorIsWearingEffectView: FC<{}> = props => -{ - const [ effect, setEffect ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ effect ]); - - useEffect(() => - { - setEffect(trigger?.intData[0] ?? 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.tooltip.effectid') } - setEffect(parseInt(event.target.value)) } /> - - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionBaseView.tsx b/src/components/wired/views/conditions/WiredConditionBaseView.tsx deleted file mode 100644 index fc49215..0000000 --- a/src/components/wired/views/conditions/WiredConditionBaseView.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { FC, PropsWithChildren } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredBaseView } from '../WiredBaseView'; - -export interface WiredConditionBaseViewProps -{ - hasSpecialInput: boolean; - requiresFurni: number; - save: () => void; -} - -export const WiredConditionBaseView: FC> = props => -{ - const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, hasSpecialInput = false, children = null } = props; - - const onSave = () => (save && save()); - - return ( - - { children } - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionDateRangeView.tsx b/src/components/wired/views/conditions/WiredConditionDateRangeView.tsx deleted file mode 100644 index 36832e1..0000000 --- a/src/components/wired/views/conditions/WiredConditionDateRangeView.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredDateToString, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionDateRangeView: FC<{}> = props => -{ - const [ startDate, setStartDate ] = useState(''); - const [ endDate, setEndDate ] = useState(''); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => - { - let startDateMili = 0; - let endDateMili = 0; - - const startDateInstance = new Date(startDate); - const endDateInstance = new Date(endDate); - - if(startDateInstance && endDateInstance) - { - startDateMili = startDateInstance.getTime() / 1000; - endDateMili = endDateInstance.getTime() / 1000; - } - - setIntParams([ startDateMili, endDateMili ]); - } - - useEffect(() => - { - if(trigger.intData.length >= 2) - { - let startDate = new Date(); - let endDate = new Date(); - - if(trigger.intData[0] > 0) startDate = new Date((trigger.intData[0] * 1000)); - - if(trigger.intData[1] > 0) endDate = new Date((trigger.intData[1] * 1000)); - - setStartDate(WiredDateToString(startDate)); - setEndDate(WiredDateToString(endDate)); - } - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.startdate') } - setStartDate(e.target.value) } /> - - - { LocalizeText('wiredfurni.params.enddate') } - setEndDate(e.target.value) } /> - - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionFurniHasAvatarOnView.tsx b/src/components/wired/views/conditions/WiredConditionFurniHasAvatarOnView.tsx deleted file mode 100644 index aa3ba14..0000000 --- a/src/components/wired/views/conditions/WiredConditionFurniHasAvatarOnView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionFurniHasAvatarOnView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/conditions/WiredConditionFurniHasFurniOnView.tsx b/src/components/wired/views/conditions/WiredConditionFurniHasFurniOnView.tsx deleted file mode 100644 index 1a9d0ef..0000000 --- a/src/components/wired/views/conditions/WiredConditionFurniHasFurniOnView.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionFurniHasFurniOnView: FC<{}> = props => -{ - const [ requireAll, setRequireAll ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ requireAll ]); - - useEffect(() => - { - setRequireAll((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.requireall') } - { [ 0, 1 ].map(value => - { - return ( - - setRequireAll(value) } /> - { LocalizeText('wiredfurni.params.requireall.' + value) } - - ) - }) } - - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionFurniHasNotFurniOnView.tsx b/src/components/wired/views/conditions/WiredConditionFurniHasNotFurniOnView.tsx deleted file mode 100644 index 031ec08..0000000 --- a/src/components/wired/views/conditions/WiredConditionFurniHasNotFurniOnView.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionFurniHasNotFurniOnView: FC<{}> = props => -{ - const [ requireAll, setRequireAll ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ requireAll ]); - - useEffect(() => - { - setRequireAll((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.not_requireall') } - { [ 0, 1 ].map(value => - { - return ( - - setRequireAll(value) } /> - { LocalizeText(`wiredfurni.params.not_requireall.${ value }`) } - - ) - }) } - - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionFurniIsOfTypeView.tsx b/src/components/wired/views/conditions/WiredConditionFurniIsOfTypeView.tsx deleted file mode 100644 index 2b0ddf4..0000000 --- a/src/components/wired/views/conditions/WiredConditionFurniIsOfTypeView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionFurniIsOfTypeView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/conditions/WiredConditionFurniMatchesSnapshotView.tsx b/src/components/wired/views/conditions/WiredConditionFurniMatchesSnapshotView.tsx deleted file mode 100644 index 47a555e..0000000 --- a/src/components/wired/views/conditions/WiredConditionFurniMatchesSnapshotView.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionFurniMatchesSnapshotView: FC<{}> = props => -{ - const [ stateFlag, setStateFlag ] = useState(0); - const [ directionFlag, setDirectionFlag ] = useState(0); - const [ positionFlag, setPositionFlag ] = useState(0); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ stateFlag, directionFlag, positionFlag ]); - - useEffect(() => - { - setStateFlag(trigger.getBoolean(0) ? 1 : 0); - setDirectionFlag(trigger.getBoolean(1) ? 1 : 0); - setPositionFlag(trigger.getBoolean(2) ? 1 : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.conditions') } - - setStateFlag(event.target.checked ? 1 : 0) } /> - { LocalizeText('wiredfurni.params.condition.state') } - - - setDirectionFlag(event.target.checked ? 1 : 0) } /> - { LocalizeText('wiredfurni.params.condition.direction') } - - - setPositionFlag(event.target.checked ? 1 : 0) } /> - { LocalizeText('wiredfurni.params.condition.position') } - - - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionLayoutView.tsx b/src/components/wired/views/conditions/WiredConditionLayoutView.tsx deleted file mode 100644 index c7c49b2..0000000 --- a/src/components/wired/views/conditions/WiredConditionLayoutView.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { WiredConditionlayout } from '../../../../api'; -import { WiredConditionActorHasHandItemView } from './WiredConditionActorHasHandItem'; -import { WiredConditionActorIsGroupMemberView } from './WiredConditionActorIsGroupMemberView'; -import { WiredConditionActorIsOnFurniView } from './WiredConditionActorIsOnFurniView'; -import { WiredConditionActorIsTeamMemberView } from './WiredConditionActorIsTeamMemberView'; -import { WiredConditionActorIsWearingBadgeView } from './WiredConditionActorIsWearingBadgeView'; -import { WiredConditionActorIsWearingEffectView } from './WiredConditionActorIsWearingEffectView'; -import { WiredConditionDateRangeView } from './WiredConditionDateRangeView'; -import { WiredConditionFurniHasAvatarOnView } from './WiredConditionFurniHasAvatarOnView'; -import { WiredConditionFurniHasFurniOnView } from './WiredConditionFurniHasFurniOnView'; -import { WiredConditionFurniHasNotFurniOnView } from './WiredConditionFurniHasNotFurniOnView'; -import { WiredConditionFurniIsOfTypeView } from './WiredConditionFurniIsOfTypeView'; -import { WiredConditionFurniMatchesSnapshotView } from './WiredConditionFurniMatchesSnapshotView'; -import { WiredConditionTimeElapsedLessView } from './WiredConditionTimeElapsedLessView'; -import { WiredConditionTimeElapsedMoreView } from './WiredConditionTimeElapsedMoreView'; -import { WiredConditionUserCountInRoomView } from './WiredConditionUserCountInRoomView'; - -export const WiredConditionLayoutView = (code: number) => -{ - switch(code) - { - case WiredConditionlayout.ACTOR_HAS_HANDITEM: - return ; - case WiredConditionlayout.ACTOR_IS_GROUP_MEMBER: - case WiredConditionlayout.NOT_ACTOR_IN_GROUP: - return ; - case WiredConditionlayout.ACTOR_IS_ON_FURNI: - case WiredConditionlayout.NOT_ACTOR_ON_FURNI: - return ; - case WiredConditionlayout.ACTOR_IS_IN_TEAM: - case WiredConditionlayout.NOT_ACTOR_IN_TEAM: - return ; - case WiredConditionlayout.ACTOR_IS_WEARING_BADGE: - case WiredConditionlayout.NOT_ACTOR_WEARS_BADGE: - return ; - case WiredConditionlayout.ACTOR_IS_WEARING_EFFECT: - case WiredConditionlayout.NOT_ACTOR_WEARING_EFFECT: - return ; - case WiredConditionlayout.DATE_RANGE_ACTIVE: - return ; - case WiredConditionlayout.FURNIS_HAVE_AVATARS: - case WiredConditionlayout.FURNI_NOT_HAVE_HABBO: - return ; - case WiredConditionlayout.HAS_STACKED_FURNIS: - return ; - case WiredConditionlayout.NOT_HAS_STACKED_FURNIS: - return ; - case WiredConditionlayout.STUFF_TYPE_MATCHES: - case WiredConditionlayout.NOT_FURNI_IS_OF_TYPE: - return ; - case WiredConditionlayout.STATES_MATCH: - case WiredConditionlayout.NOT_STATES_MATCH: - return ; - case WiredConditionlayout.TIME_ELAPSED_LESS: - return ; - case WiredConditionlayout.TIME_ELAPSED_MORE: - return ; - case WiredConditionlayout.USER_COUNT_IN: - case WiredConditionlayout.NOT_USER_COUNT_IN: - return ; - } - - return null; -} diff --git a/src/components/wired/views/conditions/WiredConditionTimeElapsedLessView.tsx b/src/components/wired/views/conditions/WiredConditionTimeElapsedLessView.tsx deleted file mode 100644 index 31d6d79..0000000 --- a/src/components/wired/views/conditions/WiredConditionTimeElapsedLessView.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { GetWiredTimeLocale, LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionTimeElapsedLessView: FC<{}> = props => -{ - const [ time, setTime ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ time ]); - - useEffect(() => - { - setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.allowbefore', [ 'seconds' ], [ GetWiredTimeLocale(time) ]) } - setTime(event) } /> - - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionTimeElapsedMoreView.tsx b/src/components/wired/views/conditions/WiredConditionTimeElapsedMoreView.tsx deleted file mode 100644 index cb158e6..0000000 --- a/src/components/wired/views/conditions/WiredConditionTimeElapsedMoreView.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { GetWiredTimeLocale, LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionTimeElapsedMoreView: FC<{}> = props => -{ - const [ time, setTime ] = useState(-1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ time ]); - - useEffect(() => - { - setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.allowafter', [ 'seconds' ], [ GetWiredTimeLocale(time) ]) } - setTime(event) } /> - - - ); -} diff --git a/src/components/wired/views/conditions/WiredConditionUserCountInRoomView.tsx b/src/components/wired/views/conditions/WiredConditionUserCountInRoomView.tsx deleted file mode 100644 index 8ef5914..0000000 --- a/src/components/wired/views/conditions/WiredConditionUserCountInRoomView.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredConditionBaseView } from './WiredConditionBaseView'; - -export const WiredConditionUserCountInRoomView: FC<{}> = props => -{ - const [ min, setMin ] = useState(1); - const [ max, setMax ] = useState(0); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ min, max ]); - - useEffect(() => - { - if(trigger.intData.length >= 2) - { - setMin(trigger.intData[0]); - setMax(trigger.intData[1]); - } - else - { - setMin(1); - setMax(0); - } - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.usercountmin', [ 'value' ], [ min.toString() ]) } - setMin(event) } /> - - - { LocalizeText('wiredfurni.params.usercountmax', [ 'value' ], [ max.toString() ]) } - setMax(event) } /> - - - ); -} diff --git a/src/components/wired/views/triggers/WiredTriggerAvatarEnterRoomView.tsx b/src/components/wired/views/triggers/WiredTriggerAvatarEnterRoomView.tsx deleted file mode 100644 index b14eafb..0000000 --- a/src/components/wired/views/triggers/WiredTriggerAvatarEnterRoomView.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggerAvatarEnterRoomView: FC<{}> = props => -{ - const [ username, setUsername ] = useState(''); - const [ avatarMode, setAvatarMode ] = useState(0); - const { trigger = null, setStringParam = null } = useWired(); - - const save = () => setStringParam((avatarMode === 1) ? username : ''); - - useEffect(() => - { - setUsername(trigger.stringData); - setAvatarMode(trigger.stringData ? 1 : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.picktriggerer') } - - setAvatarMode(0) } /> - { LocalizeText('wiredfurni.params.anyavatar') } - - - setAvatarMode(1) } /> - { LocalizeText('wiredfurni.params.certainavatar') } - - { (avatarMode === 1) && - setUsername(event.target.value) } /> } - - - ); -} diff --git a/src/components/wired/views/triggers/WiredTriggerAvatarSaysSomethingView.tsx b/src/components/wired/views/triggers/WiredTriggerAvatarSaysSomethingView.tsx deleted file mode 100644 index 4aaf8fe..0000000 --- a/src/components/wired/views/triggers/WiredTriggerAvatarSaysSomethingView.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { GetSessionDataManager } from '@nitrots/nitro-renderer'; -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Flex, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggerAvatarSaysSomethingView: FC<{}> = props => -{ - const [ message, setMessage ] = useState(''); - const [ triggererAvatar, setTriggererAvatar ] = useState(-1); - const { trigger = null, setStringParam = null, setIntParams = null } = useWired(); - - const save = () => - { - setStringParam(message); - setIntParams([ triggererAvatar ]); - } - - useEffect(() => - { - setMessage(trigger.stringData); - setTriggererAvatar((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.whatissaid') } - setMessage(event.target.value) } /> - - - { LocalizeText('wiredfurni.params.picktriggerer') } - - setTriggererAvatar(0) } /> - { LocalizeText('wiredfurni.params.anyavatar') } - - - setTriggererAvatar(1) } /> - { GetSessionDataManager().userName } - - - - ); -} diff --git a/src/components/wired/views/triggers/WiredTriggerAvatarWalksOffFurniView.tsx b/src/components/wired/views/triggers/WiredTriggerAvatarWalksOffFurniView.tsx deleted file mode 100644 index 0b98a56..0000000 --- a/src/components/wired/views/triggers/WiredTriggerAvatarWalksOffFurniView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggerAvatarWalksOffFurniView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/triggers/WiredTriggerAvatarWalksOnFurni.tsx b/src/components/wired/views/triggers/WiredTriggerAvatarWalksOnFurni.tsx deleted file mode 100644 index 25572e7..0000000 --- a/src/components/wired/views/triggers/WiredTriggerAvatarWalksOnFurni.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggerAvatarWalksOnFurniView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/triggers/WiredTriggerBaseView.tsx b/src/components/wired/views/triggers/WiredTriggerBaseView.tsx deleted file mode 100644 index f8f1575..0000000 --- a/src/components/wired/views/triggers/WiredTriggerBaseView.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { FC, PropsWithChildren } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredBaseView } from '../WiredBaseView'; - -export interface WiredTriggerBaseViewProps -{ - hasSpecialInput: boolean; - requiresFurni: number; - save: () => void; -} - -export const WiredTriggerBaseView: FC> = props => -{ - const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, hasSpecialInput = false, children = null } = props; - - const onSave = () => (save && save()); - - return ( - - { children } - - ); -} diff --git a/src/components/wired/views/triggers/WiredTriggerBotReachedAvatarView.tsx b/src/components/wired/views/triggers/WiredTriggerBotReachedAvatarView.tsx deleted file mode 100644 index 6984dc6..0000000 --- a/src/components/wired/views/triggers/WiredTriggerBotReachedAvatarView.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggerBotReachedAvatarView: FC<{}> = props => -{ - const [ botName, setBotName ] = useState(''); - const { trigger = null, setStringParam = null } = useWired(); - - const save = () => setStringParam(botName); - - useEffect(() => - { - setBotName(trigger.stringData); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.bot.name') } - setBotName(event.target.value) } /> - - - ); -} diff --git a/src/components/wired/views/triggers/WiredTriggerBotReachedStuffView.tsx b/src/components/wired/views/triggers/WiredTriggerBotReachedStuffView.tsx deleted file mode 100644 index 9cde173..0000000 --- a/src/components/wired/views/triggers/WiredTriggerBotReachedStuffView.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggerBotReachedStuffView: FC<{}> = props => -{ - const [ botName, setBotName ] = useState(''); - const { trigger = null, setStringParam = null } = useWired(); - - const save = () => setStringParam(botName); - - useEffect(() => - { - setBotName(trigger.stringData); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.bot.name') } - setBotName(event.target.value) } /> - - - ); -} diff --git a/src/components/wired/views/triggers/WiredTriggerCollisionView.tsx b/src/components/wired/views/triggers/WiredTriggerCollisionView.tsx deleted file mode 100644 index be23a6b..0000000 --- a/src/components/wired/views/triggers/WiredTriggerCollisionView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggerCollisionView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/triggers/WiredTriggerExecuteOnceView.tsx b/src/components/wired/views/triggers/WiredTriggerExecuteOnceView.tsx deleted file mode 100644 index ea3d61b..0000000 --- a/src/components/wired/views/triggers/WiredTriggerExecuteOnceView.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { GetWiredTimeLocale, LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggeExecuteOnceView: FC<{}> = props => -{ - const [ time, setTime ] = useState(1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ time ]); - - useEffect(() => - { - setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.settime', [ 'seconds' ], [ GetWiredTimeLocale(time) ]) } - setTime(event) } /> - - - ); -} diff --git a/src/components/wired/views/triggers/WiredTriggerExecutePeriodicallyLongView.tsx b/src/components/wired/views/triggers/WiredTriggerExecutePeriodicallyLongView.tsx deleted file mode 100644 index 5a698dd..0000000 --- a/src/components/wired/views/triggers/WiredTriggerExecutePeriodicallyLongView.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { FriendlyTime, LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggeExecutePeriodicallyLongView: FC<{}> = props => -{ - const [ time, setTime ] = useState(1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ time ]); - - useEffect(() => - { - setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.setlongtime', [ 'time' ], [ FriendlyTime.format(time * 5).toString() ]) } - setTime(event) } /> - - - ); -} diff --git a/src/components/wired/views/triggers/WiredTriggerExecutePeriodicallyView.tsx b/src/components/wired/views/triggers/WiredTriggerExecutePeriodicallyView.tsx deleted file mode 100644 index b77e642..0000000 --- a/src/components/wired/views/triggers/WiredTriggerExecutePeriodicallyView.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { GetWiredTimeLocale, LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggeExecutePeriodicallyView: FC<{}> = props => -{ - const [ time, setTime ] = useState(1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ time ]); - - useEffect(() => - { - setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.settime', [ 'seconds' ], [ GetWiredTimeLocale(time) ]) } - setTime(event) } /> - - - ); -} diff --git a/src/components/wired/views/triggers/WiredTriggerGameEndsView.tsx b/src/components/wired/views/triggers/WiredTriggerGameEndsView.tsx deleted file mode 100644 index c6f1c67..0000000 --- a/src/components/wired/views/triggers/WiredTriggerGameEndsView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggerGameEndsView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/triggers/WiredTriggerGameStartsView.tsx b/src/components/wired/views/triggers/WiredTriggerGameStartsView.tsx deleted file mode 100644 index 6e43a2c..0000000 --- a/src/components/wired/views/triggers/WiredTriggerGameStartsView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggerGameStartsView: FC<{}> = props => -{ - return ; -} diff --git a/src/components/wired/views/triggers/WiredTriggerLayoutView.tsx b/src/components/wired/views/triggers/WiredTriggerLayoutView.tsx deleted file mode 100644 index e45b2ea..0000000 --- a/src/components/wired/views/triggers/WiredTriggerLayoutView.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { WiredTriggerLayout } from '../../../../api'; -import { WiredTriggerAvatarEnterRoomView } from './WiredTriggerAvatarEnterRoomView'; -import { WiredTriggerAvatarSaysSomethingView } from './WiredTriggerAvatarSaysSomethingView'; -import { WiredTriggerAvatarWalksOffFurniView } from './WiredTriggerAvatarWalksOffFurniView'; -import { WiredTriggerAvatarWalksOnFurniView } from './WiredTriggerAvatarWalksOnFurni'; -import { WiredTriggerBotReachedAvatarView } from './WiredTriggerBotReachedAvatarView'; -import { WiredTriggerBotReachedStuffView } from './WiredTriggerBotReachedStuffView'; -import { WiredTriggerCollisionView } from './WiredTriggerCollisionView'; -import { WiredTriggeExecuteOnceView } from './WiredTriggerExecuteOnceView'; -import { WiredTriggeExecutePeriodicallyLongView } from './WiredTriggerExecutePeriodicallyLongView'; -import { WiredTriggeExecutePeriodicallyView } from './WiredTriggerExecutePeriodicallyView'; -import { WiredTriggerGameEndsView } from './WiredTriggerGameEndsView'; -import { WiredTriggerGameStartsView } from './WiredTriggerGameStartsView'; -import { WiredTriggeScoreAchievedView } from './WiredTriggerScoreAchievedView'; -import { WiredTriggerToggleFurniView } from './WiredTriggerToggleFurniView'; - -export const WiredTriggerLayoutView = (code: number) => -{ - switch(code) - { - case WiredTriggerLayout.AVATAR_ENTERS_ROOM: - return ; - case WiredTriggerLayout.AVATAR_SAYS_SOMETHING: - return ; - case WiredTriggerLayout.AVATAR_WALKS_OFF_FURNI: - return ; - case WiredTriggerLayout.AVATAR_WALKS_ON_FURNI: - return ; - case WiredTriggerLayout.BOT_REACHED_AVATAR: - return ; - case WiredTriggerLayout.BOT_REACHED_STUFF: - return ; - case WiredTriggerLayout.COLLISION: - return ; - case WiredTriggerLayout.EXECUTE_ONCE: - return ; - case WiredTriggerLayout.EXECUTE_PERIODICALLY: - return ; - case WiredTriggerLayout.EXECUTE_PERIODICALLY_LONG: - return ; - case WiredTriggerLayout.GAME_ENDS: - return ; - case WiredTriggerLayout.GAME_STARTS: - return ; - case WiredTriggerLayout.SCORE_ACHIEVED: - return ; - case WiredTriggerLayout.TOGGLE_FURNI: - return ; - } - - return null; -} diff --git a/src/components/wired/views/triggers/WiredTriggerScoreAchievedView.tsx b/src/components/wired/views/triggers/WiredTriggerScoreAchievedView.tsx deleted file mode 100644 index 883503b..0000000 --- a/src/components/wired/views/triggers/WiredTriggerScoreAchievedView.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { FC, useEffect, useState } from 'react'; -import ReactSlider from 'react-slider'; -import { LocalizeText, WiredFurniType } from '../../../../api'; -import { Column, Text } from '../../../../common'; -import { useWired } from '../../../../hooks'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggeScoreAchievedView: FC<{}> = props => -{ - const [ points, setPoints ] = useState(1); - const { trigger = null, setIntParams = null } = useWired(); - - const save = () => setIntParams([ points ]); - - useEffect(() => - { - setPoints((trigger.intData.length > 0) ? trigger.intData[0] : 0); - }, [ trigger ]); - - return ( - - - { LocalizeText('wiredfurni.params.setscore', [ 'points' ], [ points.toString() ]) } - setPoints(event) } /> - - - ); -} diff --git a/src/components/wired/views/triggers/WiredTriggerToggleFurniView.tsx b/src/components/wired/views/triggers/WiredTriggerToggleFurniView.tsx deleted file mode 100644 index 865006b..0000000 --- a/src/components/wired/views/triggers/WiredTriggerToggleFurniView.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FC } from 'react'; -import { WiredFurniType } from '../../../../api'; -import { WiredTriggerBaseView } from './WiredTriggerBaseView'; - -export const WiredTriggerToggleFurniView: FC<{}> = props => -{ - return ; -} diff --git a/src/events/catalog/CatalogEvent.ts b/src/events/catalog/CatalogEvent.ts deleted file mode 100644 index 893775a..0000000 --- a/src/events/catalog/CatalogEvent.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; - -export class CatalogEvent extends NitroEvent -{ - public static SHOW_CATALOG: string = 'CE_SHOW_CATALOG'; - public static HIDE_CATALOG: string = 'CE_HIDE_CATALOG'; - public static TOGGLE_CATALOG: string = 'CE_TOGGLE_CATALOG'; - public static SOLD_OUT: string = 'CE_SOLD_OUT'; - public static APPROVE_NAME_RESULT: string = 'CE_APPROVE_NAME_RESULT'; - public static PURCHASE_APPROVED: string = 'CE_PURCHASE_APPROVED'; - public static INIT_GIFT: string = 'CE_INIT_GIFT'; - public static CATALOG_RESET: string = 'CE_RESET'; - public static CATALOG_INVISIBLE_PAGE_VISITED: string = 'CE_CATALOG_INVISIBLE_PAGE_VISITED'; -} diff --git a/src/events/catalog/CatalogInitGiftEvent.ts b/src/events/catalog/CatalogInitGiftEvent.ts deleted file mode 100644 index fd9c926..0000000 --- a/src/events/catalog/CatalogInitGiftEvent.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { CatalogEvent } from './CatalogEvent'; - -export class CatalogInitGiftEvent extends CatalogEvent -{ - private _pageId: number; - private _offerId: number; - private _extraData: string; - - constructor(pageId: number, offerId: number, extraData: string) - { - super(CatalogEvent.INIT_GIFT); - - this._pageId = pageId; - this._offerId = offerId; - this._extraData = extraData; - } - - public get pageId(): number - { - return this._pageId; - } - - public get offerId(): number - { - return this._offerId; - } - - public get extraData(): string - { - return this._extraData; - } -} diff --git a/src/events/catalog/CatalogPostMarketplaceOfferEvent.ts b/src/events/catalog/CatalogPostMarketplaceOfferEvent.ts deleted file mode 100644 index d54c6c4..0000000 --- a/src/events/catalog/CatalogPostMarketplaceOfferEvent.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { CatalogEvent } from '.'; -import { FurnitureItem } from '../../api'; - -export class CatalogPostMarketplaceOfferEvent extends CatalogEvent -{ - public static readonly POST_MARKETPLACE = 'CE_POST_MARKETPLACE'; - - private _item: FurnitureItem; - - constructor(item: FurnitureItem) - { - super(CatalogPostMarketplaceOfferEvent.POST_MARKETPLACE); - this._item = item; - } - - public get item(): FurnitureItem - { - return this._item; - } -} diff --git a/src/events/catalog/CatalogPurchaseFailureEvent.ts b/src/events/catalog/CatalogPurchaseFailureEvent.ts deleted file mode 100644 index 59f0633..0000000 --- a/src/events/catalog/CatalogPurchaseFailureEvent.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; - -export class CatalogPurchaseFailureEvent extends NitroEvent -{ - public static PURCHASE_FAILED: string = 'CPFE_PURCHASE_FAILED'; - - private _code: number; - - constructor(code: number) - { - super(CatalogPurchaseFailureEvent.PURCHASE_FAILED); - - this._code = code; - } - - public get code(): number - { - return this._code; - } -} diff --git a/src/events/catalog/CatalogPurchaseNotAllowedEvent.ts b/src/events/catalog/CatalogPurchaseNotAllowedEvent.ts deleted file mode 100644 index 78d012b..0000000 --- a/src/events/catalog/CatalogPurchaseNotAllowedEvent.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; - -export class CatalogPurchaseNotAllowedEvent extends NitroEvent -{ - public static NOT_ALLOWED: string = 'CPNAE_NOT_ALLOWED'; - - private _code: number; - - constructor(code: number) - { - super(CatalogPurchaseNotAllowedEvent.NOT_ALLOWED); - - this._code = code; - } - - public get code(): number - { - return this._code; - } -} diff --git a/src/events/catalog/CatalogPurchaseOverrideEvent.ts b/src/events/catalog/CatalogPurchaseOverrideEvent.ts deleted file mode 100644 index 7c0b8b5..0000000 --- a/src/events/catalog/CatalogPurchaseOverrideEvent.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; -import { CatalogWidgetEvent } from './CatalogWidgetEvent'; - -export class CatalogPurchaseOverrideEvent extends NitroEvent -{ - private _callback: Function; - - constructor(callback: Function) - { - super(CatalogWidgetEvent.PURCHASE_OVERRIDE); - - this._callback = callback; - } - - public get callback(): Function - { - return this._callback; - } -} diff --git a/src/events/catalog/CatalogPurchaseSoldOutEvent.ts b/src/events/catalog/CatalogPurchaseSoldOutEvent.ts deleted file mode 100644 index a3a43a3..0000000 --- a/src/events/catalog/CatalogPurchaseSoldOutEvent.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; - -export class CatalogPurchaseSoldOutEvent extends NitroEvent -{ - public static SOLD_OUT: string = 'CPSOE_SOLD_OUT'; - - constructor() - { - super(CatalogPurchaseSoldOutEvent.SOLD_OUT); - } -} diff --git a/src/events/catalog/CatalogPurchasedEvent.ts b/src/events/catalog/CatalogPurchasedEvent.ts deleted file mode 100644 index dedba46..0000000 --- a/src/events/catalog/CatalogPurchasedEvent.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { NitroEvent, PurchaseOKMessageOfferData } from '@nitrots/nitro-renderer'; - -export class CatalogPurchasedEvent extends NitroEvent -{ - public static PURCHASE_SUCCESS: string = 'CPE_PURCHASE_SUCCESS'; - - private _purchase: PurchaseOKMessageOfferData; - - constructor(purchase: PurchaseOKMessageOfferData) - { - super(CatalogPurchasedEvent.PURCHASE_SUCCESS); - - this._purchase = purchase; - } - - public get purchase(): PurchaseOKMessageOfferData - { - return this._purchase; - } -} diff --git a/src/events/catalog/CatalogSetRoomPreviewerStuffDataEvent.ts b/src/events/catalog/CatalogSetRoomPreviewerStuffDataEvent.ts deleted file mode 100644 index 24e91a7..0000000 --- a/src/events/catalog/CatalogSetRoomPreviewerStuffDataEvent.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { IObjectData, NitroEvent } from '@nitrots/nitro-renderer'; -import { CatalogWidgetEvent } from './CatalogWidgetEvent'; - -export class CatalogSetRoomPreviewerStuffDataEvent extends NitroEvent -{ - private _stuffData: IObjectData; - - constructor(stuffData: IObjectData) - { - super(CatalogWidgetEvent.SET_PREVIEWER_STUFFDATA); - - this._stuffData = stuffData; - } - - public get stuffData(): IObjectData - { - return this._stuffData; - } -} diff --git a/src/events/catalog/CatalogWidgetEvent.ts b/src/events/catalog/CatalogWidgetEvent.ts deleted file mode 100644 index fd0e602..0000000 --- a/src/events/catalog/CatalogWidgetEvent.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; - -export class CatalogWidgetEvent extends NitroEvent -{ - public static WIDGETS_INITIALIZED: string = 'CWE_CWE_WIDGETS_INITIALIZED'; - public static SELECT_PRODUCT: string = 'CWE_SELECT_PRODUCT'; - public static SET_EXTRA_PARM: string = 'CWE_CWE_SET_EXTRA_PARM'; - public static PURCHASE: string = 'CWE_PURCHASE'; - public static COLOUR_ARRAY: string = 'CWE_COLOUR_ARRAY'; - public static MULTI_COLOUR_ARRAY: string = 'CWE_MULTI_COLOUR_ARRAY'; - public static COLOUR_INDEX: string = 'CWE_COLOUR_INDEX'; - public static TEXT_INPUT: string = 'CWE_TEXT_INPUT'; - public static DROPMENU_SELECT: string = 'CWE_CWE_DROPMENU_SELECT'; - public static PURCHASE_OVERRIDE: string = 'CWE_PURCHASE_OVERRIDE'; - public static SELLABLE_PET_PALETTES: string = 'CWE_SELLABLE_PET_PALETTES'; - public static UPDATE_ROOM_PREVIEW: string = 'CWE_UPDATE_ROOM_PREVIEW'; - public static GUILD_SELECTED: string = 'CWE_GUILD_SELECTED'; - public static TOTAL_PRICE_WIDGET_INITIALIZED: string = 'CWE_TOTAL_PRICE_WIDGET_INITIALIZED'; - public static PRODUCT_OFFER_UPDATED: string = 'CWE_CWE_PRODUCT_OFFER_UPDATED'; - public static SET_PREVIEWER_STUFFDATA: string = 'CWE_CWE_SET_PREVIEWER_STUFFDATA'; - public static EXTRA_PARAM_REQUIRED_FOR_BUY: string = 'CWE_CWE_EXTRA_PARAM_REQUIRED_FOR_BUY'; - public static TOGGLE: string = 'CWE_CWE_TOGGLE'; - public static BUILDER_SUBSCRIPTION_UPDATED: string = 'CWE_CWE_BUILDER_SUBSCRIPTION_UPDATED'; - public static ROOM_CHANGED: string = 'CWE_CWE_ROOM_CHANGED'; - public static SHOW_WARNING_TEXT: string = 'CWE_CWE_SHOW_WARNING_TEXT'; -} diff --git a/src/events/catalog/SetRoomPreviewerStuffDataEvent.ts b/src/events/catalog/SetRoomPreviewerStuffDataEvent.ts deleted file mode 100644 index 5332dfd..0000000 --- a/src/events/catalog/SetRoomPreviewerStuffDataEvent.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { IObjectData, NitroEvent } from '@nitrots/nitro-renderer'; -import { IPurchasableOffer } from '../../api'; - -export class SetRoomPreviewerStuffDataEvent extends NitroEvent -{ - public static UPDATE_STUFF_DATA: string = 'SRPSA_UPDATE_STUFF_DATA'; - - private _offer: IPurchasableOffer; - private _stuffData: IObjectData; - - constructor(offer: IPurchasableOffer, stuffData: IObjectData) - { - super(SetRoomPreviewerStuffDataEvent.UPDATE_STUFF_DATA); - - this._offer = offer; - this._stuffData = stuffData; - } - - public get offer(): IPurchasableOffer - { - return this._offer; - } - - public get stuffData(): IObjectData - { - return this._stuffData; - } -} diff --git a/src/events/catalog/index.ts b/src/events/catalog/index.ts deleted file mode 100644 index a7c1572..0000000 --- a/src/events/catalog/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -export * from './CatalogEvent'; -export * from './CatalogInitGiftEvent'; -export * from './CatalogPostMarketplaceOfferEvent'; -export * from './CatalogPurchasedEvent'; -export * from './CatalogPurchaseFailureEvent'; -export * from './CatalogPurchaseNotAllowedEvent'; -export * from './CatalogPurchaseOverrideEvent'; -export * from './CatalogPurchaseSoldOutEvent'; -export * from './CatalogSetRoomPreviewerStuffDataEvent'; -export * from './CatalogWidgetEvent'; -export * from './SetRoomPreviewerStuffDataEvent'; diff --git a/src/events/guide-tool/GuideToolEvent.ts b/src/events/guide-tool/GuideToolEvent.ts deleted file mode 100644 index f77cec3..0000000 --- a/src/events/guide-tool/GuideToolEvent.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; - -export class GuideToolEvent extends NitroEvent -{ - public static readonly SHOW_GUIDE_TOOL: string = 'GTE_SHOW_GUIDE_TOOL'; - public static readonly HIDE_GUIDE_TOOL: string = 'GTE_HIDE_GUIDE_TOOL'; - public static readonly TOGGLE_GUIDE_TOOL: string = 'GTE_TOGGLE_GUIDE_TOOL'; - public static readonly CREATE_HELP_REQUEST: string = 'GTE_CREATE_HELP_REQUEST'; - public static readonly CREATE_BULLY_REQUEST: string = 'GTE_CREATE_BULLY_REQUEST'; -} diff --git a/src/events/guide-tool/index.ts b/src/events/guide-tool/index.ts deleted file mode 100644 index 6cbff54..0000000 --- a/src/events/guide-tool/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './GuideToolEvent'; diff --git a/src/events/help/HelpNameChangeEvent.ts b/src/events/help/HelpNameChangeEvent.ts deleted file mode 100644 index 44597d0..0000000 --- a/src/events/help/HelpNameChangeEvent.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; - -export class HelpNameChangeEvent extends NitroEvent -{ - public static INIT: string = 'HC_NAME_CHANGE_INIT'; -} diff --git a/src/events/help/index.ts b/src/events/help/index.ts deleted file mode 100644 index e89f307..0000000 --- a/src/events/help/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './HelpNameChangeEvent'; diff --git a/src/events/index.ts b/src/events/index.ts deleted file mode 100644 index 4c5e757..0000000 --- a/src/events/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './catalog'; -export * from './guide-tool'; -export * from './help'; -export * from './inventory'; -export * from './room-widgets'; -export * from './room-widgets/thumbnail'; diff --git a/src/events/inventory/InventoryFurniAddedEvent.ts b/src/events/inventory/InventoryFurniAddedEvent.ts deleted file mode 100644 index 409f0be..0000000 --- a/src/events/inventory/InventoryFurniAddedEvent.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; - -export class InventoryFurniAddedEvent extends NitroEvent -{ - public static FURNI_ADDED: string = 'IFAE_FURNI_ADDED'; - - constructor( - public readonly id: number, - public readonly spriteId: number, - public readonly category: number) - { - super(InventoryFurniAddedEvent.FURNI_ADDED); - } -} diff --git a/src/events/inventory/index.ts b/src/events/inventory/index.ts deleted file mode 100644 index 58503ea..0000000 --- a/src/events/inventory/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './InventoryFurniAddedEvent'; diff --git a/src/events/room-widgets/index.ts b/src/events/room-widgets/index.ts deleted file mode 100644 index d4ab7a5..0000000 --- a/src/events/room-widgets/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './thumbnail'; diff --git a/src/events/room-widgets/thumbnail/RoomWidgetThumbnailEvent.ts b/src/events/room-widgets/thumbnail/RoomWidgetThumbnailEvent.ts deleted file mode 100644 index dc62c6f..0000000 --- a/src/events/room-widgets/thumbnail/RoomWidgetThumbnailEvent.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; - -export class RoomWidgetThumbnailEvent extends NitroEvent -{ - public static SHOW_THUMBNAIL: string = 'NE_SHOW_THUMBNAIL'; - public static HIDE_THUMBNAIL: string = 'NE_HIDE_THUMBNAIL'; - public static TOGGLE_THUMBNAIL: string = 'NE_TOGGLE_THUMBNAIL'; -} diff --git a/src/events/room-widgets/thumbnail/index.ts b/src/events/room-widgets/thumbnail/index.ts deleted file mode 100644 index 56f116d..0000000 --- a/src/events/room-widgets/thumbnail/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './RoomWidgetThumbnailEvent'; diff --git a/src/hooks/UseMountEffect.tsx b/src/hooks/UseMountEffect.tsx deleted file mode 100644 index 0ead14b..0000000 --- a/src/hooks/UseMountEffect.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { EffectCallback, useEffect } from 'react'; - - -// eslint-disable-next-line react-hooks/exhaustive-deps -const useEffectOnce = (effect: EffectCallback) => useEffect(effect, []); - -export const UseMountEffect = (fn: Function) => useEffectOnce(() => fn()); diff --git a/src/hooks/achievements/index.ts b/src/hooks/achievements/index.ts deleted file mode 100644 index 1a2a81e..0000000 --- a/src/hooks/achievements/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useAchievements'; diff --git a/src/hooks/achievements/useAchievements.ts b/src/hooks/achievements/useAchievements.ts deleted file mode 100644 index a067ff7..0000000 --- a/src/hooks/achievements/useAchievements.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { AchievementData, AchievementEvent, AchievementsEvent, AchievementsScoreEvent, RequestAchievementsMessageComposer } from '@nitrots/nitro-renderer'; -import { useCallback, useEffect, useMemo, useState } from 'react'; -import { useBetween } from 'use-between'; -import { AchievementCategory, AchievementUtilities, CloneObject, SendMessageComposer } from '../../api'; -import { useMessageEvent } from '../events'; - -const useAchievementsState = () => -{ - const [ needsUpdate, setNeedsUpdate ] = useState(true); - const [ achievementCategories, setAchievementCategories ] = useState([]); - const [ selectedCategoryCode, setSelectedCategoryCode ] = useState(null); - const [ selectedAchievementId, setSelectedAchievementId ] = useState(-1); - const [ achievementScore, setAchievementScore ] = useState(0); - - const getTotalUnseen = useMemo(() => - { - let unseen = 0; - - achievementCategories.forEach(category => unseen += AchievementUtilities.getAchievementCategoryTotalUnseen(category)); - - return unseen; - }, [ achievementCategories ]); - - const getProgress = useMemo(() => - { - let progress = 0; - - achievementCategories.forEach(category => (progress += category.getProgress())); - - return progress; - }, [ achievementCategories ]); - - const getMaxProgress = useMemo(() => - { - let progress = 0; - - achievementCategories.forEach(category => (progress += category.getMaxProgress())); - - return progress; - }, [ achievementCategories ]); - - const scaledProgressPercent = useMemo(() => - { - return ~~((((getProgress - 0) * (100 - 0)) / (getMaxProgress - 0)) + 0); - }, [ getProgress, getMaxProgress ]); - - const selectedCategory = useMemo(() => - { - if(selectedCategoryCode === null) return null; - - return achievementCategories.find(category => (category.code === selectedCategoryCode)); - }, [ achievementCategories, selectedCategoryCode ]); - - const selectedAchievement = useMemo(() => - { - if((selectedAchievementId === -1) || !selectedCategory) return null; - - return selectedCategory.achievements.find(achievement => (achievement.achievementId === selectedAchievementId)); - }, [ selectedCategory, selectedAchievementId ]); - - const setAchievementSeen = useCallback((categoryCode: string, achievementId: number) => - { - setAchievementCategories(prevValue => - { - const newValue = [ ...prevValue ]; - - for(const category of newValue) - { - if(category.code !== categoryCode) continue; - - for(const achievement of category.achievements) - { - if(achievement.achievementId !== achievementId) continue; - - achievement.unseen = 0; - } - } - - return newValue; - }); - }, []); - - useMessageEvent(AchievementEvent, event => - { - const parser = event.getParser(); - const achievement = parser.achievement; - - setAchievementCategories(prevValue => - { - const newValue = [ ...prevValue ]; - const categoryIndex = newValue.findIndex(existing => (existing.code === achievement.category)); - - if(categoryIndex === -1) - { - const category = new AchievementCategory(achievement.category); - - category.achievements.push(achievement); - - newValue.push(category); - } - else - { - const category = CloneObject(newValue[categoryIndex]); - const newAchievements = [ ...category.achievements ]; - const achievementIndex = newAchievements.findIndex(existing => (existing.achievementId === achievement.achievementId)); - let previousAchievement: AchievementData = null; - - if(achievementIndex === -1) - { - newAchievements.push(achievement); - } - else - { - previousAchievement = newAchievements[achievementIndex]; - - newAchievements[achievementIndex] = achievement; - } - - if(!AchievementUtilities.getAchievementIsIgnored(achievement)) - { - achievement.unseen++; - - if(previousAchievement) achievement.unseen += previousAchievement.unseen; - } - - category.achievements = newAchievements; - - newValue[categoryIndex] = category; - } - - return newValue; - }); - }); - - useMessageEvent(AchievementsEvent, event => - { - const parser = event.getParser(); - const categories: AchievementCategory[] = []; - - for(const achievement of parser.achievements) - { - const categoryName = achievement.category; - - let existing = categories.find(category => (category.code === categoryName)); - - if(!existing) - { - existing = new AchievementCategory(categoryName); - - categories.push(existing); - } - - existing.achievements.push(achievement); - } - - setAchievementCategories(categories); - }); - - useMessageEvent(AchievementsScoreEvent, event => - { - const parser = event.getParser(); - - setAchievementScore(parser.score); - }); - - useEffect(() => - { - if(!needsUpdate) return; - - SendMessageComposer(new RequestAchievementsMessageComposer()); - - setNeedsUpdate(false); - }, [ needsUpdate ]); - - useEffect(() => - { - if(!selectedCategoryCode || (selectedAchievementId === -1)) return; - - setAchievementSeen(selectedCategoryCode, selectedAchievementId); - }, [ selectedCategoryCode, selectedAchievementId, setAchievementSeen ]); - - return { achievementCategories, selectedCategoryCode, setSelectedCategoryCode, selectedAchievementId, setSelectedAchievementId, achievementScore, getTotalUnseen, getProgress, getMaxProgress, scaledProgressPercent, selectedCategory, selectedAchievement, setAchievementSeen }; -} - -export const useAchievements = () => useBetween(useAchievementsState); diff --git a/src/hooks/avatar-editor/index.ts b/src/hooks/avatar-editor/index.ts deleted file mode 100644 index ab8a733..0000000 --- a/src/hooks/avatar-editor/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './useAvatarEditor'; -export * from './useFigureData'; diff --git a/src/hooks/avatar-editor/useAvatarEditor.ts b/src/hooks/avatar-editor/useAvatarEditor.ts deleted file mode 100644 index 82dd433..0000000 --- a/src/hooks/avatar-editor/useAvatarEditor.ts +++ /dev/null @@ -1,244 +0,0 @@ -import { AvatarEditorFigureCategory, FigureSetIdsMessageEvent, GetAvatarRenderManager, GetSessionDataManager, IFigurePartSet, IPartColor } from '@nitrots/nitro-renderer'; -import { useCallback, useEffect, useMemo, useState } from 'react'; -import { useBetween } from 'use-between'; -import { AvatarEditorThumbnailsHelper, FigureData, GetClubMemberLevel, IAvatarEditorCategory, IAvatarEditorCategoryPartItem } from '../../api'; -import { useMessageEvent } from '../events'; -import { useFigureData } from './useFigureData'; - -const MAX_PALETTES: number = 2; - -const useAvatarEditorState = () => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ avatarModels, setAvatarModels ] = useState<{ [index: string]: IAvatarEditorCategory[] }>({}); - const [ activeModelKey, setActiveModelKey ] = useState(''); - const [ maxPaletteCount, setMaxPaletteCount ] = useState(1); - const [ figureSetIds, setFigureSetIds ] = useState([]); - const [ boundFurnitureNames, setBoundFurnitureNames ] = useState([]); - const { gender, selectedParts, selectedColors, loadAvatarData, selectPart, selectColor, getFigureStringWithFace } = useFigureData(); - - const activeModel = useMemo(() => (avatarModels[activeModelKey] ?? null), [ activeModelKey, avatarModels ]); - - const selectedColorParts = useMemo(() => - { - const colorSets: { [index: string]: IPartColor[] } = {}; - - for(const setType of Object.keys(selectedColors)) - { - if(!selectedColors[setType]) continue; - - const parts: IPartColor[] = []; - - for(const paletteId of Object.keys(selectedColors[setType])) - { - const partColor = activeModel.find(category => (category.setType === setType))?.colorItems[paletteId]?.find(partColor => (partColor.id === selectedColors[setType][paletteId])); - - if(partColor) parts.push(partColor); - } - - colorSets[setType] = parts; - } - - return colorSets; - - }, [ activeModel, selectedColors ]); - - const selectEditorPart = useCallback((setType: string, partId: number) => - { - if(!setType || !setType.length) return; - - const category = activeModel.find(category => (category.setType === setType)); - - if(!category || !category.partItems || !category.partItems.length) return; - - const partItem = category.partItems.find(partItem => partItem.id === partId); - - if(!partItem) return; - - if(partItem.isClear) - { - // clear the part - return; - } - - if(GetClubMemberLevel() < partItem.partSet.clubLevel) return; - - setMaxPaletteCount(partItem.maxPaletteCount || 1); - - selectPart(setType, partId); - }, [ activeModel, selectPart ]); - - const selectEditorColor = useCallback((setType: string, paletteId: number, colorId: number) => - { - if(!setType || !setType.length) return; - - const category = activeModel.find(category => (category.setType === setType)); - - if(!category || !category.colorItems || !category.colorItems.length) return; - - const palette = category.colorItems[paletteId]; - - if(!palette || !palette.length) return; - - const partColor = palette.find(partColor => (partColor.id === colorId)); - - if(!partColor) return; - - if(GetClubMemberLevel() < partColor.clubLevel) return; - - selectColor(setType, paletteId, colorId); - }, [ activeModel, selectColor ]); - - useMessageEvent(FigureSetIdsMessageEvent, event => - { - const parser = event.getParser(); - - setFigureSetIds(parser.figureSetIds); - setBoundFurnitureNames(parser.boundsFurnitureNames); - }); - - useEffect(() => - { - AvatarEditorThumbnailsHelper.clearCache(); - }, [ selectedColorParts ]); - - useEffect(() => - { - if(!isVisible) return; - - const newAvatarModels: { [index: string]: IAvatarEditorCategory[] } = {}; - - const buildCategory = (setType: string) => - { - const partItems: IAvatarEditorCategoryPartItem[] = []; - const colorItems: IPartColor[][] = []; - - for(let i = 0; i < MAX_PALETTES; i++) colorItems.push([]); - - const set = GetAvatarRenderManager().structureData.getSetType(setType); - const palette = GetAvatarRenderManager().structureData.getPalette(set.paletteID); - - if(!set || !palette) return null; - - for(const partColor of palette.colors.getValues()) - { - if(!partColor || !partColor.isSelectable) continue; - - for(let i = 0; i < MAX_PALETTES; i++) colorItems[i].push(partColor); - - // TODO - check what this does - /* if(setType !== FigureData.FACE) - { - let i = 0; - - while(i < colorIds.length) - { - if(partColor.id === colorIds[i]) partColors[i] = partColor; - - i++; - } - } */ - } - - let mandatorySetIds: string[] = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(gender, GetClubMemberLevel()); - - const isntMandatorySet = (mandatorySetIds.indexOf(setType) === -1); - - if(isntMandatorySet) partItems.push({ id: -1, isClear: true }); - - const usesColor = (setType !== FigureData.FACE); - const partSets = set.partSets; - - for(let i = (partSets.length); i >= 0; i--) - { - const partSet = partSets.getWithIndex(i); - - if(!partSet || !partSet.isSelectable || ((partSet.gender !== gender) && (partSet.gender !== FigureData.UNISEX))) continue; - - if(partSet.isSellable && figureSetIds.indexOf(partSet.id) === -1) continue; - - let maxPaletteCount = 0; - - for(const part of partSet.parts) maxPaletteCount = Math.max(maxPaletteCount, part.colorLayerIndex); - - partItems.push({ id: partSet.id, partSet, usesColor, maxPaletteCount }); - } - - partItems.sort(partSorter(false)); - - for(let i = 0; i < MAX_PALETTES; i++) colorItems[i].sort(colorSorter); - - return { setType, partItems, colorItems }; - } - - newAvatarModels[AvatarEditorFigureCategory.GENERIC] = [ FigureData.FACE ].map(setType => buildCategory(setType)); - newAvatarModels[AvatarEditorFigureCategory.HEAD] = [ FigureData.HAIR, FigureData.HAT, FigureData.HEAD_ACCESSORIES, FigureData.EYE_ACCESSORIES, FigureData.FACE_ACCESSORIES ].map(setType => buildCategory(setType)); - newAvatarModels[AvatarEditorFigureCategory.TORSO] = [ FigureData.SHIRT, FigureData.CHEST_PRINTS, FigureData.JACKET, FigureData.CHEST_ACCESSORIES ].map(setType => buildCategory(setType)); - newAvatarModels[AvatarEditorFigureCategory.LEGS] = [ FigureData.TROUSERS, FigureData.SHOES, FigureData.TROUSER_ACCESSORIES ].map(setType => buildCategory(setType)); - newAvatarModels[AvatarEditorFigureCategory.WARDROBE] = []; - - setAvatarModels(newAvatarModels); - setActiveModelKey(AvatarEditorFigureCategory.GENERIC); - }, [ isVisible, gender, figureSetIds ]); - - useEffect(() => - { - if(!isVisible) return; - - loadAvatarData(GetSessionDataManager().figure, GetSessionDataManager().gender); - }, [ isVisible, loadAvatarData ]); - - return { isVisible, setIsVisible, avatarModels, activeModelKey, setActiveModelKey, selectedParts, selectedColors, maxPaletteCount, selectedColorParts, selectEditorPart, selectEditorColor, getFigureStringWithFace }; -} - -export const useAvatarEditor = () => useBetween(useAvatarEditorState); - -const partSorter = (hcFirst: boolean) => -{ - return (a: { partSet: IFigurePartSet, usesColor: boolean, isClear?: boolean }, b: { partSet: IFigurePartSet, usesColor: boolean, isClear?: boolean }) => - { - const clubLevelA = (!a.partSet ? -1 : a.partSet.clubLevel); - const clubLevelB = (!b.partSet ? -1 : b.partSet.clubLevel); - const isSellableA = (!a.partSet ? false : a.partSet.isSellable); - const isSellableB = (!b.partSet ? false : b.partSet.isSellable); - - if(isSellableA && !isSellableB) return 1; - - if(isSellableB && !isSellableA) return -1; - - if(hcFirst) - { - if(clubLevelA > clubLevelB) return -1; - - if(clubLevelA < clubLevelB) return 1; - } - else - { - if(clubLevelA < clubLevelB) return -1; - - if(clubLevelA > clubLevelB) return 1; - } - - if(a.partSet.id < b.partSet.id) return -1; - - if(a.partSet.id > b.partSet.id) return 1; - - return 0; - } -} - -const colorSorter = (a: IPartColor, b: IPartColor) => -{ - const clubLevelA = (!a ? -1 : a.clubLevel); - const clubLevelB = (!b ? -1 : b.clubLevel); - - if(clubLevelA < clubLevelB) return -1; - - if(clubLevelA > clubLevelB) return 1; - - if(a.index < b.index) return -1; - - if(a.index > b.index) return 1; - - return 0; -} diff --git a/src/hooks/avatar-editor/useFigureData.ts b/src/hooks/avatar-editor/useFigureData.ts deleted file mode 100644 index 5d68730..0000000 --- a/src/hooks/avatar-editor/useFigureData.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { useCallback, useState } from 'react'; -import { FigureData } from '../../api'; - -const useFigureDataState = () => -{ - const [ selectedParts, setSelectedParts ] = useState<{ [index: string]: number }>({}); - const [ selectedColors, setSelectedColors ] = useState<{ [index: string]: number[] }>({}); - const [ gender, setGender ] = useState(FigureData.MALE); - - const loadAvatarData = useCallback((figureString: string, gender: string) => - { - const parse = (figure: string) => - { - const sets = figure.split('.'); - - if(!sets || !sets.length) return; - - const partSets: { [index: string]: number } = {}; - const colorSets: { [index: string]: number[] } = {}; - - for(const set of sets) - { - const parts = set.split('-'); - - if(!parts.length) continue; - - const setType = parts[0]; - const partId = 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); - - if(partId >= 0) partSets[setType] = partId; - - if(colorIds.length) colorSets[setType] = colorIds; - } - - return { partSets, colorSets }; - } - - const { partSets, colorSets } = parse(figureString); - - setSelectedParts(partSets); - setSelectedColors(colorSets); - setGender(gender); - }, []); - - const selectPart = useCallback((setType: string, partId: number) => - { - if(!setType || !setType.length) return; - - setSelectedParts(prevValue => - { - const newValue = { ...prevValue }; - - newValue[setType] = partId; - - return newValue; - }); - }, []); - - const selectColor = useCallback((setType: string, paletteId: number, colorId: number) => - { - if(!setType || !setType.length) return; - - setSelectedColors(prevValue => - { - const newValue = { ...prevValue }; - - if(!newValue[setType]) newValue[setType] = []; - - if(!newValue[setType][paletteId]) newValue[setType][paletteId] = 0; - - newValue[setType][paletteId] = colorId; - - return newValue; - }) - }, []); - - const getFigureStringWithFace = useCallback((overridePartId: number, override: boolean = true) => - { - const figureSets = [ FigureData.FACE ].map(setType => - { - // Determine the part ID, with an option to override if the set type matches. - let partId = (setType === FigureData.FACE && override) ? overridePartId : selectedParts[setType]; - const colors = selectedColors[setType] || []; - - // Construct the figure set string, including the type, part ID, and any colors. - let figureSet = `${ setType }-${ partId }`; - if (partId >= 0) - { - figureSet += colors.map(color => `-${ color }`).join(''); - } - - return figureSet; - }); - - // Join all figure sets with '.', ensuring to only add '.' between items, not at the end. - return figureSets.join('.'); - }, [ selectedParts, selectedColors ]); - - return { selectedParts, selectedColors, gender, loadAvatarData, selectPart, selectColor, getFigureStringWithFace }; -} - -export const useFigureData = useFigureDataState; diff --git a/src/hooks/camera/index.ts b/src/hooks/camera/index.ts deleted file mode 100644 index 20bea9c..0000000 --- a/src/hooks/camera/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useCamera'; diff --git a/src/hooks/camera/useCamera.ts b/src/hooks/camera/useCamera.ts deleted file mode 100644 index 78b2eb4..0000000 --- a/src/hooks/camera/useCamera.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { GetRoomCameraWidgetManager, InitCameraMessageEvent, IRoomCameraWidgetEffect, RequestCameraConfigurationComposer, RoomCameraWidgetManagerEvent } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { useBetween } from 'use-between'; -import { CameraPicture, SendMessageComposer } from '../../api'; -import { useMessageEvent, useNitroEvent } from '../events'; - -const useCameraState = () => -{ - const [ availableEffects, setAvailableEffects ] = useState([]); - const [ cameraRoll, setCameraRoll ] = useState([]); - const [ selectedPictureIndex, setSelectedPictureIndex ] = useState(-1); - const [ myLevel, setMyLevel ] = useState(10); - const [ price, setPrice ] = useState<{ credits: number, duckets: number, publishDucketPrice: number }>(null); - - useNitroEvent(RoomCameraWidgetManagerEvent.INITIALIZED, event => - { - setAvailableEffects(Array.from(GetRoomCameraWidgetManager().effects.values())); - }); - - useMessageEvent(InitCameraMessageEvent, event => - { - const parser = event.getParser(); - - setPrice({ credits: parser.creditPrice, duckets: parser.ducketPrice, publishDucketPrice: parser.publishDucketPrice }); - }); - - useEffect(() => - { - if(!GetRoomCameraWidgetManager().isLoaded) - { - GetRoomCameraWidgetManager().init(); - - SendMessageComposer(new RequestCameraConfigurationComposer()); - - return; - } - }, []); - - return { availableEffects, cameraRoll, setCameraRoll, selectedPictureIndex, setSelectedPictureIndex, myLevel, price }; -} - -export const useCamera = () => useBetween(useCameraState); diff --git a/src/hooks/catalog/index.ts b/src/hooks/catalog/index.ts deleted file mode 100644 index 75d2984..0000000 --- a/src/hooks/catalog/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './useCatalog'; -export * from './useCatalogPlaceMultipleItems'; -export * from './useCatalogSkipPurchaseConfirmation'; diff --git a/src/hooks/catalog/useCatalog.ts b/src/hooks/catalog/useCatalog.ts deleted file mode 100644 index 2b9d209..0000000 --- a/src/hooks/catalog/useCatalog.ts +++ /dev/null @@ -1,913 +0,0 @@ -import { BuildersClubFurniCountMessageEvent, BuildersClubPlaceRoomItemMessageComposer, BuildersClubPlaceWallItemMessageComposer, BuildersClubQueryFurniCountMessageComposer, BuildersClubSubscriptionStatusMessageEvent, CatalogPageMessageEvent, CatalogPagesListEvent, CatalogPublishedMessageEvent, ClubGiftInfoEvent, CreateLinkEvent, FrontPageItem, FurniturePlaceComposer, FurniturePlacePaintComposer, GetCatalogIndexComposer, GetCatalogPageComposer, GetClubGiftInfo, GetGiftWrappingConfigurationComposer, GetRoomEngine, GetTickerTime, GiftWrappingConfigurationEvent, GuildMembershipsMessageEvent, HabboClubOffersMessageEvent, LegacyDataType, LimitedEditionSoldOutEvent, MarketplaceMakeOfferResult, NodeData, ProductOfferEvent, PurchaseErrorMessageEvent, PurchaseFromCatalogComposer, PurchaseNotAllowedMessageEvent, PurchaseOKMessageEvent, RoomControllerLevel, RoomEngineObjectPlacedEvent, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType, RoomObjectVariable, RoomPreviewer, SellablePetPalettesMessageEvent, Vector3d } from '@nitrots/nitro-renderer'; -import { useCallback, useEffect, useRef, useState } from 'react'; -import { useBetween } from 'use-between'; -import { BuilderFurniPlaceableStatus, CatalogNode, CatalogPage, CatalogPetPalette, CatalogType, DispatchUiEvent, FurniCategory, GetFurnitureData, GetProductDataForLocalization, GetRoomSession, GiftWrappingConfiguration, ICatalogNode, ICatalogOptions, ICatalogPage, IPageLocalization, IProduct, IPurchasableOffer, IPurchaseOptions, LocalizeText, NotificationAlertType, Offer, PageLocalization, PlacedObjectPurchaseData, PlaySound, Product, ProductTypeEnum, RequestedPage, SearchResult, SendMessageComposer, SoundNames } from '../../api'; -import { CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent, CatalogPurchasedEvent, InventoryFurniAddedEvent } from '../../events'; -import { useMessageEvent, useNitroEvent, useUiEvent } from '../events'; -import { useNotification } from '../notification'; -import { useCatalogPlaceMultipleItems } from './useCatalogPlaceMultipleItems'; -import { useCatalogSkipPurchaseConfirmation } from './useCatalogSkipPurchaseConfirmation'; - -const DUMMY_PAGE_ID_FOR_OFFER_SEARCH = -12345678; -const DRAG_AND_DROP_ENABLED = true; - -const useCatalogState = () => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ isBusy, setIsBusy ] = useState(false); - const [ pageId, setPageId ] = useState(-1); - const [ previousPageId, setPreviousPageId ] = useState(-1); - const [ currentType, setCurrentType ] = useState(CatalogType.NORMAL); - const [ rootNode, setRootNode ] = useState(null); - const [ offersToNodes, setOffersToNodes ] = useState>(null); - const [ currentPage, setCurrentPage ] = useState(null); - const [ currentOffer, setCurrentOffer ] = useState(null); - const [ activeNodes, setActiveNodes ] = useState([]); - const [ searchResult, setSearchResult ] = useState(null); - const [ frontPageItems, setFrontPageItems ] = useState([]); - const [ roomPreviewer, setRoomPreviewer ] = useState(null); - const [ navigationHidden, setNavigationHidden ] = useState(false); - const [ purchaseOptions, setPurchaseOptions ] = useState({ quantity: 1, extraData: null, extraParamRequired: false, previewStuffData: null }); - const [ catalogOptions, setCatalogOptions ] = useState({}); - const [ objectMoverRequested, setObjectMoverRequested ] = useState(false); - const [ catalogPlaceMultipleObjects, setCatalogPlaceMultipleObjects ] = useCatalogPlaceMultipleItems(); - const [ catalogSkipPurchaseConfirmation, setCatalogSkipPurchaseConfirmation ] = useCatalogSkipPurchaseConfirmation(); - const [ purchasableOffer, setPurchaseableOffer ] = useState(null); - const [ placedObjectPurchaseData, setPlacedObjectPurchaseData ] = useState(null); - const [ furniCount, setFurniCount ] = useState(0); - const [ furniLimit, setFurniLimit ] = useState(0); - const [ maxFurniLimit, setMaxFurniLimit ] = useState(0); - const [ secondsLeft, setSecondsLeft ] = useState(0); - const [ updateTime, setUpdateTime ] = useState(0); - const [ secondsLeftWithGrace, setSecondsLeftWithGrace ] = useState(0); - const { simpleAlert = null } = useNotification(); - const requestedPage = useRef(new RequestedPage()); - - const resetState = useCallback(() => - { - setPageId(-1); - setPreviousPageId(-1); - setRootNode(null); - setOffersToNodes(null); - setCurrentPage(null); - setCurrentOffer(null); - setActiveNodes([]); - setSearchResult(null); - setFrontPageItems([]); - setIsVisible(false); - }, []); - - const getBuilderFurniPlaceableStatus = useCallback((offer: IPurchasableOffer) => - { - if(!offer) return BuilderFurniPlaceableStatus.MISSING_OFFER; - - if((furniCount < 0) || (furniCount >= furniLimit)) return BuilderFurniPlaceableStatus.FURNI_LIMIT_REACHED; - - const roomSession = GetRoomSession(); - - if(!roomSession) return BuilderFurniPlaceableStatus.NOT_IN_ROOM; - - if(!roomSession.isRoomOwner) return BuilderFurniPlaceableStatus.NOT_ROOM_OWNER; - - if(secondsLeft <= 0) - { - const roomEngine = GetRoomEngine(); - - let objectCount = roomEngine.getRoomObjectCount(roomSession.roomId, RoomObjectCategory.UNIT); - - while(objectCount > 0) - { - const roomObject = roomEngine.getRoomObjectByIndex(roomSession.roomId, objectCount, RoomObjectCategory.UNIT); - const userData = roomSession.userDataManager.getUserDataByIndex(roomObject.id); - - if(userData && (userData.type === RoomObjectType.USER) && (userData.roomIndex !== roomSession.ownRoomIndex) && !userData.isModerator) return BuilderFurniPlaceableStatus.VISITORS_IN_ROOM; - - objectCount--; - } - } - - return BuilderFurniPlaceableStatus.OKAY; - }, [ furniCount, furniLimit, secondsLeft ]); - - const isDraggable = useCallback((offer: IPurchasableOffer) => - { - const roomSession = GetRoomSession(); - - if(((DRAG_AND_DROP_ENABLED && roomSession && offer.page && (offer.page.layoutCode !== 'sold_ltd_items') && (currentType === CatalogType.NORMAL) && (roomSession.isRoomOwner || (roomSession.isGuildRoom && (roomSession.controllerLevel >= RoomControllerLevel.GUILD_MEMBER)))) || ((currentType === CatalogType.BUILDER) && (getBuilderFurniPlaceableStatus(offer) === BuilderFurniPlaceableStatus.OKAY))) && (offer.pricingModel !== Offer.PRICING_MODEL_BUNDLE) && (offer.product.productType !== ProductTypeEnum.EFFECT) && (offer.product.productType !== ProductTypeEnum.HABBO_CLUB)) return true; - - return false; - }, [ currentType, getBuilderFurniPlaceableStatus ]); - - const requestOfferToMover = useCallback((offer: IPurchasableOffer) => - { - if(!isDraggable(offer)) return; - - const product = offer.product; - - if(!product) return; - - let category = 0; - - switch(product.productType) - { - case ProductTypeEnum.FLOOR: - category = RoomObjectCategory.FLOOR; - break; - case ProductTypeEnum.WALL: - category = RoomObjectCategory.WALL; - break; - } - - if(GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.CATALOG, -(offer.offerId), category, product.productClassId, product.extraParam)) - { - setPurchaseableOffer(offer); - setObjectMoverRequested(true); - - setIsVisible(false); - } - }, [ isDraggable ]); - - const resetRoomPaint = useCallback((planeType: string, type: string) => - { - const roomEngine = GetRoomEngine(); - - let wallType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE); - let floorType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE); - let landscapeType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE); - - wallType = (wallType && wallType.length) ? wallType : '101'; - floorType = (floorType && floorType.length) ? floorType : '101'; - landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1'; - - switch(planeType) - { - case 'floor': - roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, type, wallType, landscapeType, true); - return; - case 'wallpaper': - roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, floorType, type, landscapeType, true); - return; - case 'landscape': - roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, floorType, wallType, type, true); - return; - default: - roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, floorType, wallType, landscapeType, true); - return; - } - }, []); - - const cancelObjectMover = useCallback(() => - { - if(!purchasableOffer) return; - - GetRoomEngine().cancelRoomObjectInsert(); - - setObjectMoverRequested(false); - setPurchaseableOffer(null); - }, [ purchasableOffer ]); - - const resetObjectMover = useCallback((flag: boolean = true) => - { - setObjectMoverRequested(prevValue => - { - if(prevValue && flag) - { - CreateLinkEvent('catalog/open'); - } - - return false; - }); - }, []); - - const resetPlacedOfferData = useCallback((flag: boolean = false) => - { - if(!flag) resetObjectMover(); - - setPlacedObjectPurchaseData(prevValue => - { - if(prevValue) - { - switch(prevValue.category) - { - case RoomObjectCategory.FLOOR: - GetRoomEngine().removeRoomObjectFloor(prevValue.roomId, prevValue.objectId); - break; - case RoomObjectCategory.WALL: { - - switch(prevValue.furniData.className) - { - case 'floor': - case 'wallpaper': - case 'landscape': - resetRoomPaint('reset', ''); - break; - default: - GetRoomEngine().removeRoomObjectWall(prevValue.roomId, prevValue.objectId); - break; - } - break; - } - default: - GetRoomEngine().deleteRoomObject(prevValue.objectId, prevValue.category); - break; - } - } - - return null; - }); - }, [ resetObjectMover, resetRoomPaint ]); - - const getNodeById = useCallback((id: number, node: ICatalogNode) => - { - if((node.pageId === id) && (node !== rootNode)) return node; - - for(const child of node.children) - { - const found = (getNodeById(id, child) as ICatalogNode); - - if(found) return found; - } - - return null; - }, [ rootNode ]); - - const getNodeByName = useCallback((name: string, node: ICatalogNode) => - { - if((node.pageName === name) && (node !== rootNode)) return node; - - for(const child of node.children) - { - const found = (getNodeByName(name, child) as ICatalogNode); - - if(found) return found; - } - - return null; - }, [ rootNode ]); - - const getNodesByOfferId = useCallback((offerId: number, flag: boolean = false) => - { - if(!offersToNodes || !offersToNodes.size) return null; - - if(flag) - { - const nodes: ICatalogNode[] = []; - const offers = offersToNodes.get(offerId); - - if(offers && offers.length) for(const offer of offers) (offer.isVisible && nodes.push(offer)); - - if(nodes.length) return nodes; - } - - return offersToNodes.get(offerId); - }, [ offersToNodes ]); - - const loadCatalogPage = useCallback((pageId: number, offerId: number) => - { - if(pageId < 0) return; - - setIsBusy(true); - setPageId(pageId); - - if(pageId > -1) SendMessageComposer(new GetCatalogPageComposer(pageId, offerId, currentType)); - }, [ currentType ]); - - const showCatalogPage = useCallback((pageId: number, layoutCode: string, localization: IPageLocalization, offers: IPurchasableOffer[], offerId: number, acceptSeasonCurrencyAsCredits: boolean) => - { - const catalogPage = (new CatalogPage(pageId, layoutCode, localization, offers, acceptSeasonCurrencyAsCredits) as ICatalogPage); - - setCurrentPage(catalogPage); - setPreviousPageId(prevValue => ((pageId !== -1) ? pageId : prevValue)); - setNavigationHidden(false); - - if((offerId > -1) && catalogPage.offers.length) - { - for(const offer of catalogPage.offers) - { - if(offer.offerId !== offerId) continue; - - setCurrentOffer(offer) - - break; - } - } - }, []); - - const activateNode = useCallback((targetNode: ICatalogNode, offerId: number = -1) => - { - cancelObjectMover(); - - if(targetNode.parent.pageName === 'root') - { - if(targetNode.children.length) - { - for(const child of targetNode.children) - { - if(!child.isVisible) continue; - - targetNode = child; - - break; - } - } - } - - const nodes: ICatalogNode[] = []; - - let node = targetNode; - - while(node && (node.pageName !== 'root')) - { - nodes.push(node); - - node = node.parent; - } - - nodes.reverse(); - - setActiveNodes(prevValue => - { - const isActive = (prevValue.indexOf(targetNode) >= 0); - const isOpen = targetNode.isOpen; - - for(const existing of prevValue) - { - existing.deactivate(); - - if(nodes.indexOf(existing) === -1) existing.close(); - } - - for(const n of nodes) - { - n.activate(); - - if(n.parent) n.open(); - - if((n === targetNode.parent) && n.children.length) n.open(); - } - - if(isActive && isOpen) targetNode.close(); - else targetNode.open(); - - return nodes; - }); - - if(targetNode.pageId > -1) loadCatalogPage(targetNode.pageId, offerId); - }, [ setActiveNodes, loadCatalogPage, cancelObjectMover ]); - - const openPageById = useCallback((id: number) => - { - if(id !== -1) setSearchResult(null); - - if(!isVisible) - { - requestedPage.current.requestById = id; - - setIsVisible(true); - } - else - { - const node = getNodeById(id, rootNode); - - if(node) activateNode(node); - } - }, [ isVisible, rootNode, getNodeById, activateNode ]); - - const openPageByName = useCallback((name: string) => - { - setSearchResult(null); - - if(!isVisible) - { - requestedPage.current.requestByName = name; - - setIsVisible(true); - } - else - { - const node = getNodeByName(name, rootNode); - - if(node) activateNode(node); - } - }, [ isVisible, rootNode, getNodeByName, activateNode ]); - - const openPageByOfferId = useCallback((offerId: number) => - { - setSearchResult(null); - - if(!isVisible) - { - requestedPage.current.requestedByOfferId = offerId; - - setIsVisible(true); - } - else - { - const nodes = getNodesByOfferId(offerId); - - if(!nodes || !nodes.length) return; - - activateNode(nodes[0], offerId); - } - }, [ isVisible, getNodesByOfferId, activateNode ]); - - const refreshBuilderStatus = useCallback(() => - { - - }, []); - - useMessageEvent(CatalogPagesListEvent, event => - { - const parser = event.getParser(); - const offers: Map = new Map(); - - const getCatalogNode = (node: NodeData, depth: number, parent: ICatalogNode) => - { - const catalogNode = (new CatalogNode(node, depth, parent) as ICatalogNode); - - for(const offerId of catalogNode.offerIds) - { - if(offers.has(offerId)) offers.get(offerId).push(catalogNode); - else offers.set(offerId, [ catalogNode ]); - } - - depth++; - - for(const child of node.children) catalogNode.addChild(getCatalogNode(child, depth, catalogNode)); - - return catalogNode; - } - - setRootNode(getCatalogNode(parser.root, 0, null)); - setOffersToNodes(offers); - }); - - useMessageEvent(CatalogPageMessageEvent, event => - { - const parser = event.getParser(); - - if(parser.catalogType !== currentType) return; - - const purchasableOffers: IPurchasableOffer[] = []; - - for(const offer of parser.offers) - { - const products: IProduct[] = []; - const productData = GetProductDataForLocalization(offer.localizationId); - - for(const product of offer.products) - { - const furnitureData = GetFurnitureData(product.furniClassId, product.productType); - - products.push(new Product(product.productType, product.furniClassId, product.extraParam, product.productCount, productData, furnitureData, product.uniqueLimitedItem, product.uniqueLimitedSeriesSize, product.uniqueLimitedItemsLeft)); - } - - if(!products.length) continue; - - const purchasableOffer = new Offer(offer.offerId, offer.localizationId, offer.rent, offer.priceCredits, offer.priceActivityPoints, offer.priceActivityPointsType, offer.giftable, offer.clubLevel, products, offer.bundlePurchaseAllowed); - - if((currentType === CatalogType.NORMAL) || ((purchasableOffer.pricingModel !== Offer.PRICING_MODEL_BUNDLE) && (purchasableOffer.pricingModel !== Offer.PRICING_MODEL_MULTI))) purchasableOffers.push(purchasableOffer); - } - - if(parser.frontPageItems && parser.frontPageItems.length) setFrontPageItems(parser.frontPageItems); - - setIsBusy(false); - - if(pageId === parser.pageId) - { - showCatalogPage(parser.pageId, parser.layoutCode, new PageLocalization(parser.localization.images.concat(), parser.localization.texts.concat()), purchasableOffers, parser.offerId, parser.acceptSeasonCurrencyAsCredits); - } - }); - - useMessageEvent(PurchaseOKMessageEvent, event => - { - const parser = event.getParser(); - - DispatchUiEvent(new CatalogPurchasedEvent(parser.offer)); - }); - - useMessageEvent(PurchaseErrorMessageEvent, event => - { - const parser = event.getParser(); - - DispatchUiEvent(new CatalogPurchaseFailureEvent(parser.code)); - }); - - useMessageEvent(PurchaseNotAllowedMessageEvent, event => - { - const parser = event.getParser(); - - DispatchUiEvent(new CatalogPurchaseNotAllowedEvent(parser.code)); - }); - - useMessageEvent(LimitedEditionSoldOutEvent, event => - { - const parser = event.getParser(); - - DispatchUiEvent(new CatalogPurchaseSoldOutEvent()); - }); - - useMessageEvent(ProductOfferEvent, event => - { - const parser = event.getParser(); - const offerData = parser.offer; - - if(!offerData || !offerData.products.length) return; - - const offerProductData = offerData.products[0]; - - if(offerProductData.uniqueLimitedItem) - { - // update unique - } - - const products: IProduct[] = []; - const productData = GetProductDataForLocalization(offerData.localizationId); - - for(const product of offerData.products) - { - const furnitureData = GetFurnitureData(product.furniClassId, product.productType); - - products.push(new Product(product.productType, product.furniClassId, product.extraParam, product.productCount, productData, furnitureData, product.uniqueLimitedItem, product.uniqueLimitedSeriesSize, product.uniqueLimitedItemsLeft)); - } - - const offer = new Offer(offerData.offerId, offerData.localizationId, offerData.rent, offerData.priceCredits, offerData.priceActivityPoints, offerData.priceActivityPointsType, offerData.giftable, offerData.clubLevel, products, offerData.bundlePurchaseAllowed); - - if(!((currentType === CatalogType.NORMAL) || ((offer.pricingModel !== Offer.PRICING_MODEL_BUNDLE) && (offer.pricingModel !== Offer.PRICING_MODEL_MULTI)))) return; - - offer.page = currentPage; - - setCurrentOffer(offer); - - if(offer.product && (offer.product.productType === ProductTypeEnum.WALL)) - { - setPurchaseOptions(prevValue => - { - const newValue = { ...prevValue }; - - newValue.extraData =( offer.product.extraParam || null); - - return newValue; - }); - } - - // (this._isObjectMoverRequested) && (this._purchasableOffer) - }); - - useMessageEvent(SellablePetPalettesMessageEvent, event => - { - const parser = event.getParser(); - const petPalette = new CatalogPetPalette(parser.productCode, parser.palettes.slice()); - - setCatalogOptions(prevValue => - { - const petPalettes = []; - - if(prevValue.petPalettes) petPalettes.push(...prevValue.petPalettes); - - for(let i = 0; i < petPalettes.length; i++) - { - const palette = petPalettes[i]; - - if(palette.breed === petPalette.breed) - { - petPalettes.splice(i, 1); - - break; - } - } - - petPalettes.push(petPalette); - - return { ...prevValue, petPalettes }; - }); - }); - - useMessageEvent(HabboClubOffersMessageEvent, event => - { - const parser = event.getParser(); - - setCatalogOptions(prevValue => - { - const clubOffers = parser.offers; - - return { ...prevValue, clubOffers }; - }); - }); - - useMessageEvent(GuildMembershipsMessageEvent, event => - { - const parser = event.getParser(); - - setCatalogOptions(prevValue => - { - const groups = parser.groups; - - return { ...prevValue, groups }; - }); - }); - - useMessageEvent(GiftWrappingConfigurationEvent, event => - { - const parser = event.getParser(); - - setCatalogOptions(prevValue => - { - const giftConfiguration = new GiftWrappingConfiguration(parser); - - return { ...prevValue, giftConfiguration }; - }); - }); - - useMessageEvent(MarketplaceMakeOfferResult, event => - { - const parser = event.getParser(); - - if(!parser) return; - - let title = ''; - if(parser.result === 1) - { - title = LocalizeText('inventory.marketplace.result.title.success'); - } - else - { - title = LocalizeText('inventory.marketplace.result.title.failure'); - } - - const message = LocalizeText(`inventory.marketplace.result.${ parser.result }`); - - simpleAlert(message, NotificationAlertType.DEFAULT, null, null, title); - }); - - useMessageEvent(ClubGiftInfoEvent, event => - { - const parser = event.getParser(); - - setCatalogOptions(prevValue => - { - const clubGifts = parser; - - return { ...prevValue, clubGifts }; - }); - }); - - useMessageEvent(CatalogPublishedMessageEvent, event => - { - const wasVisible = isVisible; - - resetState(); - - if(wasVisible) simpleAlert(LocalizeText('catalog.alert.published.description'), NotificationAlertType.ALERT, null, null, LocalizeText('catalog.alert.published.title')); - }); - - useMessageEvent(BuildersClubFurniCountMessageEvent, event => - { - const parser = event.getParser(); - - setFurniCount(parser.furniCount); - - refreshBuilderStatus(); - }); - - useMessageEvent(BuildersClubSubscriptionStatusMessageEvent, event => - { - const parser = event.getParser(); - - setFurniLimit(parser.furniLimit); - setMaxFurniLimit(parser.maxFurniLimit); - setSecondsLeft(parser.secondsLeft); - setUpdateTime(GetTickerTime()); - setSecondsLeftWithGrace(parser.secondsLeftWithGrace); - - refreshBuilderStatus(); - }); - - useUiEvent(CatalogPurchasedEvent.PURCHASE_SUCCESS, event => PlaySound(SoundNames.CREDITS)); - - useNitroEvent(RoomEngineObjectPlacedEvent.PLACED, event => - { - if(!objectMoverRequested || (event.type !== RoomEngineObjectPlacedEvent.PLACED)) return; - - resetPlacedOfferData(true); - - if(!purchasableOffer) - { - resetObjectMover(); - - return; - } - - let placed = false; - - const product = purchasableOffer.product; - - if(event.category === RoomObjectCategory.WALL) - { - switch(product.furnitureData.className) - { - case 'floor': - case 'wallpaper': - case 'landscape': - placed = (event.placedOnFloor || event.placedOnWall); - break; - default: - placed = event.placedInRoom; - break; - } - } - else - { - placed = event.placedInRoom; - } - - if(!placed) - { - resetObjectMover(); - - return; - } - - setPlacedObjectPurchaseData(new PlacedObjectPurchaseData(event.roomId, event.objectId, event.category, event.wallLocation, event.x, event.y, event.direction, purchasableOffer)); - - switch(currentType) - { - case CatalogType.NORMAL: { - switch(event.category) - { - case RoomObjectCategory.FLOOR: - GetRoomEngine().addFurnitureFloor(event.roomId, event.objectId, product.productClassId, new Vector3d(event.x, event.y, event.z), new Vector3d(event.direction), 0, new LegacyDataType()); - break; - case RoomObjectCategory.WALL: { - switch(product.furnitureData.className) - { - case 'floor': - case 'wallpaper': - case 'landscape': - resetRoomPaint(product.furnitureData.className, product.extraParam); - break; - default: - GetRoomEngine().addFurnitureWall(event.roomId, event.objectId, product.productClassId, new Vector3d(event.x, event.y, event.z), new Vector3d(event.direction * 45), 0, event.instanceData, 0); - break; - } - } - } - - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(roomObject) roomObject.model.setValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER, 0.5); - - if(catalogSkipPurchaseConfirmation) - { - SendMessageComposer(new PurchaseFromCatalogComposer(pageId, purchasableOffer.offerId, product.extraParam, 1)); - - if(catalogPlaceMultipleObjects) requestOfferToMover(purchasableOffer); - } - else - { - // confirm - - if(catalogPlaceMultipleObjects) requestOfferToMover(purchasableOffer); - } - break; - } - case CatalogType.BUILDER: { - let pageId = purchasableOffer.page.pageId; - - if(pageId === DUMMY_PAGE_ID_FOR_OFFER_SEARCH) - { - pageId = -1; - } - - switch(event.category) - { - case RoomObjectCategory.FLOOR: - SendMessageComposer(new BuildersClubPlaceRoomItemMessageComposer(pageId, purchasableOffer.offerId, product.extraParam, event.x, event.y, event.direction)); - break; - case RoomObjectCategory.WALL: - SendMessageComposer(new BuildersClubPlaceWallItemMessageComposer(pageId, purchasableOffer.offerId, product.extraParam, event.wallLocation)); - break; - } - - if(catalogPlaceMultipleObjects) requestOfferToMover(purchasableOffer); - break; - } - } - }); - - useUiEvent(InventoryFurniAddedEvent.FURNI_ADDED, event => - { - const roomEngine = GetRoomEngine(); - - if(!placedObjectPurchaseData || (placedObjectPurchaseData.productClassId !== event.spriteId) || (placedObjectPurchaseData.roomId !== roomEngine.activeRoomId)) return; - - switch(event.category) - { - case FurniCategory.FLOOR: { - const floorType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE); - - if(placedObjectPurchaseData.extraParam !== floorType) SendMessageComposer(new FurniturePlacePaintComposer(event.id)); - break; - } - case FurniCategory.WALL_PAPER: { - const wallType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE); - - if(placedObjectPurchaseData.extraParam !== wallType) SendMessageComposer(new FurniturePlacePaintComposer(event.id)); - break; - } - case FurniCategory.LANDSCAPE: { - const landscapeType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE); - - if(placedObjectPurchaseData.extraParam !== landscapeType) SendMessageComposer(new FurniturePlacePaintComposer(event.id)); - break; - } - default: - SendMessageComposer(new FurniturePlaceComposer(event.id, placedObjectPurchaseData.category, placedObjectPurchaseData.wallLocation, placedObjectPurchaseData.x, placedObjectPurchaseData.y, placedObjectPurchaseData.direction)); - } - - if(!catalogPlaceMultipleObjects) resetPlacedOfferData(); - }); - - useEffect(() => - { - return () => setCurrentOffer(null); - }, [ currentPage ]); - - useEffect(() => - { - if(!isVisible || !rootNode || !offersToNodes || !requestedPage.current) return; - - switch(requestedPage.current.requestType) - { - case RequestedPage.REQUEST_TYPE_NONE: - if(currentPage) return; - - if(rootNode.isBranch) - { - for(const child of rootNode.children) - { - if(child && child.isVisible) - { - activateNode(child); - - return; - } - } - } - return; - case RequestedPage.REQUEST_TYPE_ID: - openPageById(requestedPage.current.requestById); - requestedPage.current.resetRequest(); - return; - case RequestedPage.REQUEST_TYPE_OFFER: - openPageByOfferId(requestedPage.current.requestedByOfferId); - requestedPage.current.resetRequest(); - return; - case RequestedPage.REQUEST_TYPE_NAME: - openPageByName(requestedPage.current.requestByName); - requestedPage.current.resetRequest(); - return; - } - }, [ isVisible, rootNode, offersToNodes, currentPage, activateNode, openPageById, openPageByOfferId, openPageByName ]); - - useEffect(() => - { - if(!searchResult && currentPage && (currentPage.pageId === -1)) openPageById(previousPageId); - }, [ searchResult, currentPage, previousPageId, openPageById ]); - - useEffect(() => - { - if(!currentOffer) return; - - setPurchaseOptions({ quantity: 1, extraData: null, extraParamRequired: false, previewStuffData: null }); - }, [ currentOffer ]); - - useEffect(() => - { - if(!isVisible || rootNode) return; - - SendMessageComposer(new GetGiftWrappingConfigurationComposer()); - SendMessageComposer(new GetClubGiftInfo()); - SendMessageComposer(new GetCatalogIndexComposer(currentType)); - SendMessageComposer(new BuildersClubQueryFurniCountMessageComposer()); - }, [ isVisible, rootNode, currentType ]); - - useEffect(() => - { - setRoomPreviewer(new RoomPreviewer(GetRoomEngine(), ++RoomPreviewer.PREVIEW_COUNTER)); - - return () => - { - setRoomPreviewer(prevValue => - { - prevValue.dispose(); - - return null; - }); - } - }, []); - - return { isVisible, setIsVisible, isBusy, pageId, previousPageId, currentType, rootNode, offersToNodes, currentPage, setCurrentPage, currentOffer, setCurrentOffer, activeNodes, searchResult, setSearchResult, frontPageItems, roomPreviewer, navigationHidden, setNavigationHidden, purchaseOptions, setPurchaseOptions, catalogOptions, setCatalogOptions, getNodeById, getNodeByName, activateNode, openPageById, openPageByName, openPageByOfferId, requestOfferToMover }; -} - -export const useCatalog = () => useBetween(useCatalogState); diff --git a/src/hooks/catalog/useCatalogPlaceMultipleItems.ts b/src/hooks/catalog/useCatalogPlaceMultipleItems.ts deleted file mode 100644 index 39cfd28..0000000 --- a/src/hooks/catalog/useCatalogPlaceMultipleItems.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { useBetween } from 'use-between'; -import { LocalStorageKeys } from '../../api'; -import { useLocalStorage } from '../useLocalStorage'; - -const useCatalogPlaceMultipleItemsState = () => useLocalStorage(LocalStorageKeys.CATALOG_PLACE_MULTIPLE_OBJECTS, false); - -export const useCatalogPlaceMultipleItems = () => useBetween(useCatalogPlaceMultipleItemsState); diff --git a/src/hooks/catalog/useCatalogSkipPurchaseConfirmation.ts b/src/hooks/catalog/useCatalogSkipPurchaseConfirmation.ts deleted file mode 100644 index b2d69a2..0000000 --- a/src/hooks/catalog/useCatalogSkipPurchaseConfirmation.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { useBetween } from 'use-between'; -import { LocalStorageKeys } from '../../api'; -import { useLocalStorage } from '../useLocalStorage'; - -const useCatalogSkipPurchaseConfirmationState = () => useLocalStorage(LocalStorageKeys.CATALOG_SKIP_PURCHASE_CONFIRMATION, false); - -export const useCatalogSkipPurchaseConfirmation = () => useBetween(useCatalogSkipPurchaseConfirmationState); diff --git a/src/hooks/chat-history/index.ts b/src/hooks/chat-history/index.ts deleted file mode 100644 index 970d90f..0000000 --- a/src/hooks/chat-history/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useChatHistory'; diff --git a/src/hooks/chat-history/useChatHistory.ts b/src/hooks/chat-history/useChatHistory.ts deleted file mode 100644 index b8545a0..0000000 --- a/src/hooks/chat-history/useChatHistory.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { GetGuestRoomResultEvent, NewConsoleMessageEvent, RoomInviteEvent, RoomSessionEvent } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { useBetween } from 'use-between'; -import { ChatEntryType, ChatHistoryCurrentDate, IChatEntry, IRoomHistoryEntry, MessengerHistoryCurrentDate } from '../../api'; -import { useMessageEvent, useNitroEvent } from '../events'; - -const CHAT_HISTORY_MAX = 1000; -const ROOM_HISTORY_MAX = 10; -const MESSENGER_HISTORY_MAX = 1000; - -let CHAT_HISTORY_COUNTER: number = 0; -let MESSENGER_HISTORY_COUNTER: number = 0; - -const useChatHistoryState = () => -{ - const [ chatHistory, setChatHistory ] = useState([]); - const [ roomHistory, setRoomHistory ] = useState([]); - const [ messengerHistory, setMessengerHistory ] = useState([]); - const [ needsRoomInsert, setNeedsRoomInsert ] = useState(false); - - const addChatEntry = (entry: IChatEntry) => - { - entry.id = CHAT_HISTORY_COUNTER++; - - setChatHistory(prevValue => - { - const newValue = [ ...prevValue ]; - - newValue.push(entry); - - if(newValue.length > CHAT_HISTORY_MAX) newValue.shift(); - - return newValue; - }); - } - - const addRoomHistoryEntry = (entry: IRoomHistoryEntry) => - { - setRoomHistory(prevValue => - { - const newValue = [ ...prevValue ]; - - newValue.push(entry); - - if(newValue.length > ROOM_HISTORY_MAX) newValue.shift(); - - return newValue; - }); - } - - const addMessengerEntry = (entry: IChatEntry) => - { - entry.id = MESSENGER_HISTORY_COUNTER++; - - setMessengerHistory(prevValue => - { - const newValue = [ ...prevValue ]; - - newValue.push(entry); - - if(newValue.length > MESSENGER_HISTORY_MAX) newValue.shift(); - - return newValue; - }); - } - - useNitroEvent(RoomSessionEvent.STARTED, event => setNeedsRoomInsert(true)); - - useMessageEvent(GetGuestRoomResultEvent, event => - { - if(!needsRoomInsert) return; - - const parser = event.getParser(); - - if(roomHistory.length) - { - if(roomHistory[(roomHistory.length - 1)].id === parser.data.roomId) return; - } - - addChatEntry({ id: -1, webId: -1, entityId: -1, name: parser.data.roomName, timestamp: ChatHistoryCurrentDate(), type: ChatEntryType.TYPE_ROOM_INFO, roomId: parser.data.roomId }); - - addRoomHistoryEntry({ id: parser.data.roomId, name: parser.data.roomName }); - - setNeedsRoomInsert(false); - }); - - useMessageEvent(NewConsoleMessageEvent, event => - { - const parser = event.getParser(); - - addMessengerEntry({ id: -1, webId: parser.senderId, entityId: -1, name: '', message: parser.messageText, roomId: -1, timestamp: MessengerHistoryCurrentDate(parser.secondsSinceSent), type: ChatEntryType.TYPE_IM }); - }); - - useMessageEvent(RoomInviteEvent, event => - { - const parser = event.getParser(); - - addMessengerEntry({ id: -1, webId: parser.senderId, entityId: -1, name: '', message: parser.messageText, roomId: -1, timestamp: MessengerHistoryCurrentDate(), type: ChatEntryType.TYPE_IM }); - }); - - return { addChatEntry, chatHistory, roomHistory, messengerHistory }; -} - -export const useChatHistory = () => useBetween(useChatHistoryState); diff --git a/src/hooks/events/index.ts b/src/hooks/events/index.ts deleted file mode 100644 index 6d9903b..0000000 --- a/src/hooks/events/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './useEventDispatcher'; -export * from './useMessageEvent'; -export * from './useNitroEvent'; -export * from './useUiEvent'; diff --git a/src/hooks/events/useEventDispatcher.tsx b/src/hooks/events/useEventDispatcher.tsx deleted file mode 100644 index 60555f2..0000000 --- a/src/hooks/events/useEventDispatcher.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { IEventDispatcher, NitroEvent } from '@nitrots/nitro-renderer'; -import { useEffect } from 'react'; - -export const useEventDispatcher = (type: string | string[], eventDispatcher: IEventDispatcher, handler: (event: T) => void, enabled: boolean = true) => -{ - useEffect(() => - { - if(!enabled) return; - - if(Array.isArray(type)) - { - type.map(name => eventDispatcher.addEventListener(name, handler)); - } - else - { - eventDispatcher.addEventListener(type, handler); - } - - return () => - { - if(Array.isArray(type)) - { - type.map(name => eventDispatcher.removeEventListener(name, handler)); - } - else - { - eventDispatcher.removeEventListener(type, handler); - } - } - }, [ type, eventDispatcher, enabled, handler ]); -} diff --git a/src/hooks/events/useMessageEvent.tsx b/src/hooks/events/useMessageEvent.tsx deleted file mode 100644 index 9c4b031..0000000 --- a/src/hooks/events/useMessageEvent.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { GetCommunication, IMessageEvent, MessageEvent } from '@nitrots/nitro-renderer'; -import { useEffect } from 'react'; - -export const useMessageEvent = (eventType: typeof MessageEvent, handler: (event: T) => void) => -{ - useEffect(() => - { - //@ts-ignore - const event = new eventType(handler); - - GetCommunication().registerMessageEvent(event); - - return () => GetCommunication().removeMessageEvent(event); - }, [ eventType, handler ]); -} diff --git a/src/hooks/events/useNitroEvent.tsx b/src/hooks/events/useNitroEvent.tsx deleted file mode 100644 index d8cf60b..0000000 --- a/src/hooks/events/useNitroEvent.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import { GetEventDispatcher, NitroEvent } from '@nitrots/nitro-renderer'; -import { useEventDispatcher } from './useEventDispatcher'; - -export const useNitroEvent = (type: string | string[], handler: (event: T) => void, enabled = true) => useEventDispatcher(type, GetEventDispatcher(), handler, enabled); diff --git a/src/hooks/events/useUiEvent.tsx b/src/hooks/events/useUiEvent.tsx deleted file mode 100644 index 02c0aff..0000000 --- a/src/hooks/events/useUiEvent.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { NitroEvent } from '@nitrots/nitro-renderer'; -import { UI_EVENT_DISPATCHER } from '../../api'; -import { useEventDispatcher } from './useEventDispatcher'; - -export const useUiEvent = (type: string | string[], handler: (event: T) => void, enabled: boolean = true) => useEventDispatcher(type, UI_EVENT_DISPATCHER, handler, enabled); diff --git a/src/hooks/friends/index.ts b/src/hooks/friends/index.ts deleted file mode 100644 index 45c983f..0000000 --- a/src/hooks/friends/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './useFriends'; -export * from './useMessenger'; diff --git a/src/hooks/friends/useFriends.ts b/src/hooks/friends/useFriends.ts deleted file mode 100644 index 603dc54..0000000 --- a/src/hooks/friends/useFriends.ts +++ /dev/null @@ -1,252 +0,0 @@ -import { AcceptFriendMessageComposer, DeclineFriendMessageComposer, FollowFriendMessageComposer, FriendListFragmentEvent, FriendListUpdateComposer, FriendListUpdateEvent, FriendParser, FriendRequestsEvent, GetFriendRequestsComposer, GetSessionDataManager, MessengerInitComposer, MessengerInitEvent, NewFriendRequestEvent, RequestFriendComposer, SetRelationshipStatusComposer } from '@nitrots/nitro-renderer'; -import { useEffect, useMemo, useState } from 'react'; -import { useBetween } from 'use-between'; -import { CloneObject, MessengerFriend, MessengerRequest, MessengerSettings, SendMessageComposer } from '../../api'; -import { useMessageEvent } from '../events'; - -const useFriendsState = () => -{ - const [ friends, setFriends ] = useState([]); - const [ requests, setRequests ] = useState([]); - const [ sentRequests, setSentRequests ] = useState([]); - const [ dismissedRequestIds, setDismissedRequestIds ] = useState([]); - const [ settings, setSettings ] = useState(null); - - const onlineFriends = useMemo(() => - { - const onlineFriends = friends.filter(friend => friend.online); - - onlineFriends.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase())); - - return onlineFriends; - }, [ friends ]); - - const offlineFriends = useMemo(() => - { - const offlineFriends = friends.filter(friend => !friend.online); - - offlineFriends.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase())); - - return offlineFriends; - }, [ friends ]); - - const followFriend = (friend: MessengerFriend) => SendMessageComposer(new FollowFriendMessageComposer(friend.id)); - - const updateRelationship = (friend: MessengerFriend, type: number) => ((type !== friend.relationshipStatus) && SendMessageComposer(new SetRelationshipStatusComposer(friend.id, type))); - - const getFriend = (userId: number) => - { - for(const friend of friends) - { - if(friend.id === userId) return friend; - } - - return null; - } - - const canRequestFriend = (userId: number) => - { - if(userId === GetSessionDataManager().userId) return false; - - if(getFriend(userId)) return false; - - if(requests.find(request => (request.requesterUserId === userId))) return false; - - if(sentRequests.indexOf(userId) >= 0) return false; - - return true; - } - - const requestFriend = (userId: number, userName: string) => - { - if(!canRequestFriend(userId)) return false; - - setSentRequests(prevValue => - { - const newSentRequests = [ ...prevValue ]; - - newSentRequests.push(userId); - - return newSentRequests; - }); - - SendMessageComposer(new RequestFriendComposer(userName)); - } - - const requestResponse = (requestId: number, flag: boolean) => - { - if(requestId === -1 && !flag) - { - SendMessageComposer(new DeclineFriendMessageComposer(true)); - - setRequests([]); - } - else - { - setRequests(prevValue => - { - const newRequests = [ ...prevValue ]; - const index = newRequests.findIndex(request => (request.id === requestId)); - - if(index === -1) return prevValue; - - if(flag) - { - SendMessageComposer(new AcceptFriendMessageComposer(newRequests[index].id)); - } - else - { - SendMessageComposer(new DeclineFriendMessageComposer(false, newRequests[index].id)); - } - - newRequests.splice(index, 1); - - return newRequests; - }); - } - } - - useMessageEvent(MessengerInitEvent, event => - { - const parser = event.getParser(); - - setSettings(new MessengerSettings( - parser.userFriendLimit, - parser.normalFriendLimit, - parser.extendedFriendLimit, - parser.categories)); - - SendMessageComposer(new GetFriendRequestsComposer()); - }); - - useMessageEvent(FriendListFragmentEvent, event => - { - const parser = event.getParser(); - - setFriends(prevValue => - { - const newValue = [ ...prevValue ]; - - for(const friend of parser.fragment) - { - const index = newValue.findIndex(existingFriend => (existingFriend.id === friend.id)); - const newFriend = new MessengerFriend(); - newFriend.populate(friend); - - if(index > -1) newValue[index] = newFriend; - else newValue.push(newFriend); - } - - return newValue; - }); - }); - - useMessageEvent(FriendListUpdateEvent, event => - { - const parser = event.getParser(); - - setFriends(prevValue => - { - const newValue = [ ...prevValue ]; - - const processUpdate = (friend: FriendParser) => - { - const index = newValue.findIndex(existingFriend => (existingFriend.id === friend.id)); - - if(index === -1) - { - const newFriend = new MessengerFriend(); - newFriend.populate(friend); - - newValue.unshift(newFriend); - } - else - { - newValue[index].populate(friend); - } - } - - for(const friend of parser.addedFriends) processUpdate(friend); - - for(const friend of parser.updatedFriends) processUpdate(friend); - - for(const removedFriendId of parser.removedFriendIds) - { - const index = newValue.findIndex(existingFriend => (existingFriend.id === removedFriendId)); - - if(index > -1) newValue.splice(index, 1); - } - - return newValue; - }); - }); - - useMessageEvent(FriendRequestsEvent, event => - { - const parser = event.getParser(); - - setRequests(prevValue => - { - const newValue = [ ...prevValue ]; - - for(const request of parser.requests) - { - const index = newValue.findIndex(existing => (existing.requesterUserId === request.requesterUserId)); - - if(index > 0) - { - newValue[index] = CloneObject(newValue[index]); - newValue[index].populate(request); - } - else - { - const newRequest = new MessengerRequest(); - newRequest.populate(request); - - newValue.push(newRequest); - } - } - - return newValue; - }); - }); - - useMessageEvent(NewFriendRequestEvent, event => - { - const parser = event.getParser(); - const request = parser.request; - - setRequests(prevValue => - { - const newRequests = [ ...prevValue ]; - - const index = newRequests.findIndex(existing => (existing.requesterUserId === request.requesterUserId)); - - if(index === -1) - { - const newRequest = new MessengerRequest(); - newRequest.populate(request); - - newRequests.push(newRequest); - } - - return newRequests; - }); - }); - - useEffect(() => - { - SendMessageComposer(new MessengerInitComposer()); - - const interval = setInterval(() => SendMessageComposer(new FriendListUpdateComposer()), 120000); - - return () => - { - clearInterval(interval); - } - }, []); - - return { friends, requests, sentRequests, dismissedRequestIds, setDismissedRequestIds, settings, onlineFriends, offlineFriends, getFriend, canRequestFriend, requestFriend, requestResponse, followFriend, updateRelationship }; -} - -export const useFriends = () => useBetween(useFriendsState); diff --git a/src/hooks/friends/useMessenger.ts b/src/hooks/friends/useMessenger.ts deleted file mode 100644 index 2b668d5..0000000 --- a/src/hooks/friends/useMessenger.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { GetSessionDataManager, NewConsoleMessageEvent, RoomInviteErrorEvent, RoomInviteEvent, SendMessageComposer as SendMessageComposerPacket } from '@nitrots/nitro-renderer'; -import { useEffect, useMemo, useState } from 'react'; -import { useBetween } from 'use-between'; -import { CloneObject, LocalizeText, MessengerIconState, MessengerThread, MessengerThreadChat, NotificationAlertType, PlaySound, SendMessageComposer, SoundNames } from '../../api'; -import { useMessageEvent } from '../events'; -import { useNotification } from '../notification'; -import { useFriends } from './useFriends'; - -const useMessengerState = () => -{ - const [ messageThreads, setMessageThreads ] = useState([]); - const [ activeThreadId, setActiveThreadId ] = useState(-1); - const [ hiddenThreadIds, setHiddenThreadIds ] = useState([]); - const [ iconState, setIconState ] = useState(MessengerIconState.HIDDEN); - const { getFriend = null } = useFriends(); - const { simpleAlert = null } = useNotification(); - - const visibleThreads = useMemo(() => messageThreads.filter(thread => (hiddenThreadIds.indexOf(thread.threadId) === -1)), [ messageThreads, hiddenThreadIds ]); - const activeThread = useMemo(() => ((activeThreadId > 0) && visibleThreads.find(thread => (thread.threadId === activeThreadId) || null)), [ activeThreadId, visibleThreads ]); - - const getMessageThread = (userId: number) => - { - let thread = messageThreads.find(thread => (thread.participant && (thread.participant.id === userId))); - - if(!thread) - { - const friend = getFriend(userId); - - if(!friend) return null; - - thread = new MessengerThread(friend); - - thread.addMessage(null, LocalizeText('messenger.moderationinfo'), 0, null, MessengerThreadChat.SECURITY_NOTIFICATION); - - thread.setRead(); - - setMessageThreads(prevValue => - { - const newValue = [ ...prevValue ]; - - newValue.push(thread); - - return newValue; - }); - } - else - { - const hiddenIndex = hiddenThreadIds.indexOf(thread.threadId); - - if(hiddenIndex >= 0) - { - setHiddenThreadIds(prevValue => - { - const newValue = [ ...prevValue ]; - - newValue.splice(hiddenIndex, 1); - - return newValue; - }) - } - } - - return thread; - } - - const closeThread = (threadId: number) => - { - setHiddenThreadIds(prevValue => - { - const newValue = [ ...prevValue ]; - - if(newValue.indexOf(threadId) >= 0) return prevValue; - - newValue.push(threadId); - - return newValue; - }); - - if(activeThreadId === threadId) setActiveThreadId(-1); - } - - const sendMessage = (thread: MessengerThread, senderId: number, messageText: string, secondsSinceSent: number = 0, extraData: string = null, messageType: number = MessengerThreadChat.CHAT) => - { - if(!thread || !messageText || !messageText.length) return; - - const ownMessage = (senderId === GetSessionDataManager().userId); - - if(ownMessage && (messageText.length <= 255)) SendMessageComposer(new SendMessageComposerPacket(thread.participant.id, messageText)); - - setMessageThreads(prevValue => - { - const newValue = [ ...prevValue ]; - const index = newValue.findIndex(newThread => (newThread.threadId === thread.threadId)); - - if(index === -1) return prevValue; - - thread = CloneObject(newValue[index]); - - if(ownMessage && (thread.groups.length === 1)) PlaySound(SoundNames.MESSENGER_NEW_THREAD); - - thread.addMessage(((messageType === MessengerThreadChat.ROOM_INVITE) ? null : senderId), messageText, secondsSinceSent, extraData, messageType); - - if(activeThreadId === thread.threadId) thread.setRead(); - - newValue[index] = thread; - - if(!ownMessage && thread.unread) PlaySound(SoundNames.MESSENGER_MESSAGE_RECEIVED); - - return newValue; - }); - } - - useMessageEvent(NewConsoleMessageEvent, event => - { - const parser = event.getParser(); - const thread = getMessageThread(parser.senderId); - - if(!thread) return; - - sendMessage(thread, parser.senderId, parser.messageText, parser.secondsSinceSent, parser.extraData); - }); - - useMessageEvent(RoomInviteEvent, event => - { - const parser = event.getParser(); - const thread = getMessageThread(parser.senderId); - - if(!thread) return; - - sendMessage(thread, parser.senderId, parser.messageText, 0, null, MessengerThreadChat.ROOM_INVITE); - }); - - useMessageEvent(RoomInviteErrorEvent, event => - { - const parser = event.getParser(); - - simpleAlert(`Received room invite error: ${ parser.errorCode },recipients: ${ parser.failedRecipients }`, NotificationAlertType.DEFAULT, null, null, LocalizeText('friendlist.alert.title')); - }); - - useEffect(() => - { - if(activeThreadId <= 0) return; - - setMessageThreads(prevValue => - { - const newValue = [ ...prevValue ]; - const index = newValue.findIndex(newThread => (newThread.threadId === activeThreadId)); - - if(index >= 0) - { - newValue[index] = CloneObject(newValue[index]); - - newValue[index].setRead(); - } - - return newValue; - }); - }, [ activeThreadId ]); - - useEffect(() => - { - setIconState(prevValue => - { - if(!visibleThreads.length) return MessengerIconState.HIDDEN; - - let isUnread = false; - - for(const thread of visibleThreads) - { - if(thread.unreadCount > 0) - { - isUnread = true; - - break; - } - } - - if(isUnread) return MessengerIconState.UNREAD; - - return MessengerIconState.SHOW; - }); - }, [ visibleThreads ]); - - return { messageThreads, activeThread, iconState, visibleThreads, getMessageThread, setActiveThreadId, closeThread, sendMessage }; -} - -export const useMessenger = () => useBetween(useMessengerState); diff --git a/src/hooks/game-center/index.ts b/src/hooks/game-center/index.ts deleted file mode 100644 index 59f0472..0000000 --- a/src/hooks/game-center/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useGameCenter'; diff --git a/src/hooks/game-center/useGameCenter.ts b/src/hooks/game-center/useGameCenter.ts deleted file mode 100644 index 0b9dbcb..0000000 --- a/src/hooks/game-center/useGameCenter.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Game2AccountGameStatusMessageEvent, Game2AccountGameStatusMessageParser, GameConfigurationData, GameListMessageEvent, GameStatusMessageEvent, GetGameListMessageComposer, LoadGameUrlEvent } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { useBetween } from 'use-between'; -import { SendMessageComposer, VisitDesktop } from '../../api'; -import { useMessageEvent } from '../events'; - -const useGameCenterState = () => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ games, setGames ] = useState(null); - const [ selectedGame, setSelectedGame ] = useState(null); - const [ accountStatus, setAccountStatus ] = useState(null); - const [ gameOffline, setGameOffline ] = useState(false); - const [ gameURL, setGameURL ] = useState(null); - - useMessageEvent(GameListMessageEvent, event => - { - let parser = event.getParser(); - - if(!parser || parser && !parser.games.length) return; - - setSelectedGame(parser.games[0]); - - setGames(parser.games); - }); - - useMessageEvent(Game2AccountGameStatusMessageEvent, event => - { - let parser = event.getParser(); - - if(!parser) return; - - setAccountStatus(parser); - }); - - useMessageEvent(GameStatusMessageEvent, event => - { - let parser = event.getParser(); - - if(!parser) return; - - setGameOffline(parser.isInMaintenance); - }) - - useMessageEvent(LoadGameUrlEvent, event => - { - let parser = event.getParser(); - - if(!parser) return; - - switch(parser.gameTypeId) - { - case 2: - return console.log('snowwar') - default: - return setGameURL(parser.url); - } - }); - - useEffect(()=> - { - if(isVisible) - { - SendMessageComposer(new GetGameListMessageComposer()); - VisitDesktop(); - } - else - { - // dispose or wtv - } - },[ isVisible ]); - - return { - isVisible, setIsVisible, - games, - accountStatus, - selectedGame, setSelectedGame, - gameOffline, - gameURL, setGameURL - } -} - -export const useGameCenter = () => useBetween(useGameCenterState); diff --git a/src/hooks/groups/index.ts b/src/hooks/groups/index.ts deleted file mode 100644 index 95ef733..0000000 --- a/src/hooks/groups/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useGroup'; diff --git a/src/hooks/groups/useGroup.ts b/src/hooks/groups/useGroup.ts deleted file mode 100644 index 7a9fd22..0000000 --- a/src/hooks/groups/useGroup.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { GroupBadgePartsComposer, GroupBadgePartsEvent } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { useBetween } from 'use-between'; -import { IGroupCustomize, SendMessageComposer } from '../../api'; -import { useMessageEvent } from '../events'; - -const useGroupState = () => -{ - const [ groupCustomize, setGroupCustomize ] = useState(null); - - useMessageEvent(GroupBadgePartsEvent, event => - { - const parser = event.getParser(); - - const customize: IGroupCustomize = { - badgeBases: [], - badgeSymbols: [], - badgePartColors: [], - groupColorsA: [], - groupColorsB: [] - }; - - parser.bases.forEach((images, id) => customize.badgeBases.push({ id, images })); - parser.symbols.forEach((images, id) => customize.badgeSymbols.push({ id, images })); - parser.partColors.forEach((color, id) => customize.badgePartColors.push({ id, color })); - parser.colorsA.forEach((color, id) => customize.groupColorsA.push({ id, color })); - parser.colorsB.forEach((color, id) => customize.groupColorsB.push({ id, color })); - - const CompareId = (a: { id: number }, b: { id: number }) => - { - if(a.id < b.id) return -1; - - if(a.id > b.id) return 1; - - return 0; - } - - customize.badgeBases.sort(CompareId); - customize.badgeSymbols.sort(CompareId); - customize.badgePartColors.sort(CompareId); - customize.groupColorsA.sort(CompareId); - customize.groupColorsB.sort(CompareId); - - setGroupCustomize(customize); - }); - - useEffect(() => - { - SendMessageComposer(new GroupBadgePartsComposer()); - }, []); - - return { groupCustomize }; -} - -export const useGroup = () => useBetween(useGroupState); diff --git a/src/hooks/help/index.ts b/src/hooks/help/index.ts deleted file mode 100644 index f03e754..0000000 --- a/src/hooks/help/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useHelp'; diff --git a/src/hooks/help/useHelp.ts b/src/hooks/help/useHelp.ts deleted file mode 100644 index 1c74b62..0000000 --- a/src/hooks/help/useHelp.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { CallForHelpDisabledNotifyMessageEvent, CallForHelpPendingCallsDeletedMessageEvent, CallForHelpPendingCallsMessageEvent, CallForHelpReplyMessageEvent, CallForHelpResultMessageEvent, DeletePendingCallsForHelpMessageComposer, GetPendingCallsForHelpMessageComposer, IssueCloseNotificationMessageEvent, SanctionStatusEvent, SanctionStatusMessageParser } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { useBetween } from 'use-between'; -import { CallForHelpResult, GetCloseReasonKey, IHelpReport, LocalizeText, NotificationAlertType, ReportState, ReportType, SendMessageComposer } from '../../api'; -import { useMessageEvent } from '../events'; -import { useNotification } from '../notification'; - -const useHelpState = () => -{ - const [ activeReport, setActiveReport ] = useState(null); - const [ sanctionInfo, setSanctionInfo ] = useState(null); - const { simpleAlert = null, showConfirm = null } = useNotification(); - - const report = (type: number, options: Partial) => - { - const newReport: IHelpReport = { - reportType: type, - reportedUserId: -1, - reportedChats: [], - cfhCategory: -1, - cfhTopic: -1, - roomId: -1, - roomName: '', - messageId: -1, - threadId: -1, - groupId: -1, - extraData: '', - roomObjectId: -1, - message: '', - currentStep: 0 - }; - - switch(type) - { - case ReportType.BULLY: - case ReportType.EMERGENCY: - case ReportType.IM: - newReport.reportedUserId = options.reportedUserId; - newReport.currentStep = ReportState.SELECT_CHATS; - break; - case ReportType.ROOM: - newReport.roomId = options.roomId; - newReport.roomName = options.roomName; - newReport.currentStep = ReportState.SELECT_TOPICS; - break; - case ReportType.THREAD: - newReport.groupId = options.groupId; - newReport.threadId = options.threadId; - newReport.currentStep = ReportState.SELECT_TOPICS; - break; - case ReportType.MESSAGE: - newReport.groupId = options.groupId; - newReport.threadId = options.threadId; - newReport.messageId = options.messageId; - newReport.currentStep = ReportState.SELECT_TOPICS; - break; - case ReportType.PHOTO: - newReport.extraData = options.extraData; - newReport.roomId = options.roomId; - newReport.reportedUserId = options.reportedUserId; - newReport.roomObjectId = options.roomObjectId; - newReport.currentStep = ReportState.SELECT_TOPICS; - break; - case ReportType.GUIDE: - break; - } - - setActiveReport(newReport); - } - - useMessageEvent(CallForHelpResultMessageEvent, event => - { - const parser = event.getParser(); - - let message = parser.messageText; - - switch(parser.resultType) - { - case CallForHelpResult.TOO_MANY_PENDING_CALLS_CODE: - SendMessageComposer(new GetPendingCallsForHelpMessageComposer()); - simpleAlert(LocalizeText('help.cfh.error.pending'), NotificationAlertType.MODERATION, null, null, LocalizeText('help.cfh.error.title')); - break; - case CallForHelpResult.HAS_ABUSIVE_CALL_CODE: - simpleAlert(LocalizeText('help.cfh.error.abusive'), NotificationAlertType.MODERATION, null, null, LocalizeText('help.cfh.error.title')); - break; - default: - if(message.trim().length === 0) - { - message = LocalizeText('help.cfh.sent.text'); - } - - simpleAlert(message, NotificationAlertType.MODERATION, null, null, LocalizeText('help.cfh.sent.title')); - } - }); - - useMessageEvent(IssueCloseNotificationMessageEvent, event => - { - const parser = event.getParser(); - - const message = parser.messageText.length === 0 ? LocalizeText('help.cfh.closed.' + GetCloseReasonKey(parser.closeReason)) : parser.messageText; - - simpleAlert(message, NotificationAlertType.MODERATION, null, null, LocalizeText('mod.alert.title')); - }); - - useMessageEvent(CallForHelpPendingCallsMessageEvent, event => - { - const parser = event.getParser(); - - if(parser.count > 0) - { - showConfirm(LocalizeText('help.emergency.pending.title') + '\n' + parser.pendingCalls[0].message, () => - { - SendMessageComposer(new DeletePendingCallsForHelpMessageComposer()); - }, null, LocalizeText('help.emergency.pending.button.discard'), LocalizeText('help.emergency.pending.button.keep'), LocalizeText('help.emergency.pending.message.subtitle')); - } - }); - - useMessageEvent(CallForHelpPendingCallsDeletedMessageEvent, event => - { - const message = 'Your pending calls were deleted'; // todo: add localization - - simpleAlert(message, NotificationAlertType.MODERATION, null, null, LocalizeText('mod.alert.title')); - }); - - useMessageEvent(CallForHelpReplyMessageEvent, event => - { - const parser = event.getParser(); - - simpleAlert(parser.message, NotificationAlertType.MODERATION, null, null, LocalizeText('help.cfh.reply.title')); - }); - - useMessageEvent(CallForHelpDisabledNotifyMessageEvent, event => - { - const parser = event.getParser(); - - simpleAlert(LocalizeText('help.emergency.global_mute.message'), NotificationAlertType.MODERATION, parser.infoUrl, LocalizeText('help.emergency.global_mute.link'), LocalizeText('help.emergency.global_mute.subtitle')) - }); - - useMessageEvent(SanctionStatusEvent, event => - { - const parser = event.getParser(); - - setSanctionInfo(parser); - }); - - return { activeReport, setActiveReport, sanctionInfo, setSanctionInfo, report }; -} - -export const useHelp = () => useBetween(useHelpState); diff --git a/src/hooks/index.ts b/src/hooks/index.ts deleted file mode 100644 index 58b4afc..0000000 --- a/src/hooks/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -export * from './UseMountEffect'; -export * from './achievements'; -export * from './avatar-editor'; -export * from './camera'; -export * from './catalog'; -export * from './chat-history'; -export * from './events'; -export * from './friends'; -export * from './game-center'; -export * from './groups'; -export * from './help'; -export * from './inventory'; -export * from './mod-tools'; -export * from './navigator'; -export * from './notification'; -export * from './purse'; -export * from './rooms'; -export * from './rooms/engine'; -export * from './rooms/promotes'; -export * from './rooms/widgets'; -export * from './rooms/widgets/furniture'; -export * from './session'; -export * from './useLocalStorage'; -export * from './useSharedVisibility'; -export * from './wired'; diff --git a/src/hooks/inventory/index.ts b/src/hooks/inventory/index.ts deleted file mode 100644 index 4e70819..0000000 --- a/src/hooks/inventory/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './useInventoryBadges'; -export * from './useInventoryBots'; -export * from './useInventoryFurni'; -export * from './useInventoryPets'; -export * from './useInventoryTrade'; -export * from './useInventoryUnseenTracker'; diff --git a/src/hooks/inventory/useInventoryBadges.ts b/src/hooks/inventory/useInventoryBadges.ts deleted file mode 100644 index 766c668..0000000 --- a/src/hooks/inventory/useInventoryBadges.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { BadgeReceivedEvent, BadgesEvent, RequestBadgesComposer, SetActivatedBadgesComposer } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { useBetween } from 'use-between'; -import { GetConfigurationValue, SendMessageComposer, UnseenItemCategory } from '../../api'; -import { useMessageEvent } from '../events'; -import { useSharedVisibility } from '../useSharedVisibility'; -import { useInventoryUnseenTracker } from './useInventoryUnseenTracker'; - -const useInventoryBadgesState = () => -{ - const [ needsUpdate, setNeedsUpdate ] = useState(true); - const [ badgeCodes, setBadgeCodes ] = useState([]); - const [ badgeIds, setBadgeIds ] = useState>(new Map()); - const [ activeBadgeCodes, setActiveBadgeCodes ] = useState([]); - const [ selectedBadgeCode, setSelectedBadgeCode ] = useState(null); - const { isVisible = false, activate = null, deactivate = null } = useSharedVisibility(); - const { isUnseen = null, resetCategory = null } = useInventoryUnseenTracker(); - - const maxBadgeCount = GetConfigurationValue('user.badges.max.slots', 5); - const isWearingBadge = (badgeCode: string) => (activeBadgeCodes.indexOf(badgeCode) >= 0); - const canWearBadges = () => (activeBadgeCodes.length < maxBadgeCount); - - const toggleBadge = (badgeCode: string) => - { - setActiveBadgeCodes(prevValue => - { - const newValue = [ ...prevValue ]; - - const index = newValue.indexOf(badgeCode); - - if(index === -1) - { - if(!canWearBadges()) return prevValue; - - newValue.push(badgeCode); - } - else - { - newValue.splice(index, 1); - } - - const composer = new SetActivatedBadgesComposer(); - - for(let i = 0; i < maxBadgeCount; i++) composer.addActivatedBadge(newValue[i] ?? ''); - - SendMessageComposer(composer); - - return newValue; - }); - } - - const getBadgeId = (badgeCode: string) => - { - const index = badgeCodes.indexOf(badgeCode); - - if(index === -1) return 0; - - return (badgeIds.get(badgeCode) ?? 0); - } - - useMessageEvent(BadgesEvent, event => - { - const parser = event.getParser(); - const badgesToAdd: string[] = []; - - setBadgeIds(prevValue => - { - const newValue = new Map(prevValue); - - parser.getAllBadgeCodes().forEach(code => - { - const exists = badgeCodes.indexOf(code) >= 0; - const badgeId = parser.getBadgeId(code); - - newValue.set(code, badgeId); - - if(exists) return; - - badgesToAdd.push(code); - }); - - return newValue; - }); - - setActiveBadgeCodes(parser.getActiveBadgeCodes()); - setBadgeCodes(prev => [ ...prev, ...badgesToAdd ]); - }); - - useMessageEvent(BadgeReceivedEvent, event => - { - const parser = event.getParser(); - const unseen = isUnseen(UnseenItemCategory.BADGE, parser.badgeId); - - setBadgeCodes(prevValue => - { - const newValue = [ ...prevValue ]; - - if(unseen) newValue.unshift(parser.badgeCode) - else newValue.push(parser.badgeCode); - - return newValue; - }); - - setBadgeIds(prevValue => - { - const newValue = new Map(prevValue); - - newValue.set(parser.badgeCode, parser.badgeId); - - return newValue; - }); - }); - - useEffect(() => - { - if(!badgeCodes || !badgeCodes.length) return; - - setSelectedBadgeCode(prevValue => - { - let newValue = prevValue; - - if(newValue && (badgeCodes.indexOf(newValue) === -1)) newValue = null; - - if(!newValue) newValue = badgeCodes[0]; - - return newValue; - }); - }, [ badgeCodes ]); - - useEffect(() => - { - if(!isVisible) return; - - return () => - { - resetCategory(UnseenItemCategory.BADGE); - } - }, [ isVisible, resetCategory ]); - - useEffect(() => - { - if(!isVisible || !needsUpdate) return; - - SendMessageComposer(new RequestBadgesComposer()); - - setNeedsUpdate(false); - }, [ isVisible, needsUpdate ]); - - return { badgeCodes, activeBadgeCodes, selectedBadgeCode, setSelectedBadgeCode, isWearingBadge, canWearBadges, toggleBadge, getBadgeId, activate, deactivate }; -} - -export const useInventoryBadges = () => useBetween(useInventoryBadgesState); diff --git a/src/hooks/inventory/useInventoryBots.ts b/src/hooks/inventory/useInventoryBots.ts deleted file mode 100644 index 55663a5..0000000 --- a/src/hooks/inventory/useInventoryBots.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { BotAddedToInventoryEvent, BotData, BotInventoryMessageEvent, BotRemovedFromInventoryEvent, CreateLinkEvent, GetBotInventoryComposer } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { useBetween } from 'use-between'; -import { IBotItem, SendMessageComposer, UnseenItemCategory, cancelRoomObjectPlacement, getPlacingItemId } from '../../api'; -import { useMessageEvent } from '../events'; -import { useSharedVisibility } from '../useSharedVisibility'; -import { useInventoryUnseenTracker } from './useInventoryUnseenTracker'; - -const useInventoryBotsState = () => -{ - const [ needsUpdate, setNeedsUpdate ] = useState(true); - const [ botItems, setBotItems ] = useState([]); - const [ selectedBot, setSelectedBot ] = useState(null); - const { isVisible = false, activate = null, deactivate = null } = useSharedVisibility(); - const { isUnseen = null, resetCategory = null } = useInventoryUnseenTracker(); - - useMessageEvent(BotInventoryMessageEvent, event => - { - const parser = event.getParser(); - - setBotItems(prevValue => - { - const newValue = [ ...prevValue ]; - const existingIds = newValue.map(item => item.botData.id); - const addedDatas: BotData[] = []; - - for(const botData of parser.items.values()) ((existingIds.indexOf(botData.id) === -1) && addedDatas.push(botData)); - - for(const existingId of existingIds) - { - let remove = true; - - for(const botData of parser.items.values()) - { - if(botData.id === existingId) - { - remove = false; - - break; - } - } - - if(!remove) continue; - - const index = newValue.findIndex(item => (item.botData.id === existingId)); - const botItem = newValue[index]; - - if((index === -1) || !botItem) continue; - - if(getPlacingItemId() === botItem.botData.id) - { - cancelRoomObjectPlacement(); - - CreateLinkEvent('inventory/open'); - } - - newValue.splice(index, 1); - } - - for(const botData of addedDatas) - { - const botItem = { botData } as IBotItem; - const unseen = isUnseen(UnseenItemCategory.BOT, botData.id); - - if(unseen) newValue.unshift(botItem); - else newValue.push(botItem); - } - - return newValue; - }); - }); - - useMessageEvent(BotAddedToInventoryEvent, event => - { - const parser = event.getParser(); - - setBotItems(prevValue => - { - const newValue = [ ...prevValue ]; - - const index = newValue.findIndex(item => (item.botData.id === parser.item.id)); - - if(index >= 0) return prevValue; - - const botItem = { botData: parser.item } as IBotItem; - const unseen = isUnseen(UnseenItemCategory.BOT, botItem.botData.id); - - if(unseen) newValue.unshift(botItem); - else newValue.push(botItem); - - return newValue; - }); - }); - - useMessageEvent(BotRemovedFromInventoryEvent, event => - { - const parser = event.getParser(); - - setBotItems(prevValue => - { - const newValue = [ ...prevValue ]; - - const index = newValue.findIndex(item => (item.botData.id === parser.itemId)); - - if(index === -1) return prevValue; - - newValue.splice(index, 1); - - if(getPlacingItemId() === parser.itemId) - { - cancelRoomObjectPlacement(); - - CreateLinkEvent('inventory/show'); - } - - return newValue; - }); - }); - - useEffect(() => - { - if(!botItems || !botItems.length) return; - - setSelectedBot(prevValue => - { - let newValue = prevValue; - - if(newValue && (botItems.indexOf(newValue) === -1)) newValue = null; - - if(!newValue) newValue = botItems[0]; - - return newValue; - }); - }, [ botItems ]); - - useEffect(() => - { - if(!isVisible) return; - - return () => - { - resetCategory(UnseenItemCategory.BOT); - } - }, [ isVisible, resetCategory ]); - - useEffect(() => - { - if(!isVisible || !needsUpdate) return; - - SendMessageComposer(new GetBotInventoryComposer()); - - setNeedsUpdate(false); - }, [ isVisible, needsUpdate ]); - - return { botItems, selectedBot, setSelectedBot, activate, deactivate }; -} - -export const useInventoryBots = () => useBetween(useInventoryBotsState); diff --git a/src/hooks/inventory/useInventoryFurni.ts b/src/hooks/inventory/useInventoryFurni.ts deleted file mode 100644 index b8a6d0d..0000000 --- a/src/hooks/inventory/useInventoryFurni.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { CreateLinkEvent, FurnitureListAddOrUpdateEvent, FurnitureListComposer, FurnitureListEvent, FurnitureListInvalidateEvent, FurnitureListItemParser, FurnitureListRemovedEvent, FurniturePostItPlacedEvent } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { useBetween } from 'use-between'; -import { CloneObject, DispatchUiEvent, FurnitureItem, GroupItem, SendMessageComposer, UnseenItemCategory, addFurnitureItem, attemptItemPlacement, cancelRoomObjectPlacement, getAllItemIds, getPlacingItemId, mergeFurniFragments } from '../../api'; -import { InventoryFurniAddedEvent } from '../../events'; -import { useMessageEvent } from '../events'; -import { useSharedVisibility } from '../useSharedVisibility'; -import { useInventoryUnseenTracker } from './useInventoryUnseenTracker'; - -let furniMsgFragments: Map[] = null; - -const useInventoryFurniState = () => -{ - const [ needsUpdate, setNeedsUpdate ] = useState(true); - const [ groupItems, setGroupItems ] = useState([]); - const [ selectedItem, setSelectedItem ] = useState(null); - const { isVisible = false, activate = null, deactivate = null } = useSharedVisibility(); - const { isUnseen = null, resetCategory = null } = useInventoryUnseenTracker(); - - const getItemsByType = (type: number) => - { - if(!groupItems || !groupItems.length) return; - - return groupItems.filter((i) => i.type === type); - } - - const getWallItemById = (id: number) => - { - if(!groupItems || !groupItems.length) return; - - for(const groupItem of groupItems) - { - const item = groupItem.getItemById(id); - - if(item && item.isWallItem) return groupItem; - } - - return null; - } - - const getFloorItemById = (id: number) => - { - if(!groupItems || !groupItems.length) return; - - for(const groupItem of groupItems) - { - const item = groupItem.getItemById(id); - - if(item && !item.isWallItem) return groupItem; - } - - return null; - } - - useMessageEvent(FurnitureListAddOrUpdateEvent, event => - { - const parser = event.getParser(); - - setGroupItems(prevValue => - { - const newValue = [ ...prevValue ]; - - for(const item of parser.items) - { - let i = 0; - let groupItem: GroupItem = null; - - while(i < newValue.length) - { - const group = newValue[i]; - - let j = 0; - - while(j < group.items.length) - { - const furniture = group.items[j]; - - if(furniture.id === item.itemId) - { - furniture.update(item); - - const newFurniture = [ ...group.items ]; - - newFurniture[j] = furniture; - - group.items = newFurniture; - - groupItem = group; - - break; - } - - j++ - } - - if(groupItem) break; - - i++; - } - - if(groupItem) - { - groupItem.hasUnseenItems = true; - - newValue[i] = CloneObject(groupItem); - } - else - { - const furniture = new FurnitureItem(item); - - addFurnitureItem(newValue, furniture, isUnseen(UnseenItemCategory.FURNI, item.itemId)); - - DispatchUiEvent(new InventoryFurniAddedEvent(furniture.id, furniture.type, furniture.category)); - } - } - - return newValue; - }); - }); - - useMessageEvent(FurnitureListEvent, event => - { - const parser = event.getParser(); - - if(!furniMsgFragments) furniMsgFragments = new Array(parser.totalFragments); - - const fragment = mergeFurniFragments(parser.fragment, parser.totalFragments, parser.fragmentNumber, furniMsgFragments); - - if(!fragment) return; - - setGroupItems(prevValue => - { - const newValue = [ ...prevValue ]; - const existingIds = getAllItemIds(newValue); - - for(const existingId of existingIds) - { - if(fragment.get(existingId)) continue; - - let index = 0; - - while(index < newValue.length) - { - const group = newValue[index]; - const item = group.remove(existingId); - - if(!item) - { - index++; - - continue; - } - - if(getPlacingItemId() === item.ref) - { - cancelRoomObjectPlacement(); - - if(!attemptItemPlacement(group)) - { - CreateLinkEvent('inventory/show'); - } - } - - if(group.getTotalCount() <= 0) - { - newValue.splice(index, 1); - - group.dispose(); - } - - break; - } - } - - for(const itemId of fragment.keys()) - { - if(existingIds.indexOf(itemId) >= 0) continue; - - const parser = fragment.get(itemId); - - if(!parser) continue; - - const item = new FurnitureItem(parser); - - addFurnitureItem(newValue, item, isUnseen(UnseenItemCategory.FURNI, itemId)); - - DispatchUiEvent(new InventoryFurniAddedEvent(item.id, item.type, item.category)); - - } - - return newValue; - }); - - furniMsgFragments = null; - }); - - useMessageEvent(FurnitureListInvalidateEvent, event => - { - setNeedsUpdate(true); - }); - - useMessageEvent(FurnitureListRemovedEvent, event => - { - const parser = event.getParser(); - - setGroupItems(prevValue => - { - const newValue = [ ...prevValue ]; - - let index = 0; - - while(index < newValue.length) - { - const group = newValue[index]; - const item = group.remove(parser.itemId); - - if(!item) - { - index++; - - continue; - } - - if(getPlacingItemId() === item.ref) - { - cancelRoomObjectPlacement(); - - if(!attemptItemPlacement(group)) CreateLinkEvent('inventory/show'); - } - - if(group.getTotalCount() <= 0) - { - newValue.splice(index, 1); - - group.dispose(); - } - - break; - } - - return newValue; - }); - }); - - useMessageEvent(FurniturePostItPlacedEvent, event => - { - - }); - - useEffect(() => - { - if(!groupItems || !groupItems.length) return; - - setSelectedItem(prevValue => - { - let newValue = prevValue; - - if(newValue && (groupItems.indexOf(newValue) === -1)) newValue = null; - - if(!newValue) newValue = groupItems[0]; - - return newValue; - }); - }, [ groupItems ]); - - useEffect(() => - { - if(!isVisible) return; - - return () => - { - if(resetCategory(UnseenItemCategory.FURNI)) - { - setGroupItems(prevValue => - { - const newValue = [ ...prevValue ]; - - for(const newGroup of newValue) newGroup.hasUnseenItems = false; - - return newValue; - }); - } - } - }, [ isVisible, resetCategory ]); - - useEffect(() => - { - if(!isVisible || !needsUpdate) return; - - SendMessageComposer(new FurnitureListComposer()); - - setNeedsUpdate(false); - }, [ isVisible, needsUpdate ]); - - return { isVisible, groupItems, setGroupItems, selectedItem, setSelectedItem, activate, deactivate, getWallItemById, getFloorItemById, getItemsByType }; -} - -export const useInventoryFurni = () => useBetween(useInventoryFurniState); diff --git a/src/hooks/inventory/useInventoryPets.ts b/src/hooks/inventory/useInventoryPets.ts deleted file mode 100644 index d95e8bf..0000000 --- a/src/hooks/inventory/useInventoryPets.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { PetAddedToInventoryEvent, PetData, PetInventoryEvent, PetRemovedFromInventory, RequestPetsComposer } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { useBetween } from 'use-between'; -import { addSinglePetItem, IPetItem, mergePetFragments, processPetFragment, removePetItemById, SendMessageComposer, UnseenItemCategory } from '../../api'; -import { useMessageEvent } from '../events'; -import { useSharedVisibility } from '../useSharedVisibility'; -import { useInventoryUnseenTracker } from './useInventoryUnseenTracker'; - -let petMsgFragments: Map[] = null; - -const useInventoryPetsState = () => -{ - const [ needsUpdate, setNeedsUpdate ] = useState(true); - const [ petItems, setPetItems ] = useState([]); - const [ selectedPet, setSelectedPet ] = useState(null); - const { isVisible = false, activate = null, deactivate = null } = useSharedVisibility(); - const { isUnseen = null, resetCategory = null } = useInventoryUnseenTracker(); - - useMessageEvent(PetInventoryEvent, event => - { - const parser = event.getParser(); - - if(!petMsgFragments) petMsgFragments = new Array(parser.totalFragments); - - const fragment = mergePetFragments(parser.fragment, parser.totalFragments, parser.fragmentNumber, petMsgFragments); - - if(!fragment) return; - - setPetItems(prevValue => - { - const newValue = [ ...prevValue ]; - - processPetFragment(newValue, fragment, isUnseen); - - return newValue; - }); - - petMsgFragments = null; - }); - - useMessageEvent(PetAddedToInventoryEvent, event => - { - const parser = event.getParser(); - - setPetItems(prevValue => - { - const newValue = [ ...prevValue ]; - - addSinglePetItem(parser.pet, newValue, isUnseen(UnseenItemCategory.PET, parser.pet.id)); - - return newValue; - }); - }); - - useMessageEvent(PetRemovedFromInventory, event => - { - const parser = event.getParser(); - - setPetItems(prevValue => - { - const newValue = [ ...prevValue ]; - - removePetItemById(parser.petId, newValue); - - return newValue; - }); - }); - - useEffect(() => - { - if(!petItems || !petItems.length) return; - - setSelectedPet(prevValue => - { - let newValue = prevValue; - - if(newValue && (petItems.indexOf(newValue) === -1)) newValue = null; - - if(!newValue) newValue = petItems[0]; - - return newValue; - }); - }, [ petItems ]); - - useEffect(() => - { - if(!isVisible) return; - - return () => - { - resetCategory(UnseenItemCategory.PET); - } - }, [ isVisible, resetCategory ]); - - useEffect(() => - { - if(!isVisible || !needsUpdate) return; - - SendMessageComposer(new RequestPetsComposer()); - - setNeedsUpdate(false); - }, [ isVisible, needsUpdate ]); - - return { petItems, selectedPet, setSelectedPet, activate, deactivate }; -} - -export const useInventoryPets = () => useBetween(useInventoryPetsState); diff --git a/src/hooks/inventory/useInventoryTrade.ts b/src/hooks/inventory/useInventoryTrade.ts deleted file mode 100644 index bb83022..0000000 --- a/src/hooks/inventory/useInventoryTrade.ts +++ /dev/null @@ -1,288 +0,0 @@ -import { AdvancedMap, GetSessionDataManager, TradingAcceptComposer, TradingAcceptEvent, TradingCancelComposer, TradingCloseComposer, TradingCloseEvent, TradingCloseParser, TradingCompletedEvent, TradingConfirmationComposer, TradingConfirmationEvent, TradingListItemEvent, TradingListItemRemoveComposer, TradingNotOpenEvent, TradingOpenEvent, TradingOpenFailedEvent, TradingOtherNotAllowedEvent, TradingUnacceptComposer, TradingYouAreNotAllowedEvent } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { useBetween } from 'use-between'; -import { CloneObject, GetRoomSession, GroupItem, LocalizeText, SendMessageComposer, TradeState, TradeUserData, TradingNotificationType, parseTradeItems } from '../../api'; -import { useMessageEvent } from '../events'; -import { useNotification } from '../notification'; -import { useInventoryFurni } from './useInventoryFurni'; - -const useInventoryTradeState = () => -{ - const [ ownUser, setOwnUser ] = useState(null); - const [ otherUser, setOtherUser ] = useState(null); - const [ tradeState, setTradeState ] = useState(TradeState.TRADING_STATE_READY); - const { groupItems = [], setGroupItems = null, activate = null, deactivate = null } = useInventoryFurni(); - const { simpleAlert = null, showTradeAlert = null } = useNotification(); - const isTrading = (tradeState >= TradeState.TRADING_STATE_RUNNING); - - const progressTrade = () => - { - switch(tradeState) - { - case TradeState.TRADING_STATE_RUNNING: - if(!otherUser.itemCount && !ownUser.accepts) - { - simpleAlert(LocalizeText('inventory.trading.warning.other_not_offering'), null, null, null); - } - - if(ownUser.accepts) - { - SendMessageComposer(new TradingUnacceptComposer()); - } - else - { - SendMessageComposer(new TradingAcceptComposer()); - } - return; - case TradeState.TRADING_STATE_CONFIRMING: - SendMessageComposer(new TradingConfirmationComposer()); - - setTradeState(TradeState.TRADING_STATE_CONFIRMED); - return; - } - } - - const removeItem = (group: GroupItem) => - { - const item = group.getLastItem(); - - if(!item) return; - - SendMessageComposer(new TradingListItemRemoveComposer(item.id)); - } - - const stopTrading = () => - { - if(!isTrading) return; - - switch(tradeState) - { - case TradeState.TRADING_STATE_RUNNING: - SendMessageComposer(new TradingCloseComposer()); - return; - default: - SendMessageComposer(new TradingCancelComposer()); - return; - } - } - - useMessageEvent(TradingAcceptEvent, event => - { - const parser = event.getParser(); - - if(!ownUser || !otherUser) return; - - if(ownUser.userId === parser.userID) - { - setOwnUser(prevValue => - { - const newValue = CloneObject(prevValue); - - newValue.accepts = parser.userAccepts; - - return newValue; - }); - } - - else if(otherUser.userId === parser.userID) - { - setOtherUser(prevValue => - { - const newValue = CloneObject(prevValue); - - newValue.accepts = parser.userAccepts; - - return newValue; - }); - } - }); - - useMessageEvent(TradingCloseEvent, event => - { - const parser = event.getParser(); - - if(parser.reason === TradingCloseParser.ERROR_WHILE_COMMIT) - { - showTradeAlert(TradingNotificationType.ERROR_WHILE_COMMIT); - } - else - { - if(ownUser && (parser.userID !== ownUser.userId)) - { - showTradeAlert(TradingNotificationType.THEY_CANCELLED); - } - } - - setOwnUser(null); - setOtherUser(null); - setTradeState(TradeState.TRADING_STATE_READY); - }); - - useMessageEvent(TradingCompletedEvent, event => - { - const parser = event.getParser(); - - setOwnUser(null); - setOtherUser(null); - setTradeState(TradeState.TRADING_STATE_READY); - }); - - useMessageEvent(TradingConfirmationEvent, event => - { - const parser = event.getParser(); - - setTradeState(TradeState.TRADING_STATE_COUNTDOWN); - }); - - useMessageEvent(TradingListItemEvent, event => - { - const parser = event.getParser(); - const firstUserItems = parseTradeItems(parser.firstUserItemArray); - const secondUserItems = parseTradeItems(parser.secondUserItemArray); - - setOwnUser(prevValue => - { - const newValue = CloneObject(prevValue); - - if(newValue.userId === parser.firstUserID) - { - newValue.creditsCount = parser.firstUserNumCredits; - newValue.itemCount = parser.firstUserNumItems; - newValue.userItems = firstUserItems; - } - else - { - newValue.creditsCount = parser.secondUserNumCredits; - newValue.itemCount = parser.secondUserNumItems; - newValue.userItems = secondUserItems; - } - - const tradeIds: number[] = []; - - for(const groupItem of newValue.userItems.getValues()) - { - let i = 0; - - while(i < groupItem.getTotalCount()) - { - const item = groupItem.getItemByIndex(i); - - if(item) tradeIds.push(item.ref); - - i++; - } - } - - setGroupItems(prevValue => - { - const newValue = [ ...prevValue ]; - - for(const groupItem of newValue) groupItem.lockItemIds(tradeIds); - - return newValue; - }); - - return newValue; - }); - - setOtherUser(prevValue => - { - const newValue = CloneObject(prevValue); - - if(newValue.userId === parser.firstUserID) - { - newValue.creditsCount = parser.firstUserNumCredits; - newValue.itemCount = parser.firstUserNumItems; - newValue.userItems = firstUserItems; - } - else - { - newValue.creditsCount = parser.secondUserNumCredits; - newValue.itemCount = parser.secondUserNumItems; - newValue.userItems = secondUserItems; - } - - return newValue; - }); - }); - - useMessageEvent(TradingNotOpenEvent, event => - { - const parser = event.getParser(); - }); - - useMessageEvent(TradingOpenEvent, event => - { - const parser = event.getParser(); - - const firstUser = new TradeUserData(); - const firstUserData = GetRoomSession().userDataManager.getUserData(parser.userID); - - firstUser.userItems = new AdvancedMap(); - - const secondUser = new TradeUserData(); - const secondUserData = GetRoomSession().userDataManager.getUserData(parser.otherUserID); - - secondUser.userItems = new AdvancedMap(); - - if(firstUserData.webID === GetSessionDataManager().userId) - { - firstUser.userId = firstUserData.webID; - firstUser.userName = firstUserData.name; - firstUser.canTrade = parser.userCanTrade; - - secondUser.userId = secondUserData.webID; - secondUser.userName = secondUserData.name; - secondUser.canTrade = parser.otherUserCanTrade; - } - - else if(secondUserData.webID === GetSessionDataManager().userId) - { - firstUser.userId = secondUserData.webID; - firstUser.userName = secondUserData.name; - firstUser.canTrade = parser.otherUserCanTrade; - - secondUser.userId = firstUserData.webID; - secondUser.userName = firstUserData.name; - secondUser.canTrade = parser.userCanTrade; - } - - setOwnUser(firstUser); - setOtherUser(secondUser); - setTradeState(TradeState.TRADING_STATE_RUNNING); - }); - - useMessageEvent(TradingOpenFailedEvent, event => - { - const parser = event.getParser(); - - showTradeAlert(parser.reason, parser.otherUserName); - }); - - useMessageEvent(TradingOtherNotAllowedEvent, event => - { - const parser = event.getParser(); - - showTradeAlert(TradingNotificationType.THEY_NOT_ALLOWED); - }); - - useMessageEvent(TradingYouAreNotAllowedEvent, event => - { - const parser = event.getParser(); - - showTradeAlert(TradingNotificationType.YOU_NOT_ALLOWED); - }); - - useEffect(() => - { - if(tradeState === TradeState.TRADING_STATE_READY) return; - - const id = activate(); - - return () => deactivate(id); - }, [ tradeState, activate, deactivate ]); - - return { ownUser, otherUser, tradeState, setTradeState, isTrading, groupItems, progressTrade, removeItem, stopTrading }; -} - -export const useInventoryTrade = () => useBetween(useInventoryTradeState); diff --git a/src/hooks/inventory/useInventoryUnseenTracker.ts b/src/hooks/inventory/useInventoryUnseenTracker.ts deleted file mode 100644 index 90ba66e..0000000 --- a/src/hooks/inventory/useInventoryUnseenTracker.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { UnseenItemsEvent, UnseenResetCategoryComposer, UnseenResetItemsComposer } from '@nitrots/nitro-renderer'; -import { useCallback, useMemo, useState } from 'react'; -import { useBetween } from 'use-between'; -import { SendMessageComposer } from '../../api'; -import { useMessageEvent } from '../events'; - -const sendResetCategoryMessage = (category: number) => SendMessageComposer(new UnseenResetCategoryComposer(category)); -const sendResetItemsMessage = (category: number, itemIds: number[]) => SendMessageComposer(new UnseenResetItemsComposer(category, ...itemIds)); - -const useInventoryUnseenTrackerState = () => -{ - const [ unseenItems, setUnseenItems ] = useState>(new Map()); - - const getCount = useCallback((category: number) => (unseenItems.get(category)?.length || 0), [ unseenItems ]); - - const getFullCount = useMemo(() => - { - let count = 0; - - for(const key of unseenItems.keys()) count += getCount(key); - - return count; - }, [ unseenItems, getCount ]); - - const resetCategory = useCallback((category: number) => - { - let didReset = true; - - setUnseenItems(prevValue => - { - if(!prevValue.has(category)) - { - didReset = false; - - return prevValue; - } - - const newValue = new Map(prevValue); - - newValue.delete(category); - - sendResetCategoryMessage(category); - - return newValue; - }); - - return didReset; - }, []); - - const resetItems = useCallback((category: number, itemIds: number[]) => - { - let didReset = true; - - setUnseenItems(prevValue => - { - if(!prevValue.has(category)) - { - didReset = false; - - return prevValue; - } - - const newValue = new Map(prevValue); - const existing = newValue.get(category); - - if(existing) for(const itemId of itemIds) existing.splice(existing.indexOf(itemId), 1); - - sendResetItemsMessage(category, itemIds); - - return newValue; - }); - - return didReset; - }, []); - - const isUnseen = useCallback((category: number, itemId: number) => - { - if(!unseenItems.has(category)) return false; - - const items = unseenItems.get(category); - - return (items.indexOf(itemId) >= 0); - }, [ unseenItems ]); - - const removeUnseen = useCallback((category: number, itemId: number) => - { - setUnseenItems(prevValue => - { - if(!prevValue.has(category)) return prevValue; - - const newValue = new Map(prevValue); - const items = newValue.get(category); - const index = items.indexOf(itemId); - - if(index >= 0) items.splice(index, 1); - - return newValue; - }); - }, []); - - useMessageEvent(UnseenItemsEvent, event => - { - const parser = event.getParser(); - - setUnseenItems(prevValue => - { - const newValue = new Map(prevValue); - - for(const category of parser.categories) - { - let existing = newValue.get(category); - - if(!existing) - { - existing = []; - - newValue.set(category, existing); - } - - const itemIds = parser.getItemsByCategory(category); - - for(const itemId of itemIds) ((existing.indexOf(itemId) === -1) && existing.push(itemId)); - } - - return newValue; - }); - }); - - return { getCount, getFullCount, resetCategory, resetItems, isUnseen, removeUnseen }; -} - -export const useInventoryUnseenTracker = () => useBetween(useInventoryUnseenTrackerState); diff --git a/src/hooks/mod-tools/index.ts b/src/hooks/mod-tools/index.ts deleted file mode 100644 index 26546fd..0000000 --- a/src/hooks/mod-tools/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useModTools'; diff --git a/src/hooks/mod-tools/useModTools.ts b/src/hooks/mod-tools/useModTools.ts deleted file mode 100644 index 93628f1..0000000 --- a/src/hooks/mod-tools/useModTools.ts +++ /dev/null @@ -1,207 +0,0 @@ -import { CallForHelpCategoryData, CfhSanctionMessageEvent, CfhTopicsInitEvent, IssueDeletedMessageEvent, IssueInfoMessageEvent, IssueMessageData, IssuePickFailedMessageEvent, ModeratorActionResultMessageEvent, ModeratorInitData, ModeratorInitMessageEvent, ModeratorToolPreferencesEvent } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { useBetween } from 'use-between'; -import { NotificationAlertType, PlaySound, SoundNames } from '../../api'; -import { useMessageEvent } from '../events'; -import { useNotification } from '../notification'; - -const useModToolsState = () => -{ - const [ settings, setSettings ] = useState(null); - const [ openRooms, setOpenRooms ] = useState([]); - const [ openRoomChatlogs, setOpenRoomChatlogs ] = useState([]); - const [ openUserInfos, setOpenUserInfos ] = useState([]); - const [ openUserChatlogs, setOpenUserChatlogs ] = useState([]); - const [ tickets, setTickets ] = useState([]); - const [ cfhCategories, setCfhCategories ] = useState([]); - const { simpleAlert = null } = useNotification(); - - const openRoomInfo = (roomId: number) => - { - if(openRooms.indexOf(roomId) >= 0) return; - - setOpenRooms(prevValue => [ ...prevValue, roomId ]); - } - - const closeRoomInfo = (roomId: number) => - { - setOpenRooms(prevValue => - { - const newValue = [ ...prevValue ]; - const existingIndex = newValue.indexOf(roomId); - - if(existingIndex >= 0) newValue.splice(existingIndex); - - return newValue; - }); - } - - const toggleRoomInfo = (roomId: number) => - { - if(openRooms.indexOf(roomId) >= 0) closeRoomInfo(roomId); - else openRoomInfo(roomId); - } - - const openRoomChatlog = (roomId: number) => - { - if(openRoomChatlogs.indexOf(roomId) >= 0) return; - - setOpenRoomChatlogs(prevValue => [ ...prevValue, roomId ]); - } - - const closeRoomChatlog = (roomId: number) => - { - setOpenRoomChatlogs(prevValue => - { - const newValue = [ ...prevValue ]; - const existingIndex = newValue.indexOf(roomId); - - if(existingIndex >= 0) newValue.splice(existingIndex); - - return newValue; - }); - } - - const toggleRoomChatlog = (roomId: number) => - { - if(openRoomChatlogs.indexOf(roomId) >= 0) closeRoomChatlog(roomId); - else openRoomChatlog(roomId); - } - - const openUserInfo = (userId: number) => - { - if(openUserInfos.indexOf(userId) >= 0) return; - - setOpenUserInfos(prevValue => [ ...prevValue, userId ]); - } - - const closeUserInfo = (userId: number) => - { - setOpenUserInfos(prevValue => - { - const newValue = [ ...prevValue ]; - const existingIndex = newValue.indexOf(userId); - - if(existingIndex >= 0) newValue.splice(existingIndex); - - return newValue; - }); - } - - const toggleUserInfo = (userId: number) => - { - if(openUserInfos.indexOf(userId) >= 0) closeUserInfo(userId); - else openUserInfo(userId); - } - - const openUserChatlog = (userId: number) => - { - if(openUserChatlogs.indexOf(userId) >= 0) return; - - setOpenUserChatlogs(prevValue => [ ...prevValue, userId ]); - } - - const closeUserChatlog = (userId: number) => - { - setOpenUserChatlogs(prevValue => - { - const newValue = [ ...prevValue ]; - const existingIndex = newValue.indexOf(userId); - - if(existingIndex >= 0) newValue.splice(existingIndex); - - return newValue; - }); - } - - const toggleUserChatlog = (userId: number) => - { - if(openRoomChatlogs.indexOf(userId) >= 0) closeUserChatlog(userId); - else openUserChatlog(userId); - } - - useMessageEvent(ModeratorInitMessageEvent, event => - { - const parser = event.getParser(); - const data = parser.data; - - setSettings(data); - setTickets(data.issues); - }); - - useMessageEvent(IssueInfoMessageEvent, event => - { - const parser = event.getParser(); - - setTickets(prevValue => - { - const newValue = [ ...prevValue ]; - const existingIndex = newValue.findIndex(ticket => (ticket.issueId === parser.issueData.issueId)); - - if(existingIndex >= 0) newValue[existingIndex] = parser.issueData; - else - { - newValue.push(parser.issueData); - - PlaySound(SoundNames.MODTOOLS_NEW_TICKET); - } - - return newValue; - }); - }); - - useMessageEvent(ModeratorToolPreferencesEvent, event => - { - const parser = event.getParser(); - }); - - useMessageEvent(IssuePickFailedMessageEvent, event => - { - const parser = event.getParser(); - - if(!parser) return; - - simpleAlert('Failed to pick issue', NotificationAlertType.DEFAULT, null, null, 'Error') - }); - - useMessageEvent(IssueDeletedMessageEvent, event => - { - const parser = event.getParser(); - - setTickets(prevValue => - { - const newValue = [ ...prevValue ]; - const existingIndex = newValue.findIndex(ticket => (ticket.issueId === parser.issueId)); - - if(existingIndex >= 0) newValue.splice(existingIndex, 1); - - return newValue; - }); - }); - - useMessageEvent(ModeratorActionResultMessageEvent, event => - { - const parser = event.getParser(); - - if(parser.success) simpleAlert('Moderation action was successfull', NotificationAlertType.MODERATION, null, null, 'Success'); - else simpleAlert('There was a problem applying tht moderation action', NotificationAlertType.MODERATION, null, null, 'Error'); - }); - - useMessageEvent(CfhTopicsInitEvent, event => - { - const parser = event.getParser(); - - setCfhCategories(parser.callForHelpCategories); - }); - - useMessageEvent(CfhSanctionMessageEvent, event => - { - const parser = event.getParser(); - - // todo: update sanction data - }); - - return { settings, openRooms, openRoomChatlogs, openUserChatlogs, openUserInfos, cfhCategories, tickets, openRoomInfo, closeRoomInfo, toggleRoomInfo, openRoomChatlog, closeRoomChatlog, toggleRoomChatlog, openUserInfo, closeUserInfo, toggleUserInfo, openUserChatlog, closeUserChatlog, toggleUserChatlog }; -} - -export const useModTools = () => useBetween(useModToolsState); diff --git a/src/hooks/navigator/index.ts b/src/hooks/navigator/index.ts deleted file mode 100644 index 1f6f053..0000000 --- a/src/hooks/navigator/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useNavigator'; diff --git a/src/hooks/navigator/useNavigator.ts b/src/hooks/navigator/useNavigator.ts deleted file mode 100644 index 87d2de3..0000000 --- a/src/hooks/navigator/useNavigator.ts +++ /dev/null @@ -1,442 +0,0 @@ -import { CanCreateRoomEventEvent, CantConnectMessageParser, CreateLinkEvent, DoorbellMessageEvent, FlatAccessDeniedMessageEvent, FlatCreatedEvent, FollowFriendMessageComposer, GenericErrorEvent, GetGuestRoomMessageComposer, GetGuestRoomResultEvent, GetSessionDataManager, GetUserEventCatsMessageComposer, GetUserFlatCatsMessageComposer, HabboWebTools, LegacyExternalInterface, NavigatorCategoryDataParser, NavigatorEventCategoryDataParser, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSearchEvent, NavigatorSearchResultSet, NavigatorTopLevelContext, RoomDataParser, RoomDoorbellAcceptedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, RoomScoreEvent, RoomSettingsUpdatedEvent, SecurityLevel, UserEventCatsEvent, UserFlatCatsEvent, UserInfoEvent, UserPermissionsEvent } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { useBetween } from 'use-between'; -import { CreateRoomSession, DoorStateType, GetConfigurationValue, INavigatorData, LocalizeText, NotificationAlertType, SendMessageComposer, TryVisitRoom, VisitDesktop } from '../../api'; -import { useMessageEvent } from '../events'; -import { useNotification } from '../notification'; - -const useNavigatorState = () => -{ - const [ categories, setCategories ] = useState(null); - const [ eventCategories, setEventCategories ] = useState(null); - const [ topLevelContext, setTopLevelContext ] = useState(null); - const [ topLevelContexts, setTopLevelContexts ] = useState(null); - const [ doorData, setDoorData ] = useState<{ roomInfo: RoomDataParser, state: number }>({ roomInfo: null, state: DoorStateType.NONE }); - const [ searchResult, setSearchResult ] = useState(null); - const [ navigatorData, setNavigatorData ] = useState({ - settingsReceived: false, - homeRoomId: 0, - enteredGuestRoom: null, - currentRoomOwner: false, - currentRoomId: 0, - currentRoomIsStaffPick: false, - createdFlatId: 0, - avatarId: 0, - roomPicker: false, - eventMod: false, - currentRoomRating: 0, - canRate: true - }); - const { simpleAlert = null } = useNotification(); - - useMessageEvent(RoomSettingsUpdatedEvent, event => - { - const parser = event.getParser(); - - SendMessageComposer(new GetGuestRoomMessageComposer(parser.roomId, false, false)); - }); - - useMessageEvent(CanCreateRoomEventEvent, event => - { - const parser = event.getParser(); - - if(parser.canCreate) - { - // show room event cvreate - - return; - } - - simpleAlert(LocalizeText(`navigator.cannotcreateevent.error.${ parser.errorCode }`), null, null, null, LocalizeText('navigator.cannotcreateevent.title')); - }); - - useMessageEvent(UserInfoEvent, event => - { - SendMessageComposer(new GetUserFlatCatsMessageComposer()); - SendMessageComposer(new GetUserEventCatsMessageComposer()); - }); - - useMessageEvent(UserPermissionsEvent, event => - { - const parser = event.getParser(); - - setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.eventMod = (parser.securityLevel >= SecurityLevel.MODERATOR); - newValue.roomPicker = (parser.securityLevel >= SecurityLevel.COMMUNITY); - - return newValue; - }); - }); - - useMessageEvent(RoomForwardEvent, event => - { - const parser = event.getParser(); - - TryVisitRoom(parser.roomId); - }); - - useMessageEvent(RoomEntryInfoMessageEvent, event => - { - const parser = event.getParser(); - - setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.enteredGuestRoom = null; - newValue.currentRoomOwner = parser.isOwner; - newValue.currentRoomId = parser.roomId; - - return newValue; - }); - - // close room info - // close room settings - // close room filter - - SendMessageComposer(new GetGuestRoomMessageComposer(parser.roomId, true, false)); - - if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'navigator', 'private', [ parser.roomId ]); - }); - - useMessageEvent(GetGuestRoomResultEvent, event => - { - const parser = event.getParser(); - - if(parser.roomEnter) - { - setDoorData({ roomInfo: null, state: DoorStateType.NONE }); - - setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.enteredGuestRoom = parser.data; - newValue.currentRoomIsStaffPick = parser.staffPick; - - const isCreated = (newValue.createdFlatId === parser.data.roomId); - - if(!isCreated && parser.data.displayRoomEntryAd) - { - if(GetConfigurationValue('roomenterad.habblet.enabled', false)) HabboWebTools.openRoomEnterAd(); - } - - newValue.createdFlatId = 0; - - if(newValue.enteredGuestRoom && (newValue.enteredGuestRoom.habboGroupId > 0)) - { - // close event info - } - - return newValue; - }); - } - else if(parser.roomForward) - { - if((parser.data.ownerName !== GetSessionDataManager().userName) && !parser.isGroupMember) - { - switch(parser.data.doorMode) - { - case RoomDataParser.DOORBELL_STATE: - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.roomInfo = parser.data; - newValue.state = DoorStateType.START_DOORBELL; - - return newValue; - }); - return; - case RoomDataParser.PASSWORD_STATE: - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.roomInfo = parser.data; - newValue.state = DoorStateType.START_PASSWORD; - - return newValue; - }); - return; - } - } - - if((parser.data.doorMode === RoomDataParser.NOOB_STATE) && !GetSessionDataManager().isAmbassador && !GetSessionDataManager().isRealNoob && !GetSessionDataManager().isModerator) return; - - CreateRoomSession(parser.data.roomId); - } - else - { - setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.enteredGuestRoom = parser.data; - newValue.currentRoomIsStaffPick = parser.staffPick; - - return newValue; - }); - } - }); - - useMessageEvent(RoomScoreEvent, event => - { - const parser = event.getParser(); - - setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.currentRoomRating = parser.totalLikes; - newValue.canRate = parser.canLike; - - return newValue; - }); - }); - - useMessageEvent(DoorbellMessageEvent, event => - { - const parser = event.getParser(); - - if(!parser.userName || (parser.userName.length === 0)) - { - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.state = DoorStateType.STATE_WAITING; - - return newValue; - }); - } - }); - - useMessageEvent(RoomDoorbellAcceptedEvent, event => - { - const parser = event.getParser(); - - if(!parser.userName || (parser.userName.length === 0)) - { - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.state = DoorStateType.STATE_ACCEPTED; - - return newValue; - }); - } - }); - - useMessageEvent(FlatAccessDeniedMessageEvent, event => - { - const parser = event.getParser(); - - if(!parser.userName || (parser.userName.length === 0)) - { - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.state = DoorStateType.STATE_NO_ANSWER; - - return newValue; - }); - } - }); - - useMessageEvent(GenericErrorEvent, event => - { - const parser = event.getParser(); - - switch(parser.errorCode) - { - case -100002: - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.state = DoorStateType.STATE_WRONG_PASSWORD; - - return newValue; - }); - return; - case 4009: - simpleAlert(LocalizeText('navigator.alert.need.to.be.vip'), NotificationAlertType.DEFAULT, null, null, LocalizeText('generic.alert.title')); - - return; - case 4010: - simpleAlert(LocalizeText('navigator.alert.invalid_room_name'), NotificationAlertType.DEFAULT, null, null, LocalizeText('generic.alert.title')); - - return; - case 4011: - simpleAlert(LocalizeText('navigator.alert.cannot_perm_ban'), NotificationAlertType.DEFAULT, null, null, LocalizeText('generic.alert.title')); - - return; - case 4013: - simpleAlert(LocalizeText('navigator.alert.room_in_maintenance'), NotificationAlertType.DEFAULT, null, null, LocalizeText('generic.alert.title')); - - return; - } - }); - - useMessageEvent(NavigatorMetadataEvent, event => - { - const parser = event.getParser(); - - setTopLevelContexts(parser.topLevelContexts); - setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null); - }); - - useMessageEvent(NavigatorSearchEvent, event => - { - const parser = event.getParser(); - - setTopLevelContext(prevValue => - { - let newValue = prevValue; - - if(!newValue) newValue = ((topLevelContexts && topLevelContexts.length && topLevelContexts[0]) || null); - - if(!newValue) return null; - - if((parser.result.code !== newValue.code) && topLevelContexts && topLevelContexts.length) - { - for(const context of topLevelContexts) - { - if(context.code !== parser.result.code) continue; - - newValue = context; - } - } - - for(const context of topLevelContexts) - { - if(context.code !== parser.result.code) continue; - - newValue = context; - } - - return newValue; - }); - - setSearchResult(parser.result); - }); - - useMessageEvent(UserFlatCatsEvent, event => - { - const parser = event.getParser(); - - setCategories(parser.categories); - }); - - useMessageEvent(UserEventCatsEvent, event => - { - const parser = event.getParser(); - - setEventCategories(parser.categories); - }); - - useMessageEvent(FlatCreatedEvent, event => - { - const parser = event.getParser(); - - CreateRoomSession(parser.roomId); - }); - - useMessageEvent(NavigatorHomeRoomEvent, event => - { - const parser = event.getParser(); - - let prevSettingsReceived = false; - - setNavigatorData(prevValue => - { - prevSettingsReceived = prevValue.settingsReceived; - - const newValue = { ...prevValue }; - - newValue.homeRoomId = parser.homeRoomId; - newValue.settingsReceived = true; - - return newValue; - }); - - if(prevSettingsReceived) - { - // refresh room info window - return; - } - - let forwardType = -1; - let forwardId = -1; - - if((GetConfigurationValue('friend.id') !== undefined) && (parseInt(GetConfigurationValue('friend.id')) > 0)) - { - forwardType = 0; - SendMessageComposer(new FollowFriendMessageComposer(parseInt(GetConfigurationValue('friend.id')))); - } - - if((GetConfigurationValue('forward.type') !== undefined) && (GetConfigurationValue('forward.id') !== undefined)) - { - forwardType = parseInt(GetConfigurationValue('forward.type')); - forwardId = parseInt(GetConfigurationValue('forward.id')) - } - - if(forwardType === 2) - { - TryVisitRoom(forwardId); - } - - else if((forwardType === -1) && (parser.roomIdToEnter > 0)) - { - CreateLinkEvent('navigator/close'); - - if(parser.roomIdToEnter !== parser.homeRoomId) - { - CreateRoomSession(parser.roomIdToEnter); - } - else - { - CreateRoomSession(parser.homeRoomId); - } - } - }); - - useMessageEvent(RoomEnterErrorEvent, event => - { - const parser = event.getParser(); - - switch(parser.reason) - { - case CantConnectMessageParser.REASON_FULL: - simpleAlert(LocalizeText('navigator.guestroomfull.text'), NotificationAlertType.DEFAULT, null, null, LocalizeText('navigator.guestroomfull.title')); - - break; - case CantConnectMessageParser.REASON_QUEUE_ERROR: - simpleAlert(LocalizeText(`room.queue.error.${ parser.parameter }`), NotificationAlertType.DEFAULT, null, null, LocalizeText('room.queue.error.title')); - - break; - case CantConnectMessageParser.REASON_BANNED: - simpleAlert(LocalizeText('navigator.banned.text'), NotificationAlertType.DEFAULT, null, null, LocalizeText('navigator.banned.title')); - - break; - default: - simpleAlert(LocalizeText('room.queue.error.title'), NotificationAlertType.DEFAULT, null, null, LocalizeText('room.queue.error.title')); - - break; - } - - VisitDesktop(); - }); - - useMessageEvent(NavigatorOpenRoomCreatorEvent, event => CreateLinkEvent('navigator/show')); - - return { categories, doorData, setDoorData, topLevelContext, topLevelContexts, searchResult, navigatorData }; -} - -export const useNavigator = () => useBetween(useNavigatorState); diff --git a/src/hooks/notification/index.ts b/src/hooks/notification/index.ts deleted file mode 100644 index b5a8561..0000000 --- a/src/hooks/notification/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useNotification'; diff --git a/src/hooks/notification/useNotification.ts b/src/hooks/notification/useNotification.ts deleted file mode 100644 index 2343b8e..0000000 --- a/src/hooks/notification/useNotification.ts +++ /dev/null @@ -1,433 +0,0 @@ -import { AchievementNotificationMessageEvent, ActivityPointNotificationMessageEvent, ClubGiftNotificationEvent, ClubGiftSelectedEvent, ConnectionErrorEvent, GetLocalizationManager, GetRoomEngine, GetSessionDataManager, HabboBroadcastMessageEvent, HotelClosedAndOpensEvent, HotelClosesAndWillOpenAtEvent, HotelWillCloseInMinutesEvent, InfoFeedEnableMessageEvent, MaintenanceStatusMessageEvent, ModeratorCautionEvent, ModeratorMessageEvent, MOTDNotificationEvent, NotificationDialogMessageEvent, PetLevelNotificationEvent, PetReceivedMessageEvent, RespectReceivedEvent, RoomEnterEffect, RoomEnterEvent, SimpleAlertMessageEvent, UserBannedMessageEvent, Vector3d } from '@nitrots/nitro-renderer'; -import { useCallback, useState } from 'react'; -import { useBetween } from 'use-between'; -import { GetConfigurationValue, LocalizeBadgeName, LocalizeText, NotificationAlertItem, NotificationAlertType, NotificationBubbleItem, NotificationBubbleType, NotificationConfirmItem, PlaySound, ProductImageUtility, TradingNotificationType } from '../../api'; -import { useMessageEvent } from '../events'; - -const cleanText = (text: string) => (text && text.length) ? text.replace(/\\r/g, '\r') : ''; - -const getTimeZeroPadded = (time: number) => -{ - const text = ('0' + time); - - return text.substr((text.length - 2), text.length); -} - -let modDisclaimerTimeout: ReturnType = null; - -const useNotificationState = () => -{ - const [ alerts, setAlerts ] = useState([]); - const [ bubbleAlerts, setBubbleAlerts ] = useState([]); - const [ confirms, setConfirms ] = useState([]); - const [ bubblesDisabled, setBubblesDisabled ] = useState(false); - const [ modDisclaimerShown, setModDisclaimerShown ] = useState(false); - - const getMainNotificationConfig = () => GetConfigurationValue<{ [key: string]: { delivery?: string, display?: string; title?: string; image?: string }}>('notification', {}); - - const getNotificationConfig = (key: string) => - { - const mainConfig = getMainNotificationConfig(); - - if(!mainConfig) return null; - - return mainConfig[key]; - } - - const getNotificationPart = (options: Map, type: string, key: string, localize: boolean) => - { - if(options.has(key)) return options.get(key); - - const localizeKey = [ 'notification', type, key ].join('.'); - - if(GetLocalizationManager().hasValue(localizeKey) || localize) return LocalizeText(localizeKey, Array.from(options.keys()), Array.from(options.values())); - - return null; - } - - const getNotificationImageUrl = (options: Map, type: string) => - { - let imageUrl = options.get('image'); - - if(!imageUrl) imageUrl = GetConfigurationValue('image.library.notifications.url', '').replace('%image%', type.replace(/\./g, '_')); - - return LocalizeText(imageUrl); - } - - const simpleAlert = useCallback((message: string, type: string = null, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null) => - { - if(!title || !title.length) title = LocalizeText('notifications.broadcast.title'); - - if(!type || !type.length) type = NotificationAlertType.DEFAULT; - - const alertItem = new NotificationAlertItem([ cleanText(message) ], type, clickUrl, clickUrlText, title, imageUrl); - - setAlerts(prevValue => [ alertItem, ...prevValue ]); - }, []); - - const showNitroAlert = useCallback(() => simpleAlert(null, NotificationAlertType.NITRO), [ simpleAlert ]); - - const showSingleBubble = useCallback((message: string, type: string, imageUrl: string = null, internalLink: string = null) => - { - if(bubblesDisabled) return; - - const notificationItem = new NotificationBubbleItem(message, type, imageUrl, internalLink); - - setBubbleAlerts(prevValue => [ notificationItem, ...prevValue ]); - }, [ bubblesDisabled ]); - - const showNotification = (type: string, options: Map = null) => - { - if(!options) options = new Map(); - - const configuration = getNotificationConfig(('notification.' + type)); - - if(configuration) for(const key in configuration) options.set(key, configuration[key]); - - if (type === 'floorplan_editor.error') options.set('message', options.get('message').replace(/[^a-zA-Z._ ]/g, '')); - - const title = getNotificationPart(options, type, 'title', true); - const message = getNotificationPart(options, type, 'message', true).replace(/\\r/g, '\r'); - const linkTitle = getNotificationPart(options, type, 'linkTitle', false); - const linkUrl = getNotificationPart(options, type, 'linkUrl', false); - const image = getNotificationImageUrl(options, type); - - if(options.get('display') === 'BUBBLE') - { - showSingleBubble(LocalizeText(message), NotificationBubbleType.INFO, image, linkUrl); - } - else - { - simpleAlert(LocalizeText(message), type, linkUrl, linkTitle, title, image); - } - - if(options.get('sound')) PlaySound(options.get('sound')); - } - - const showConfirm = useCallback((message: string, onConfirm: () => void, onCancel: () => void, confirmText: string = null, cancelText: string = null, title: string = null, type: string = null) => - { - if(!confirmText || !confirmText.length) confirmText = LocalizeText('generic.confirm'); - - if(!cancelText || !cancelText.length) cancelText = LocalizeText('generic.cancel'); - - if(!title || !title.length) title = LocalizeText('notifications.broadcast.title'); - - const confirmItem = new NotificationConfirmItem(type, message, onConfirm, onCancel, confirmText, cancelText, title); - - setConfirms(prevValue => [ confirmItem, ...prevValue ]); - }, []); - - const showModeratorMessage = (message: string, url: string = null, showHabboWay: boolean = true) => - { - simpleAlert(message, NotificationAlertType.DEFAULT, url, LocalizeText('mod.alert.link'), LocalizeText('mod.alert.title')); - } - - const showTradeAlert = useCallback((type: number, otherUsername: string = '') => - { - switch(type) - { - case TradingNotificationType.ALERT_SCAM: - simpleAlert(LocalizeText('inventory.trading.warning.other_not_offering'), null, null, null, LocalizeText('inventory.trading.notification.title')); - return; - case TradingNotificationType.HOTEL_TRADING_DISABLED: - case TradingNotificationType.YOU_NOT_ALLOWED: - case TradingNotificationType.THEY_NOT_ALLOWED: - case TradingNotificationType.ROOM_DISABLED: - case TradingNotificationType.YOU_OPEN: - case TradingNotificationType.THEY_OPEN: - simpleAlert(LocalizeText(`inventory.trading.openfail.${ type }`, [ 'otherusername' ], [ otherUsername ]), null, null, null, LocalizeText('inventory.trading.openfail.title')); - return; - case TradingNotificationType.ERROR_WHILE_COMMIT: - simpleAlert(`${ LocalizeText('inventory.trading.notification.caption') }, ${ LocalizeText('inventory.trading.notification.commiterror.info') }`, null, null, null, LocalizeText('inventory.trading.notification.title')); - return; - case TradingNotificationType.THEY_CANCELLED: - simpleAlert(LocalizeText('inventory.trading.info.closed'), null, null, null, LocalizeText('inventory.trading.notification.title')); - return; - } - }, [ simpleAlert ]); - - const closeAlert = useCallback((alert: NotificationAlertItem) => - { - setAlerts(prevValue => - { - const newAlerts = [ ...prevValue ]; - const index = newAlerts.findIndex(value => (alert === value)); - - if(index >= 0) newAlerts.splice(index, 1); - - return newAlerts; - }); - }, []); - - const closeBubbleAlert = useCallback((item: NotificationBubbleItem) => - { - setBubbleAlerts(prevValue => - { - const newAlerts = [ ...prevValue ]; - const index = newAlerts.findIndex(value => (item === value)); - - if(index >= 0) newAlerts.splice(index, 1); - - return newAlerts; - }) - }, []); - - const closeConfirm = useCallback((item: NotificationConfirmItem) => - { - setConfirms(prevValue => - { - const newConfirms = [ ...prevValue ]; - const index = newConfirms.findIndex(value => (item === value)); - - if(index >= 0) newConfirms.splice(index, 1); - - return newConfirms; - }) - }, []); - - useMessageEvent(RespectReceivedEvent, event => - { - const parser = event.getParser(); - - if(parser.userId !== GetSessionDataManager().userId) return; - - const text1 = LocalizeText('notifications.text.respect.1'); - const text2 = LocalizeText('notifications.text.respect.2', [ 'count' ], [ parser.respectsReceived.toString() ]); - - showSingleBubble(text1, NotificationBubbleType.RESPECT); - showSingleBubble(text2, NotificationBubbleType.RESPECT); - }); - - useMessageEvent(HabboBroadcastMessageEvent, event => - { - const parser = event.getParser(); - - simpleAlert(parser.message.replace(/\\r/g, '\r'), null, null, LocalizeText('notifications.broadcast.title')); - }); - - useMessageEvent(AchievementNotificationMessageEvent, event => - { - const parser = event.getParser(); - - const text1 = LocalizeText('achievements.levelup.desc'); - const badgeName = LocalizeBadgeName(parser.data.badgeCode); - const badgeImage = GetSessionDataManager().getBadgeUrl(parser.data.badgeCode); - const internalLink = 'questengine/achievements/' + parser.data.category; - - showSingleBubble((text1 + ' ' + badgeName), NotificationBubbleType.ACHIEVEMENT, badgeImage, internalLink); - }); - - useMessageEvent(ClubGiftNotificationEvent, event => - { - const parser = event.getParser(); - - if(parser.numGifts <= 0) return; - - showSingleBubble(parser.numGifts.toString(), NotificationBubbleType.CLUBGIFT, null, ('catalog/open/' + GetConfigurationValue('catalog.links')['hc.hc_gifts'])); - }); - - useMessageEvent(ModeratorMessageEvent, event => - { - const parser = event.getParser(); - - showModeratorMessage(parser.message, parser.url, false); - }); - - useMessageEvent(ActivityPointNotificationMessageEvent, event => - { - const parser = event.getParser(); - - if((parser.amountChanged <= 0) || (parser.type !== 5)) return; - - const imageUrl = GetConfigurationValue('currency.asset.icon.url', '').replace('%type%', parser.type.toString()); - - showSingleBubble(LocalizeText('notifications.text.loyalty.received', [ 'AMOUNT' ], [ parser.amountChanged.toString() ]), NotificationBubbleType.INFO, imageUrl); - }); - - useMessageEvent(UserBannedMessageEvent, event => - { - const parser = event.getParser(); - - showModeratorMessage(parser.message); - }); - - useMessageEvent(HotelClosesAndWillOpenAtEvent, event => - { - const parser = event.getParser(); - - simpleAlert( LocalizeText(('opening.hours.' + (parser.userThrowOutAtClose ? 'disconnected' : 'closed')), [ 'h', 'm' ], [ getTimeZeroPadded(parser.openHour), getTimeZeroPadded(parser.openMinute) ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title')); - }); - - useMessageEvent(PetReceivedMessageEvent, async event => - { - const parser = event.getParser(); - - const text = LocalizeText('notifications.text.' + (parser.boughtAsGift ? 'petbought' : 'petreceived')); - - let imageUrl: string = null; - - const imageResult = GetRoomEngine().getRoomObjectPetImage(parser.pet.typeId, parser.pet.paletteId, parseInt(parser.pet.color, 16), new Vector3d(45 * 3), 64, null, true); - - if(imageResult) imageUrl = (await imageResult.getImage())?.src; - - showSingleBubble(text, NotificationBubbleType.PETLEVEL, imageUrl); - }); - - useMessageEvent(MOTDNotificationEvent, event => - { - const parser = event.getParser(); - - const messages = parser.messages.map(message => cleanText(message)); - - const alertItem = new NotificationAlertItem(messages, NotificationAlertType.MOTD, null, null, LocalizeText('notifications.motd.title')); - - setAlerts(prevValue => [ alertItem, ...prevValue ]); - }); - - useMessageEvent(PetLevelNotificationEvent, async event => - { - const parser = event.getParser(); - - let imageUrl: string = null; - - const imageResult = GetRoomEngine().getRoomObjectPetImage(parser.figureData.typeId, parser.figureData.paletteId, parseInt(parser.figureData.color, 16), new Vector3d(45 * 3), 64, null, true); - - if(imageResult) imageUrl = (await imageResult.getImage())?.src; - - showSingleBubble(LocalizeText('notifications.text.petlevel', [ 'pet_name', 'level' ], [ parser.petName, parser.level.toString() ]), NotificationBubbleType.PETLEVEL, imageUrl); - }); - - useMessageEvent(InfoFeedEnableMessageEvent, event => - { - const parser = event.getParser(); - - setBubblesDisabled(!parser.enabled); - }); - - useMessageEvent(ClubGiftSelectedEvent, event => - { - const parser = event.getParser(); - - if(!parser.products || !parser.products.length) return; - - const productData = parser.products[0]; - - if(!productData) return; - - showSingleBubble(LocalizeText('notifications.text.club_gift.selected'), NotificationBubbleType.INFO, ProductImageUtility.getProductImageUrl(productData.productType, productData.furniClassId, productData.extraParam)); - }); - - useMessageEvent(MaintenanceStatusMessageEvent, event => - { - const parser = event.getParser(); - - simpleAlert(LocalizeText('maintenance.shutdown', [ 'm', 'd' ], [ parser.minutesUntilMaintenance.toString(), parser.duration.toString() ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title')); - }); - - useMessageEvent(ModeratorCautionEvent, event => - { - const parser = event.getParser(); - - showModeratorMessage(parser.message, parser.url); - }); - - useMessageEvent(NotificationDialogMessageEvent, event => - { - const parser = event.getParser(); - - showNotification(parser.type, parser.parameters); - }); - - useMessageEvent(HotelWillCloseInMinutesEvent, event => - { - const parser = event.getParser(); - - simpleAlert(LocalizeText('opening.hours.shutdown', [ 'm' ], [ parser.openMinute.toString() ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title')); - }); - - useMessageEvent(HotelClosedAndOpensEvent, event => - { - const parser = event.getParser(); - - simpleAlert(LocalizeText('opening.hours.disconnected', [ 'h', 'm' ], [ parser.openHour.toString(), parser.openMinute.toString() ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title')); - }); - - useMessageEvent(ConnectionErrorEvent, event => - { - const parser = event.getParser(); - - switch(parser.errorCode) - { - default: - case 0: - simpleAlert(LocalizeText('connection.server.error.desc', [ 'errorCode' ], [ parser.errorCode.toString() ]), NotificationAlertType.ALERT, null, null, LocalizeText('connection.server.error.title')); - break; - case 1001: - case 1002: - case 1003: - case 1004: - case 1005: - case 1006: - case 1007: - case 1008: - case 1009: - case 1010: - case 1011: - case 1012: - case 1013: - case 1014: - case 1015: - case 1016: - case 1017: - case 1018: - case 1019: - // TODO: fix dispose - //event.connection.dispose(); - break; - case 4013: - simpleAlert(LocalizeText('connection.room.maintenance.desc'), NotificationAlertType.ALERT, null, null, LocalizeText('connection.room.maintenance.title')); - break; - } - }); - - useMessageEvent(SimpleAlertMessageEvent, event => - { - const parser = event.getParser(); - - simpleAlert(LocalizeText(parser.alertMessage), NotificationAlertType.DEFAULT, null, null, LocalizeText(parser.titleMessage ? parser.titleMessage : 'notifications.broadcast.title')); - }); - - const onRoomEnterEvent = useCallback(() => - { - if(modDisclaimerShown) return; - - if(RoomEnterEffect.isRunning()) - { - if(modDisclaimerTimeout) return; - - modDisclaimerTimeout = setTimeout(() => - { - onRoomEnterEvent(); - }, (RoomEnterEffect.totalRunningTime + 5000)); - } - else - { - if(modDisclaimerTimeout) - { - clearTimeout(modDisclaimerTimeout); - - modDisclaimerTimeout = null; - } - - showSingleBubble(LocalizeText('mod.chatdisclaimer'), NotificationBubbleType.INFO); - - setModDisclaimerShown(true); - } - }, [ modDisclaimerShown, showSingleBubble ]); - - useMessageEvent(RoomEnterEvent, onRoomEnterEvent); - - return { alerts, bubbleAlerts, confirms, simpleAlert, showNitroAlert, showTradeAlert, showConfirm, showSingleBubble, closeAlert, closeBubbleAlert, closeConfirm }; -} - -export const useNotification = () => useBetween(useNotificationState); diff --git a/src/hooks/purse/index.ts b/src/hooks/purse/index.ts deleted file mode 100644 index d9d1ff7..0000000 --- a/src/hooks/purse/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './usePurse'; diff --git a/src/hooks/purse/usePurse.ts b/src/hooks/purse/usePurse.ts deleted file mode 100644 index e8155ce..0000000 --- a/src/hooks/purse/usePurse.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { ActivityPointNotificationMessageEvent, UserCreditsEvent, UserCurrencyComposer, UserCurrencyEvent, UserSubscriptionComposer, UserSubscriptionEvent, UserSubscriptionParser } from '@nitrots/nitro-renderer'; -import { useEffect, useMemo, useState } from 'react'; -import { useBetween } from 'use-between'; -import { CloneObject, ClubStatus, GetConfigurationValue, IPurse, PlaySound, Purse, SendMessageComposer, SoundNames } from '../../api'; -import { useMessageEvent } from '../events'; - -const usePurseState = () => -{ - const [ purse, setPurse ] = useState(new Purse()); - const hcDisabled = useMemo(() => GetConfigurationValue('hc.disabled', false), []); - - const clubStatus = useMemo(() => - { - if(hcDisabled || (purse.clubDays > 0)) return ClubStatus.ACTIVE; - - if((purse.pastVipDays > 0) || (purse.pastVipDays > 0)) return ClubStatus.EXPIRED; - - return ClubStatus.NONE; - }, [ purse, hcDisabled ]); - - const getCurrencyAmount = (type: number) => - { - if(type === -1) return purse.credits; - - for(const [ key, value ] of purse.activityPoints.entries()) - { - if(key !== type) continue; - - return value; - } - - return 0; - } - - useMessageEvent(UserCreditsEvent, event => - { - const parser = event.getParser(); - - setPurse(prevValue => - { - const newValue = CloneObject(prevValue); - - newValue.credits = parseFloat(parser.credits); - - if(prevValue.credits !== newValue.credits) PlaySound(SoundNames.CREDITS); - - return newValue; - }); - }); - - useMessageEvent(UserCurrencyEvent, event => - { - const parser = event.getParser(); - - setPurse(prevValue => - { - const newValue = CloneObject(prevValue); - - newValue.activityPoints = parser.currencies; - - return newValue; - }); - }); - - useMessageEvent(ActivityPointNotificationMessageEvent, event => - { - const parser = event.getParser(); - - setPurse(prevValue => - { - const newValue = CloneObject(prevValue); - - newValue.activityPoints = new Map(newValue.activityPoints); - - newValue.activityPoints.set(parser.type, parser.amount); - - if(parser.type === 0) PlaySound(SoundNames.DUCKETS) - - return newValue; - }); - }); - - useMessageEvent(UserSubscriptionEvent, event => - { - const parser = event.getParser(); - const productName = parser.productName; - - if((productName !== 'club_habbo') && (productName !== 'habbo_club')) return; - - setPurse(prevValue => - { - const newValue = CloneObject(prevValue); - - newValue.clubDays = Math.max(0, parser.daysToPeriodEnd); - newValue.clubPeriods = Math.max(0, parser.periodsSubscribedAhead); - newValue.isVip = parser.isVip; - newValue.pastClubDays = parser.pastClubDays; - newValue.pastVipDays = parser.pastVipDays; - newValue.isExpiring = ((parser.responseType === UserSubscriptionParser.RESPONSE_TYPE_DISCOUNT_AVAILABLE) ? true : false); - newValue.minutesUntilExpiration = parser.minutesUntilExpiration; - newValue.minutesSinceLastModified = parser.minutesSinceLastModified; - - return newValue; - }); - }); - - useEffect(() => - { - if(hcDisabled) return; - - SendMessageComposer(new UserSubscriptionComposer('habbo_club')); - - const interval = setInterval(() => SendMessageComposer(new UserSubscriptionComposer('habbo_club')), 50000); - - return () => clearInterval(interval); - }, [ hcDisabled ]); - - useEffect(() => - { - SendMessageComposer(new UserCurrencyComposer()); - }, []); - - return { purse, hcDisabled, clubStatus, getCurrencyAmount }; -} - -export const usePurse = () => useBetween(usePurseState); diff --git a/src/hooks/rooms/engine/index.ts b/src/hooks/rooms/engine/index.ts deleted file mode 100644 index 42364b6..0000000 --- a/src/hooks/rooms/engine/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export * from './useFurniAddedEvent'; -export * from './useFurniRemovedEvent'; -export * from './useObjectDeselectedEvent'; -export * from './useObjectDoubleClickedEvent'; -export * from './useObjectRollOutEvent'; -export * from './useObjectRollOverEvent'; -export * from './useObjectSelectedEvent'; -export * from './useUserAddedEvent'; -export * from './useUserRemovedEvent'; diff --git a/src/hooks/rooms/engine/useFurniAddedEvent.ts b/src/hooks/rooms/engine/useFurniAddedEvent.ts deleted file mode 100644 index f5422c6..0000000 --- a/src/hooks/rooms/engine/useFurniAddedEvent.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { useEffect } from 'react'; -import { RoomWidgetUpdateRoomObjectEvent, UI_EVENT_DISPATCHER } from '../../../api'; - -export const useFurniAddedEvent = (isActive: boolean, handler: (event: RoomWidgetUpdateRoomObjectEvent) => void) => -{ - useEffect(() => - { - if(!isActive) return; - - const onRoomWidgetUpdateRoomObjectEvent = (event: RoomWidgetUpdateRoomObjectEvent) => handler(event); - - UI_EVENT_DISPATCHER.addEventListener(RoomWidgetUpdateRoomObjectEvent.FURNI_ADDED, onRoomWidgetUpdateRoomObjectEvent); - - return () => - { - UI_EVENT_DISPATCHER.removeEventListener(RoomWidgetUpdateRoomObjectEvent.FURNI_ADDED, onRoomWidgetUpdateRoomObjectEvent); - } - }, [ isActive, handler ]); -} diff --git a/src/hooks/rooms/engine/useFurniRemovedEvent.ts b/src/hooks/rooms/engine/useFurniRemovedEvent.ts deleted file mode 100644 index ddd1be2..0000000 --- a/src/hooks/rooms/engine/useFurniRemovedEvent.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { useEffect } from 'react'; -import { RoomWidgetUpdateRoomObjectEvent, UI_EVENT_DISPATCHER } from '../../../api'; - -export const useFurniRemovedEvent = (isActive: boolean, handler: (event: RoomWidgetUpdateRoomObjectEvent) => void) => -{ - useEffect(() => - { - if(!isActive) return; - - const onRoomWidgetUpdateRoomObjectEvent = (event: RoomWidgetUpdateRoomObjectEvent) => handler(event); - - UI_EVENT_DISPATCHER.addEventListener(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, onRoomWidgetUpdateRoomObjectEvent); - - return () => - { - UI_EVENT_DISPATCHER.removeEventListener(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, onRoomWidgetUpdateRoomObjectEvent); - } - }, [ isActive, handler ]); -} diff --git a/src/hooks/rooms/engine/useObjectDeselectedEvent.ts b/src/hooks/rooms/engine/useObjectDeselectedEvent.ts deleted file mode 100644 index ba54981..0000000 --- a/src/hooks/rooms/engine/useObjectDeselectedEvent.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { RoomWidgetUpdateRoomObjectEvent } from '../../../api'; -import { useUiEvent } from '../../events'; - -export const useObjectDeselectedEvent = (handler: (event: RoomWidgetUpdateRoomObjectEvent) => void) => -{ - useUiEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED, handler); -} diff --git a/src/hooks/rooms/engine/useObjectDoubleClickedEvent.ts b/src/hooks/rooms/engine/useObjectDoubleClickedEvent.ts deleted file mode 100644 index 66e3673..0000000 --- a/src/hooks/rooms/engine/useObjectDoubleClickedEvent.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { RoomWidgetUpdateRoomObjectEvent } from '../../../api'; -import { useUiEvent } from '../../events'; - -export const useObjectDoubleClickedEvent = (handler: (event: RoomWidgetUpdateRoomObjectEvent) => void) => -{ - useUiEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_DOUBLE_CLICKED, handler); -} diff --git a/src/hooks/rooms/engine/useObjectRollOutEvent.ts b/src/hooks/rooms/engine/useObjectRollOutEvent.ts deleted file mode 100644 index 433ca91..0000000 --- a/src/hooks/rooms/engine/useObjectRollOutEvent.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { RoomWidgetUpdateRoomObjectEvent } from '../../../api'; -import { useUiEvent } from '../../events'; - -export const useObjectRollOutEvent = (handler: (event: RoomWidgetUpdateRoomObjectEvent) => void) => -{ - useUiEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OUT, handler); -} diff --git a/src/hooks/rooms/engine/useObjectRollOverEvent.ts b/src/hooks/rooms/engine/useObjectRollOverEvent.ts deleted file mode 100644 index 2774ef2..0000000 --- a/src/hooks/rooms/engine/useObjectRollOverEvent.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { RoomWidgetUpdateRoomObjectEvent } from '../../../api'; -import { useUiEvent } from '../../events'; - -export const useObjectRollOverEvent = (handler: (event: RoomWidgetUpdateRoomObjectEvent) => void) => -{ - useUiEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OVER, handler); -} diff --git a/src/hooks/rooms/engine/useObjectSelectedEvent.ts b/src/hooks/rooms/engine/useObjectSelectedEvent.ts deleted file mode 100644 index 38db66f..0000000 --- a/src/hooks/rooms/engine/useObjectSelectedEvent.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { RoomWidgetUpdateRoomObjectEvent } from '../../../api'; -import { useUiEvent } from '../../events'; - -export const useObjectSelectedEvent = (handler: (event: RoomWidgetUpdateRoomObjectEvent) => void) => -{ - useUiEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_SELECTED, handler); -} diff --git a/src/hooks/rooms/engine/useUserAddedEvent.ts b/src/hooks/rooms/engine/useUserAddedEvent.ts deleted file mode 100644 index d3c761b..0000000 --- a/src/hooks/rooms/engine/useUserAddedEvent.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { useEffect } from 'react'; -import { RoomWidgetUpdateRoomObjectEvent, UI_EVENT_DISPATCHER } from '../../../api'; - -export const useUserAddedEvent = (isActive: boolean, handler: (event: RoomWidgetUpdateRoomObjectEvent) => void) => -{ - useEffect(() => - { - if(!isActive) return; - - const onRoomWidgetUpdateRoomObjectEvent = (event: RoomWidgetUpdateRoomObjectEvent) => handler(event); - - UI_EVENT_DISPATCHER.addEventListener(RoomWidgetUpdateRoomObjectEvent.USER_ADDED, onRoomWidgetUpdateRoomObjectEvent); - - return () => - { - UI_EVENT_DISPATCHER.removeEventListener(RoomWidgetUpdateRoomObjectEvent.USER_ADDED, onRoomWidgetUpdateRoomObjectEvent); - } - }, [ isActive, handler ]); -} diff --git a/src/hooks/rooms/engine/useUserRemovedEvent.ts b/src/hooks/rooms/engine/useUserRemovedEvent.ts deleted file mode 100644 index 2820241..0000000 --- a/src/hooks/rooms/engine/useUserRemovedEvent.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { useEffect } from 'react'; -import { RoomWidgetUpdateRoomObjectEvent, UI_EVENT_DISPATCHER } from '../../../api'; - -export const useUserRemovedEvent = (isActive: boolean, handler: (event: RoomWidgetUpdateRoomObjectEvent) => void) => -{ - useEffect(() => - { - if(!isActive) return; - - const onRoomWidgetUpdateRoomObjectEvent = (event: RoomWidgetUpdateRoomObjectEvent) => handler(event); - - UI_EVENT_DISPATCHER.addEventListener(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, onRoomWidgetUpdateRoomObjectEvent); - - return () => - { - UI_EVENT_DISPATCHER.removeEventListener(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, onRoomWidgetUpdateRoomObjectEvent); - } - }, [ isActive, handler ]); -} diff --git a/src/hooks/rooms/index.ts b/src/hooks/rooms/index.ts deleted file mode 100644 index e57ecfb..0000000 --- a/src/hooks/rooms/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './engine'; -export * from './promotes'; -export * from './useRoom'; -export * from './widgets'; diff --git a/src/hooks/rooms/promotes/index.ts b/src/hooks/rooms/promotes/index.ts deleted file mode 100644 index b1fd0d3..0000000 --- a/src/hooks/rooms/promotes/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useRoomPromote'; diff --git a/src/hooks/rooms/promotes/useRoomPromote.ts b/src/hooks/rooms/promotes/useRoomPromote.ts deleted file mode 100644 index e534d18..0000000 --- a/src/hooks/rooms/promotes/useRoomPromote.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { RoomEventEvent, RoomEventMessageParser } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { useBetween } from 'use-between'; -import { useMessageEvent } from '../../events'; - -const useRoomPromoteState = () => -{ - const [ promoteInformation, setPromoteInformation ] = useState(null); - const [ isExtended, setIsExtended ] = useState(false); - - useMessageEvent(RoomEventEvent, event => - { - const parser = event.getParser(); - - if (!parser) return; - - setPromoteInformation(parser); - }); - - return { promoteInformation, isExtended, setPromoteInformation, setIsExtended }; -} - -export const useRoomPromote = () => useBetween(useRoomPromoteState); diff --git a/src/hooks/rooms/useRoom.ts b/src/hooks/rooms/useRoom.ts deleted file mode 100644 index 0ad1732..0000000 --- a/src/hooks/rooms/useRoom.ts +++ /dev/null @@ -1,283 +0,0 @@ -import { ColorConverter, GetRenderer, GetRoomEngine, GetStage, IRoomSession, NitroAdjustmentFilter, NitroSprite, NitroTexture, RoomBackgroundColorEvent, RoomEngineEvent, RoomEngineObjectEvent, RoomGeometry, RoomId, RoomObjectCategory, RoomObjectHSLColorEnabledEvent, RoomObjectOperationType, RoomSessionEvent, RoomVariableEnum, Vector3d } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { useBetween } from 'use-between'; -import { CanManipulateFurniture, DispatchUiEvent, GetRoomSession, InitializeRoomInstanceRenderingCanvas, IsFurnitureSelectionDisabled, ProcessRoomObjectOperation, RoomWidgetUpdateBackgroundColorPreviewEvent, RoomWidgetUpdateRoomObjectEvent, SetActiveRoomId, StartRoomSession } from '../../api'; -import { useNitroEvent, useUiEvent } from '../events'; - -const useRoomState = () => -{ - const [ roomSession, setRoomSession ] = useState(null); - const [ roomBackground, setRoomBackground ] = useState(null); - const [ roomFilter, setRoomFilter ] = useState(null); - const [ originalRoomBackgroundColor, setOriginalRoomBackgroundColor ] = useState(0); - - const updateRoomBackgroundColor = (hue: number, saturation: number, lightness: number, original: boolean = false) => - { - if(!roomBackground) return; - - const newColor = ColorConverter.hslToRGB(((((hue & 0xFF) << 16) + ((saturation & 0xFF) << 8)) + (lightness & 0xFF))); - - if(original) setOriginalRoomBackgroundColor(newColor); - - if(!hue && !saturation && !lightness) - { - roomBackground.tint = 0; - } - else - { - roomBackground.tint = newColor; - } - } - - const updateRoomFilter = (color: number) => - { - if(!roomFilter) return; - - const r = ((color >> 16) & 0xFF); - const g = ((color >> 8) & 0xFF); - const b = (color & 0xFF); - - roomFilter.red = (r / 255); - roomFilter.green = (g / 255); - roomFilter.blue = (b / 255); - } - - useUiEvent(RoomWidgetUpdateBackgroundColorPreviewEvent.PREVIEW, event => updateRoomBackgroundColor(event.hue, event.saturation, event.lightness)); - - useUiEvent(RoomWidgetUpdateBackgroundColorPreviewEvent.CLEAR_PREVIEW, event => - { - if(!roomBackground) return; - - roomBackground.tint = originalRoomBackgroundColor; - }); - - useNitroEvent(RoomObjectHSLColorEnabledEvent.ROOM_BACKGROUND_COLOR, event => - { - if(RoomId.isRoomPreviewerId(event.roomId)) return; - - if(event.enable) updateRoomBackgroundColor(event.hue, event.saturation, event.lightness, true); - else updateRoomBackgroundColor(0, 0, 0, true); - }); - - useNitroEvent(RoomBackgroundColorEvent.ROOM_COLOR, event => - { - if(RoomId.isRoomPreviewerId(event.roomId)) return; - - let color = 0x000000; - let brightness = 0xFF; - - if(!event.bgOnly) - { - color = event.color; - brightness = event.brightness; - } - - updateRoomFilter(ColorConverter.hslToRGB(((ColorConverter.rgbToHSL(color) & 0xFFFF00) + brightness))); - }); - - useNitroEvent([ - RoomEngineEvent.INITIALIZED, - RoomEngineEvent.DISPOSED - ], event => - { - if(RoomId.isRoomPreviewerId(event.roomId)) return; - - const session = GetRoomSession(); - - if(!session) return; - - switch(event.type) - { - case RoomEngineEvent.INITIALIZED: - SetActiveRoomId(event.roomId); - setRoomSession(session); - return; - case RoomEngineEvent.DISPOSED: - setRoomSession(null); - return; - } - }); - - useNitroEvent([ - RoomSessionEvent.CREATED, - RoomSessionEvent.ENDED - ], event => - { - switch(event.type) - { - case RoomSessionEvent.CREATED: - StartRoomSession(event.session); - return; - case RoomSessionEvent.ENDED: - setRoomSession(null); - return; - } - }); - - useNitroEvent([ - RoomEngineObjectEvent.SELECTED, - RoomEngineObjectEvent.DESELECTED, - RoomEngineObjectEvent.ADDED, - RoomEngineObjectEvent.REMOVED, - RoomEngineObjectEvent.PLACED, - RoomEngineObjectEvent.REQUEST_MOVE, - RoomEngineObjectEvent.REQUEST_ROTATE, - RoomEngineObjectEvent.MOUSE_ENTER, - RoomEngineObjectEvent.MOUSE_LEAVE, - RoomEngineObjectEvent.DOUBLE_CLICK - ], event => - { - if(RoomId.isRoomPreviewerId(event.roomId)) return; - - let updateEvent: RoomWidgetUpdateRoomObjectEvent = null; - - switch(event.type) - { - case RoomEngineObjectEvent.SELECTED: - if(!IsFurnitureSelectionDisabled(event)) updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_SELECTED, event.objectId, event.category, event.roomId); - break; - case RoomEngineObjectEvent.DESELECTED: - updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED, event.objectId, event.category, event.roomId); - break; - case RoomEngineObjectEvent.ADDED: { - let addedEventType: string = null; - - switch(event.category) - { - case RoomObjectCategory.FLOOR: - case RoomObjectCategory.WALL: - addedEventType = RoomWidgetUpdateRoomObjectEvent.FURNI_ADDED; - break; - case RoomObjectCategory.UNIT: - addedEventType = RoomWidgetUpdateRoomObjectEvent.USER_ADDED; - break; - } - - if(addedEventType) updateEvent = new RoomWidgetUpdateRoomObjectEvent(addedEventType, event.objectId, event.category, event.roomId); - break; - } - case RoomEngineObjectEvent.REMOVED: { - let removedEventType: string = null; - - switch(event.category) - { - case RoomObjectCategory.FLOOR: - case RoomObjectCategory.WALL: - removedEventType = RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED; - break; - case RoomObjectCategory.UNIT: - removedEventType = RoomWidgetUpdateRoomObjectEvent.USER_REMOVED; - break; - } - - if(removedEventType) updateEvent = new RoomWidgetUpdateRoomObjectEvent(removedEventType, event.objectId, event.category, event.roomId); - break; - } - case RoomEngineObjectEvent.REQUEST_MOVE: - if(CanManipulateFurniture(roomSession, event.objectId, event.category)) ProcessRoomObjectOperation(event.objectId, event.category, RoomObjectOperationType.OBJECT_MOVE); - break; - case RoomEngineObjectEvent.REQUEST_ROTATE: - if(CanManipulateFurniture(roomSession, event.objectId, event.category)) ProcessRoomObjectOperation(event.objectId, event.category, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE); - break; - case RoomEngineObjectEvent.MOUSE_ENTER: - updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OVER, event.objectId, event.category, event.roomId); - break; - case RoomEngineObjectEvent.MOUSE_LEAVE: - updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OUT, event.objectId, event.category, event.roomId); - break; - case RoomEngineObjectEvent.DOUBLE_CLICK: - updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_DOUBLE_CLICKED, event.objectId, event.category, event.roomId); - break; - } - - if(updateEvent) DispatchUiEvent(updateEvent); - }); - - useEffect(() => - { - if(!roomSession) return; - - const roomEngine = GetRoomEngine(); - const roomId = roomSession.roomId; - const canvasId = 1; - const width = Math.floor(window.innerWidth); - const height = Math.floor(window.innerHeight); - const renderer = GetRenderer(); - - if(renderer) renderer.resize(width, height); - - const displayObject = roomEngine.getRoomInstanceDisplay(roomId, canvasId, width, height, RoomGeometry.SCALE_ZOOMED_IN); - const canvas = GetRoomEngine().getRoomInstanceRenderingCanvas(roomId, canvasId); - - if(!displayObject || !canvas) return; - - const background = new NitroSprite(NitroTexture.WHITE); - const filter = new NitroAdjustmentFilter(); - const master = canvas.master; - - background.tint = 0; - background.width = width; - background.height = height; - - master.addChildAt(background, 0); - master.filters = [ filter ]; - - setRoomBackground(background); - setRoomFilter(filter); - - const geometry = (roomEngine.getRoomInstanceGeometry(roomId, canvasId) as RoomGeometry); - - if(geometry) - { - const minX = (roomEngine.getRoomInstanceVariable(roomId, RoomVariableEnum.ROOM_MIN_X) || 0); - const maxX = (roomEngine.getRoomInstanceVariable(roomId, RoomVariableEnum.ROOM_MAX_X) || 0); - const minY = (roomEngine.getRoomInstanceVariable(roomId, RoomVariableEnum.ROOM_MIN_Y) || 0); - const maxY = (roomEngine.getRoomInstanceVariable(roomId, RoomVariableEnum.ROOM_MAX_Y) || 0); - - let x = ((minX + maxX) / 2); - let y = ((minY + maxY) / 2); - - const offset = 20; - - x = (x + (offset - 1)); - y = (y + (offset - 1)); - - const z = (Math.sqrt(((offset * offset) + (offset * offset))) * Math.tan(((30 / 180) * Math.PI))); - - geometry.location = new Vector3d(x, y, z); - } - - GetStage().addChild(displayObject); - - SetActiveRoomId(roomSession.roomId); - - const resize = (event: UIEvent) => - { - const width = Math.floor(window.innerWidth); - const height = Math.floor(window.innerHeight); - - renderer.resolution = window.devicePixelRatio; - renderer.resize(width, height); - - background.width = width; - background.height = height; - - InitializeRoomInstanceRenderingCanvas(width, height, 1); - } - - window.addEventListener('resize', resize); - - return () => - { - setRoomBackground(null); - setRoomFilter(null); - setOriginalRoomBackgroundColor(0); - - window.removeEventListener('resize', resize); - } - }, [ roomSession ]); - - return { roomSession }; -} - -export const useRoom = () => useBetween(useRoomState); diff --git a/src/hooks/rooms/widgets/furniture/index.ts b/src/hooks/rooms/widgets/furniture/index.ts deleted file mode 100644 index 37fa573..0000000 --- a/src/hooks/rooms/widgets/furniture/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -export * from './useFurnitureBackgroundColorWidget'; -export * from './useFurnitureBadgeDisplayWidget'; -export * from './useFurnitureContextMenuWidget'; -export * from './useFurnitureCraftingWidget'; -export * from './useFurnitureDimmerWidget'; -export * from './useFurnitureExchangeWidget'; -export * from './useFurnitureExternalImageWidget'; -export * from './useFurnitureFriendFurniWidget'; -export * from './useFurnitureHighScoreWidget'; -export * from './useFurnitureInternalLinkWidget'; -export * from './useFurnitureMannequinWidget'; -export * from './useFurniturePlaylistEditorWidget'; -export * from './useFurniturePresentWidget'; -export * from './useFurnitureRoomLinkWidget'; -export * from './useFurnitureSpamWallPostItWidget'; -export * from './useFurnitureStackHeightWidget'; -export * from './useFurnitureStickieWidget'; -export * from './useFurnitureTrophyWidget'; -export * from './useFurnitureYoutubeWidget'; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureBackgroundColorWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureBackgroundColorWidget.ts deleted file mode 100644 index a605f28..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureBackgroundColorWidget.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { ApplyTonerComposer, ColorConverter, GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { CanManipulateFurniture, ColorUtils, DispatchUiEvent, RoomWidgetUpdateBackgroundColorPreviewEvent, SendMessageComposer } from '../../../../api'; -import { useNitroEvent } from '../../../events'; -import { useFurniRemovedEvent } from '../../engine'; -import { useRoom } from '../../useRoom'; - -const useFurnitureBackgroundColorWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ color, setColor ] = useState(0); - const { roomSession = null } = useRoom(); - - const applyToner = () => - { - const hsl = ColorConverter.rgbToHSL(color); - const [ _, hue, saturation, lightness ] = ColorUtils.int_to_8BitVals(hsl); - SendMessageComposer(new ApplyTonerComposer(objectId, hue, saturation, lightness)); - } - - const toggleToner = () => roomSession.useMultistateItem(objectId); - - const onClose = () => - { - DispatchUiEvent(new RoomWidgetUpdateBackgroundColorPreviewEvent(RoomWidgetUpdateBackgroundColorPreviewEvent.CLEAR_PREVIEW)); - - setObjectId(-1); - setCategory(-1); - setColor(0); - } - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, event => - { - if(!CanManipulateFurniture(roomSession, event.objectId, event.category)) return; - - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - const model = roomObject.model; - - setObjectId(event.objectId); - setCategory(event.category) - const hue = parseInt(model.getValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_HUE)); - const saturation = parseInt(model.getValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION)); - const light = parseInt(model.getValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS)); - - const hsl = ColorUtils.eight_bitVals_to_int(0, hue,saturation,light); - - const rgbColor = ColorConverter.hslToRGB(hsl); - setColor(rgbColor); - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - useEffect(() => - { - if((objectId === -1) || (category === -1)) return; - - const hls = ColorConverter.rgbToHSL(color); - const [ _, hue, saturation, lightness ] = ColorUtils.int_to_8BitVals(hls); - DispatchUiEvent(new RoomWidgetUpdateBackgroundColorPreviewEvent(RoomWidgetUpdateBackgroundColorPreviewEvent.PREVIEW, hue, saturation, lightness)); - }, [ objectId, category, color ]); - - return { objectId, color, setColor, applyToner, toggleToner, onClose }; -} - -export const useFurnitureBackgroundColorWidget = useFurnitureBackgroundColorWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureBadgeDisplayWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureBadgeDisplayWidget.ts deleted file mode 100644 index 1cc513c..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureBadgeDisplayWidget.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, RoomEngineTriggerWidgetEvent, RoomObjectVariable, StringDataType } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { LocalizeBadgeDescription, LocalizeBadgeName, LocalizeText } from '../../../../api'; -import { useNitroEvent } from '../../../events'; -import { useNotification } from '../../../notification'; -import { useFurniRemovedEvent } from '../../engine'; - -const useFurnitureBadgeDisplayWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ color, setColor ] = useState('1'); - const [ badgeName, setBadgeName ] = useState(''); - const [ badgeDesc, setBadgeDesc ] = useState(''); - const [ date, setDate ] = useState(''); - const [ senderName, setSenderName ] = useState(''); - const { simpleAlert = null } = useNotification(); - - const onClose = () => - { - setObjectId(-1); - setCategory(-1); - setColor('1'); - setBadgeName(''); - setBadgeDesc(''); - setDate(''); - setSenderName(''); - } - - useNitroEvent([ - RoomEngineTriggerWidgetEvent.REQUEST_BADGE_DISPLAY_ENGRAVING, - RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING - ], event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - const stringStuff = new StringDataType(); - - stringStuff.initializeFromRoomObjectModel(roomObject.model); - - setObjectId(event.objectId); - setCategory(event.category); - setColor('1'); - setBadgeName(LocalizeBadgeName(stringStuff.getValue(1))); - setBadgeDesc(LocalizeBadgeDescription(stringStuff.getValue(1))); - setDate(stringStuff.getValue(2)); - setSenderName(stringStuff.getValue(3)); - }); - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_FAILED, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - const ownerId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID); - - if(ownerId !== GetSessionDataManager().userId) return; - - simpleAlert(`${ LocalizeText('resolution.failed.subtitle') } ${ LocalizeText('resolution.failed.text') }`, null, null, null, LocalizeText('resolution.failed.title')); - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - return { objectId, category, color, badgeName, badgeDesc, date, senderName, onClose }; -} - -export const useFurnitureBadgeDisplayWidget = useFurnitureBadgeDisplayWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureContextMenuWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureContextMenuWidget.ts deleted file mode 100644 index c9616bb..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureContextMenuWidget.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { ContextMenuEnum, GetRoomEngine, GroupFurniContextMenuInfoMessageEvent, GroupFurniContextMenuInfoMessageParser, RoomEngineTriggerWidgetEvent, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { IsOwnerOfFurniture, TryJoinGroup, TryVisitRoom } from '../../../../api'; -import { useMessageEvent, useNitroEvent } from '../../../events'; -import { useRoom } from '../../useRoom'; - -export const MONSTERPLANT_SEED_CONFIRMATION: string = 'MONSTERPLANT_SEED_CONFIRMATION'; -export const PURCHASABLE_CLOTHING_CONFIRMATION: string = 'PURCHASABLE_CLOTHING_CONFIRMATION'; -export const GROUP_FURNITURE: string = 'GROUP_FURNITURE'; -export const EFFECTBOX_OPEN: string = 'EFFECTBOX_OPEN'; -export const MYSTERYTROPHY_OPEN_DIALOG: string = 'MYSTERYTROPHY_OPEN_DIALOG'; - -const useFurnitureContextMenuWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ mode, setMode ] = useState(null); - const [ confirmMode, setConfirmMode ] = useState(null); - const [ confirmingObjectId, setConfirmingObjectId ] = useState(-1); - const [ groupData, setGroupData ] = useState(null); - const [ isGroupMember, setIsGroupMember ] = useState(false); - const [ objectOwnerId, setObjectOwnerId ] = useState(-1); - const { roomSession = null } = useRoom(); - - const onClose = () => - { - setObjectId(-1); - setGroupData(null); - setIsGroupMember(false); - setMode(null); - } - - const closeConfirm = () => - { - setConfirmMode(null); - setConfirmingObjectId(-1); - } - - const processAction = (name: string) => - { - if(name) - { - switch(name) - { - case 'use_friend_furni': - roomSession.useMultistateItem(objectId); - break; - case 'use_monsterplant_seed': - setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION); - setConfirmingObjectId(objectId); - break; - case 'use_random_teleport': - GetRoomEngine().useRoomObject(objectId, RoomObjectCategory.FLOOR); - break; - case 'use_purchaseable_clothing': - setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION); - setConfirmingObjectId(objectId); - break; - case 'use_mystery_box': - roomSession.useMultistateItem(objectId); - break; - case 'use_mystery_trophy': - setConfirmMode(MYSTERYTROPHY_OPEN_DIALOG); - setConfirmingObjectId(objectId); - break; - case 'join_group': - TryJoinGroup(groupData.guildId); - setIsGroupMember(true); - return; - case 'go_to_group_homeroom': - if(groupData) TryVisitRoom(groupData.guildHomeRoomId); - break; - } - } - - onClose(); - } - - useNitroEvent([ - RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU, - RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU, - RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG, - RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG, - RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG, - RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYBOX_OPEN_DIALOG, - RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYTROPHY_OPEN_DIALOG - ], event => - { - const object = GetRoomEngine().getRoomObject(roomSession.roomId, event.objectId, event.category); - - if(!object) return; - - setObjectOwnerId(object.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID)); - - switch(event.type) - { - case RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG: - if(!IsOwnerOfFurniture(object)) return; - - setConfirmingObjectId(object.id); - setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION); - - onClose(); - return; - case RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG: - if(!IsOwnerOfFurniture(object)) return; - - setConfirmingObjectId(object.id); - setConfirmMode(EFFECTBOX_OPEN); - - onClose(); - return; - case RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG: - if(!IsOwnerOfFurniture(object)) return; - - setConfirmingObjectId(object.id); - setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION); - - onClose(); - return; - case RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYBOX_OPEN_DIALOG: - roomSession.useMultistateItem(object.id); - - onClose(); - return; - case RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYTROPHY_OPEN_DIALOG: - if(!IsOwnerOfFurniture(object)) return; - - setConfirmingObjectId(object.id); - setConfirmMode(MYSTERYTROPHY_OPEN_DIALOG); - - onClose(); - return; - case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU: - - setObjectId(object.id); - - switch(event.contextMenu) - { - case ContextMenuEnum.FRIEND_FURNITURE: - setMode(ContextMenuEnum.FRIEND_FURNITURE); - return; - case ContextMenuEnum.MONSTERPLANT_SEED: - if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.MONSTERPLANT_SEED); - return; - case ContextMenuEnum.MYSTERY_BOX: - setMode(ContextMenuEnum.MYSTERY_BOX); - return; - case ContextMenuEnum.MYSTERY_TROPHY: - if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.MYSTERY_TROPHY); - return; - case ContextMenuEnum.RANDOM_TELEPORT: - setMode(ContextMenuEnum.RANDOM_TELEPORT); - return; - case ContextMenuEnum.PURCHASABLE_CLOTHING: - if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.PURCHASABLE_CLOTHING); - return; - } - - return; - case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU: - if(object.id === objectId) onClose(); - return; - } - }); - - useMessageEvent(GroupFurniContextMenuInfoMessageEvent, event => - { - const parser = event.getParser(); - - setObjectId(parser.objectId); - setGroupData(parser); - setIsGroupMember(parser.userIsMember); - setMode(GROUP_FURNITURE); - }); - - return { objectId, mode, confirmMode, confirmingObjectId, groupData, isGroupMember, objectOwnerId, closeConfirm, processAction, onClose }; -} - -export const useFurnitureContextMenuWidget = useFurnitureContextMenuWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureCraftingWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureCraftingWidget.ts deleted file mode 100644 index d2bca20..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureCraftingWidget.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { CraftableProductsEvent, CraftComposer, CraftingRecipeEvent, CraftingRecipeIngredientParser, CraftingRecipesAvailableEvent, CraftingResultEvent, GetCraftableProductsComposer, GetCraftingRecipeComposer, GetRoomContentLoader, GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomWidgetEnum } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { ICraftingIngredient, ICraftingRecipe, LocalizeText, SendMessageComposer } from '../../../../api'; -import { useMessageEvent, useNitroEvent } from '../../../events'; -import { useInventoryFurni } from '../../../inventory'; -import { useNotification } from './../../../notification'; - -const useFurnitureCraftingWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ recipes, setRecipes ] = useState([]); - const [ selectedRecipe, setSelectedRecipe ] = useState(null); - const [ ingredients, setIngredients ] = useState([]); - const [ ingredientNames, setIngredientNames ] = useState(null); - const [ cachedIngredients, setCachedIngredients ] = useState>(new Map()); - const [ isCrafting, setIsCrafting ] = useState(false); - const { groupItems = [], getItemsByType = null, activate = null, deactivate = null } = useInventoryFurni(); - const { simpleAlert = null } = useNotification(); - - const requiredIngredients = ((selectedRecipe && cachedIngredients.get(selectedRecipe.name) || null)); - - const resetData = () => - { - setRecipes([]); - setSelectedRecipe(null); - setIngredients([]); - setCachedIngredients(new Map()); - }; - - const onClose = () => - { - setObjectId(-1); - resetData(); - }; - - const craft = () => - { - setIsCrafting(true); - - SendMessageComposer(new CraftComposer(objectId, selectedRecipe.name)); - }; - - const selectRecipe = (recipe: ICraftingRecipe) => - { - setSelectedRecipe(recipe); - - const cache = cachedIngredients.get(recipe.name); - - if(!cache) SendMessageComposer(new GetCraftingRecipeComposer(recipe.name)); - } - - useNitroEvent(RoomEngineTriggerWidgetEvent.OPEN_WIDGET, event => - { - if (event.widget !== RoomWidgetEnum.CRAFTING) return; - - setObjectId(event.objectId); - resetData(); - SendMessageComposer(new GetCraftableProductsComposer(event.objectId)); - }); - - useMessageEvent(CraftableProductsEvent, event => - { - const parser = event.getParser(); - - if (!parser.isActive()) - { - setObjectId(-1); - - return; - } - - setRecipes(prevValue => - { - const newValue: ICraftingRecipe[] = []; - - for(const recipe of parser.recipes) - { - //@ts-ignore - const itemId = GetRoomContentLoader()._activeObjectTypeIds.get(recipe.itemName); - const iconUrl = GetRoomEngine().getFurnitureFloorIconUrl(itemId); - - newValue.push({ - name: recipe.recipeName, - localizedName: LocalizeText('roomItem.name.' + itemId), - iconUrl - }); - } - - return newValue; - }); - - setIngredientNames(parser.ingredients); - }); - - useMessageEvent(CraftingRecipeEvent, event => - { - const parser = event.getParser(); - - setCachedIngredients(prevValue => - { - const newValue = new Map(prevValue); - - newValue.set(selectedRecipe.name, parser.ingredients); - - return newValue; - }); - }); - - useMessageEvent(CraftingResultEvent, event => - { - setSelectedRecipe(null); - setIsCrafting(false); - - const parser = event.getParser(); - - if(parser.result) simpleAlert(LocalizeText('crafting.info.result.ok')); - }); - - useMessageEvent(CraftingRecipesAvailableEvent, event => - { - }); - - useEffect(() => - { - if(!ingredientNames || !ingredientNames.length) return; - - setIngredients(prevValue => - { - const newValue: ICraftingIngredient[] = []; - - for(const name of ingredientNames) - { - //@ts-ignore - const itemId = GetRoomContentLoader()._activeObjectTypeIds.get(name); - const iconUrl = GetRoomEngine().getFurnitureFloorIconUrl(itemId); - - const inventoryItems = getItemsByType(itemId); - - let amountAvailable = 0; - - if (inventoryItems) for (const inventoryItem of inventoryItems) amountAvailable += inventoryItem.items.length; - - newValue.push({ - name: name, - iconUrl, - count: amountAvailable - }); - } - - return newValue; - }); - }, [ groupItems, ingredientNames, getItemsByType ]); - - useEffect(() => - { - if((objectId === -1)) return; - - const id = activate(); - - return () => deactivate(id); - }, [ objectId, activate, deactivate ]); - - return { objectId, recipes, ingredients, selectedRecipe, requiredIngredients, isCrafting, selectRecipe, craft, onClose }; -} - -export const useFurnitureCraftingWidget = useFurnitureCraftingWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureDimmerWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureDimmerWidget.ts deleted file mode 100644 index 5c206a7..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureDimmerWidget.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { GetSessionDataManager, RoomControllerLevel, RoomEngineDimmerStateEvent, RoomEngineTriggerWidgetEvent, RoomId, RoomSessionDimmerPresetsEvent } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { DimmerFurnitureWidgetPresetItem, FurnitureDimmerUtilities } from '../../../../api'; -import { useNitroEvent } from '../../../events'; -import { useRoom } from '../../useRoom'; - -const useFurnitureDimmerWidgetState = () => -{ - const [ presets, setPresets ] = useState([]); - const [ selectedPresetId, setSelectedPresetId ] = useState(0); - const [ dimmerState, setDimmerState ] = useState(0); - const [ lastDimmerState, setLastDimmerState ] = useState(0); - const [ effectId, setEffectId ] = useState(0); - const [ color, setColor ] = useState(0xFFFFFF); - const [ brightness, setBrightness ] = useState(0xFF); - const [ selectedEffectId, setSelectedEffectId ] = useState(0); - const [ selectedColor, setSelectedColor ] = useState(0); - const [ selectedBrightness, setSelectedBrightness ] = useState(0); - const { roomSession = null } = useRoom(); - - const canOpenWidget = () => (roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator); - - const selectPresetId = (id: number) => - { - const preset = presets[(id - 1)]; - - if(!preset) return; - - setSelectedPresetId(preset.id); - setSelectedEffectId(preset.type); - setSelectedColor(preset.color); - setSelectedBrightness(preset.light); - } - - const applyChanges = () => - { - if(dimmerState === 0) return; - - const selectedPresetIndex = (selectedPresetId - 1); - - if((selectedPresetId < 1) || (selectedPresetId > presets.length)) return; - - const preset = presets[selectedPresetIndex]; - - if(!preset || ((selectedEffectId === preset.type) && (selectedColor === preset.color) && (selectedBrightness === preset.light))) return; - - setPresets(prevValue => - { - const newValue = [ ...prevValue ]; - - newValue[selectedPresetIndex] = new DimmerFurnitureWidgetPresetItem(preset.id, selectedEffectId, selectedColor, selectedBrightness); - - return newValue; - }); - - FurnitureDimmerUtilities.savePreset(preset.id, selectedEffectId, selectedColor, selectedBrightness, true); - } - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_DIMMER, event => - { - if(!canOpenWidget()) return; - - roomSession.requestMoodlightSettings(); - }); - - useNitroEvent(RoomSessionDimmerPresetsEvent.ROOM_DIMMER_PRESETS, event => - { - const presets: DimmerFurnitureWidgetPresetItem[] = []; - - let i = 0; - - while(i < event.presetCount) - { - const preset = event.getPreset(i); - - if(preset) presets.push(new DimmerFurnitureWidgetPresetItem(preset.id, preset.type, preset.color, preset.brightness)); - - i++; - } - - setPresets(presets); - setSelectedPresetId(event.selectedPresetId); - }); - - useNitroEvent(RoomEngineDimmerStateEvent.ROOM_COLOR, event => - { - if(RoomId.isRoomPreviewerId(event.roomId)) return; - - setLastDimmerState(dimmerState); - setDimmerState(event.state); - setSelectedPresetId(event.presetId); - setEffectId(event.effectId); - setSelectedEffectId(event.effectId); - setColor(event.color); - setSelectedColor(event.color); - setBrightness(event.brightness); - setSelectedBrightness(event.brightness); - }); - - useEffect(() => - { - if((dimmerState === 0) && (lastDimmerState === 0)) return; - - FurnitureDimmerUtilities.previewDimmer(selectedColor, selectedBrightness, (selectedEffectId === 2)); - }, [ dimmerState, lastDimmerState, selectedColor, selectedBrightness, selectedEffectId ]); - - return { presets, selectedPresetId, dimmerState, lastDimmerState, effectId, color, brightness, selectedEffectId, setSelectedEffectId, selectedColor, setSelectedColor, selectedBrightness, setSelectedBrightness, selectPresetId, applyChanges }; -} - -export const useFurnitureDimmerWidget = useFurnitureDimmerWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureExchangeWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureExchangeWidget.ts deleted file mode 100644 index dc3404f..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureExchangeWidget.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { FurnitureExchangeComposer, GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { IsOwnerOfFurniture, SendMessageComposer } from '../../../../api'; -import { useNitroEvent } from '../../../events'; -import { useFurniRemovedEvent } from '../../engine'; - -const useFurnitureExchangeWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ value, setValue ] = useState(0); - - const onClose = () => - { - setObjectId(-1); - setCategory(-1); - setValue(0); - } - - const redeem = () => - { - SendMessageComposer(new FurnitureExchangeComposer(objectId)); - - onClose(); - } - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_CREDITFURNI, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject || !IsOwnerOfFurniture(roomObject)) return; - - setObjectId(event.objectId); - setCategory(event.category); - setValue(roomObject.model.getValue(RoomObjectVariable.FURNITURE_CREDIT_VALUE) || 0); - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - return { objectId, value, redeem, onClose }; -} - -export const useFurnitureExchangeWidget = useFurnitureExchangeWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureExternalImageWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureExternalImageWidget.ts deleted file mode 100644 index 5e5aa99..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureExternalImageWidget.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { IPhotoData } from '../../../../api'; -import { useNitroEvent } from '../../../events'; -import { useFurniRemovedEvent } from '../../engine'; -import { useRoom } from '../../useRoom'; - -const useFurnitureExternalImageWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ currentPhotoIndex, setCurrentPhotoIndex ] = useState(-1); - const [ currentPhotos, setCurrentPhotos ] = useState([]); - const { roomSession = null } = useRoom(); - - const onClose = () => - { - setObjectId(-1); - setCategory(-1); - setCurrentPhotoIndex(-1); - setCurrentPhotos([]); - } - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_EXTERNAL_IMAGE, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - const roomTotalImages = GetRoomEngine().getRoomObjects(roomSession?.roomId, RoomObjectCategory.WALL); - - if(!roomObject) return; - - const datas: IPhotoData[] = []; - - roomTotalImages.forEach(object => - { - if (object.type !== 'external_image_wallitem_poster_small') return null; - - const data = object.model.getValue(RoomObjectVariable.FURNITURE_DATA); - const jsonData: IPhotoData = JSON.parse(data); - - datas.push(jsonData); - }); - - setObjectId(event.objectId); - setCategory(event.category); - setCurrentPhotos(datas); - - const roomObjectPhotoData = (JSON.parse(roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA)) as IPhotoData); - - setCurrentPhotoIndex(prevValue => - { - let index = 0; - - if(roomObjectPhotoData) - { - index = datas.findIndex(data => (data.u === roomObjectPhotoData.u)) - } - - if(index < 0) index = 0; - - return index; - }); - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - return { objectId, currentPhotoIndex, currentPhotos, onClose }; -} - -export const useFurnitureExternalImageWidget = useFurnitureExternalImageWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureFriendFurniWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureFriendFurniWidget.ts deleted file mode 100644 index 3517d39..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureFriendFurniWidget.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { FriendFurniConfirmLockMessageComposer, GetRoomEngine, LoveLockFurniFinishedEvent, LoveLockFurniFriendConfirmedEvent, LoveLockFurniStartEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { SendMessageComposer } from '../../../../api'; -import { useMessageEvent, useNitroEvent } from '../../../events'; -import { useFurniRemovedEvent } from '../../engine'; - -const useFurnitureFriendFurniWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ type, setType ] = useState(0); - const [ usernames, setUsernames ] = useState([]); - const [ figures, setFigures ] = useState([]); - const [ date, setDate ] = useState(null); - const [ stage, setStage ] = useState(0); - - const onClose = () => - { - setObjectId(-1); - setCategory(-1); - setType(0); - setUsernames([]); - setFigures([]); - setDate(null); - } - - const respond = (flag: boolean) => - { - SendMessageComposer(new FriendFurniConfirmLockMessageComposer(objectId, flag)); - - onClose(); - } - - useMessageEvent(LoveLockFurniStartEvent, event => - { - const parser = event.getParser(); - - setObjectId(parser.furniId); - setStage(parser.start ? 1 : 2); - }); - - useMessageEvent(LoveLockFurniFinishedEvent, event => onClose()); - useMessageEvent(LoveLockFurniFriendConfirmedEvent, event => onClose()); - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_FRIEND_FURNITURE_ENGRAVING, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - const data = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA); - const type = roomObject.model.getValue(RoomObjectVariable.FURNITURE_FRIENDFURNI_ENGRAVING); - - if((data[0] !== '1') || (data.length !== 6)) return; - - setObjectId(event.objectId); - setCategory(event.category); - setType(type); - setUsernames([ data[1], data[2] ]); - setFigures([ data[3], data[4] ]); - setDate(data[5]); - setStage(0); - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - return { objectId, type, usernames, figures, date, stage, onClose, respond }; -} - -export const useFurnitureFriendFurniWidget = useFurnitureFriendFurniWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureHighScoreWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureHighScoreWidget.ts deleted file mode 100644 index 08e5038..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureHighScoreWidget.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { GetRoomEngine, HighScoreDataType, ObjectDataFactory, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { useNitroEvent } from '../../../events'; -import { useRoom } from '../../useRoom'; - -const SCORE_TYPES = [ 'perteam', 'mostwins', 'classic' ]; -const CLEAR_TYPES = [ 'alltime', 'daily', 'weekly', 'monthly' ]; - -const useFurnitureHighScoreWidgetState = () => -{ - const [ stuffDatas, setStuffDatas ] = useState>(new Map()); - const { roomSession = null } = useRoom(); - - const getScoreType = (type: number) => SCORE_TYPES[type]; - const getClearType = (type: number) => CLEAR_TYPES[type]; - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_HIGH_SCORE_DISPLAY, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - const formatKey = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA_FORMAT); - const stuffData = (ObjectDataFactory.getData(formatKey) as HighScoreDataType); - - stuffData.initializeFromRoomObjectModel(roomObject.model); - - setStuffDatas(prevValue => - { - const newValue = new Map(prevValue); - - newValue.set(roomObject.id, stuffData); - - return newValue; - }); - }); - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_HIDE_HIGH_SCORE_DISPLAY, event => - { - if(event.roomId !== roomSession.roomId) return; - - setStuffDatas(prevValue => - { - const newValue = new Map(prevValue); - - newValue.delete(event.objectId); - - return newValue; - }); - }); - - return { stuffDatas, getScoreType, getClearType }; -} - -export const useFurnitureHighScoreWidget = useFurnitureHighScoreWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureInternalLinkWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureInternalLinkWidget.ts deleted file mode 100644 index 27e6b2e..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureInternalLinkWidget.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { CreateLinkEvent, GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useNitroEvent } from '../../../events'; - -const INTERNALLINK = 'internalLink'; - -const useFurnitureInternalLinkWidgetState = () => -{ - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_INTERNAL_LINK, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - const data = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA); - - let link = data[INTERNALLINK]; - - if(!link || !link.length) link = roomObject.model.getValue(RoomObjectVariable.FURNITURE_INTERNAL_LINK); - - if(link && link.length) CreateLinkEvent(link); - }); - - return {}; -} - -export const useFurnitureInternalLinkWidget = useFurnitureInternalLinkWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureMannequinWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureMannequinWidget.ts deleted file mode 100644 index 3e88457..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureMannequinWidget.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { FurnitureMannequinSaveLookComposer, FurnitureMannequinSaveNameComposer, FurnitureMultiStateComposer, GetAvatarRenderManager, GetRoomEngine, HabboClubLevelEnum, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { MannequinUtilities, SendMessageComposer } from '../../../../api'; -import { useNitroEvent } from '../../../events'; -import { useFurniRemovedEvent } from '../../engine'; - -const useFurnitureMannequinWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ figure, setFigure ] = useState(null); - const [ gender, setGender ] = useState(null); - const [ clubLevel, setClubLevel ] = useState(HabboClubLevelEnum.NO_CLUB); - const [ name, setName ] = useState(null); - - const onClose = () => - { - setObjectId(-1); - setCategory(-1); - setFigure(null); - setGender(null); - setName(null); - } - - const saveFigure = () => - { - if(objectId === -1) return; - - SendMessageComposer(new FurnitureMannequinSaveLookComposer(objectId)); - - onClose(); - } - - const wearFigure = () => - { - if(objectId === -1) return; - - SendMessageComposer(new FurnitureMultiStateComposer(objectId)); - - onClose(); - } - - const saveName = () => - { - if(objectId === -1) return; - - SendMessageComposer(new FurnitureMannequinSaveNameComposer(objectId, name)); - } - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - const model = roomObject.model; - const figure = (model.getValue(RoomObjectVariable.FURNITURE_MANNEQUIN_FIGURE) || null); - const gender = (model.getValue(RoomObjectVariable.FURNITURE_MANNEQUIN_GENDER) || null); - const figureContainer = GetAvatarRenderManager().createFigureContainer(figure); - const figureClubLevel = GetAvatarRenderManager().getFigureClubLevel(figureContainer, gender, MannequinUtilities.MANNEQUIN_CLOTHING_PART_TYPES); - - setObjectId(event.objectId); - setCategory(event.category); - setFigure(figure); - setGender(gender); - setClubLevel(figureClubLevel); - setName(model.getValue(RoomObjectVariable.FURNITURE_MANNEQUIN_NAME) || null); - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - return { objectId, figure, gender, clubLevel, name, setName, saveFigure, wearFigure, saveName, onClose }; -} - -export const useFurnitureMannequinWidget = useFurnitureMannequinWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurniturePlaylistEditorWidget.ts b/src/hooks/rooms/widgets/furniture/useFurniturePlaylistEditorWidget.ts deleted file mode 100644 index ec89553..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurniturePlaylistEditorWidget.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { AddJukeboxDiskComposer, AdvancedMap, FurnitureListAddOrUpdateEvent, FurnitureListEvent, FurnitureListRemovedEvent, FurnitureMultiStateComposer, GetRoomEngine, GetSessionDataManager, GetSoundManager, IAdvancedMap, IMessageEvent, ISongInfo, NotifyPlayedSongEvent, NowPlayingEvent, PlayListStatusEvent, RemoveJukeboxDiskComposer, RoomControllerLevel, RoomEngineTriggerWidgetEvent, SongDiskInventoryReceivedEvent } from '@nitrots/nitro-renderer'; -import { useCallback, useState } from 'react'; -import { IsOwnerOfFurniture, LocalizeText, NotificationAlertType, NotificationBubbleType, SendMessageComposer } from '../../../../api'; -import { useMessageEvent, useNitroEvent } from '../../../events'; -import { useNotification } from '../../../notification'; -import { useFurniRemovedEvent } from '../../engine'; -import { useRoom } from '../../useRoom'; - -const useFurniturePlaylistEditorWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ currentPlayingIndex, setCurrentPlayingIndex ] = useState(-1); - const [ diskInventory, setDiskInventory ] = useState>(new AdvancedMap()); - const [ playlist, setPlaylist ] = useState([]); - const { roomSession = null } = useRoom(); - const { showSingleBubble = null, simpleAlert = null } = useNotification(); - - const onClose = () => - { - setObjectId(-1); - setCategory(-1); - } - - const addToPlaylist = useCallback((diskId: number, slotNumber: number) => SendMessageComposer(new AddJukeboxDiskComposer(diskId, slotNumber)), []); - - const removeFromPlaylist = useCallback((slotNumber: number) => SendMessageComposer(new RemoveJukeboxDiskComposer(slotNumber)), []); - - const togglePlayPause = useCallback((furniId: number, position: number) => SendMessageComposer(new FurnitureMultiStateComposer(furniId, position)), []); - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_PLAYLIST_EDITOR, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - if(IsOwnerOfFurniture(roomObject)) - { - // show the editor - setObjectId(event.objectId); - setCategory(event.category); - - GetSoundManager().musicController?.requestUserSongDisks(); - GetSoundManager().musicController?.getRoomItemPlaylist()?.requestPlayList(); - - return; - } - - if(roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator) SendMessageComposer(new FurnitureMultiStateComposer(event.objectId, -2)); - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - useNitroEvent(NowPlayingEvent.NPE_SONG_CHANGED, event => - { - setCurrentPlayingIndex(event.position); - }); - - useNitroEvent(NotifyPlayedSongEvent.NOTIFY_PLAYED_SONG, event => - { - showSingleBubble(LocalizeText('soundmachine.notification.playing', [ 'songname', 'songauthor' ], [ event.name, event.creator ]), NotificationBubbleType.SOUNDMACHINE) - }); - - useNitroEvent(SongDiskInventoryReceivedEvent.SDIR_SONG_DISK_INVENTORY_RECEIVENT_EVENT, event => - { - setDiskInventory(GetSoundManager().musicController?.songDiskInventory.clone()); - }); - - useNitroEvent(PlayListStatusEvent.PLUE_PLAY_LIST_UPDATED, event => - { - setPlaylist(GetSoundManager().musicController?.getRoomItemPlaylist()?.entries.concat()) - }); - - useNitroEvent(PlayListStatusEvent.PLUE_PLAY_LIST_FULL, event => - { - simpleAlert(LocalizeText('playlist.editor.alert.playlist.full'), NotificationAlertType.ALERT, '', '', LocalizeText('playlist.editor.alert.playlist.full.title')); - }); - - const onFurniListUpdated = (event : IMessageEvent) => - { - if(objectId === -1) return; - - if(event instanceof FurnitureListEvent) - { - if(event.getParser().fragmentNumber === 0) - { - GetSoundManager().musicController?.requestUserSongDisks(); - } - } - else - { - GetSoundManager().musicController?.requestUserSongDisks(); - } - } - - useMessageEvent(FurnitureListEvent, onFurniListUpdated); - useMessageEvent(FurnitureListRemovedEvent, onFurniListUpdated); - useMessageEvent(FurnitureListAddOrUpdateEvent, onFurniListUpdated); - - return { objectId, diskInventory, playlist, currentPlayingIndex, onClose, addToPlaylist, removeFromPlaylist, togglePlayPause }; -} - -export const useFurniturePlaylistEditorWidget = useFurniturePlaylistEditorWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurniturePresentWidget.ts b/src/hooks/rooms/widgets/furniture/useFurniturePresentWidget.ts deleted file mode 100644 index 0058885..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurniturePresentWidget.ts +++ /dev/null @@ -1,235 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, IFurnitureData, IGetImageListener, PetFigureData, RoomEngineTriggerWidgetEvent, RoomObjectCategory, RoomObjectVariable, RoomSessionPresentEvent, TextureUtils, Vector3d } from '@nitrots/nitro-renderer'; -import { useMemo, useState } from 'react'; -import { IsOwnerOfFurniture, LocalizeText, ProductTypeEnum } from '../../../../api'; -import { useNitroEvent } from '../../../events'; -import { useFurniRemovedEvent } from '../../engine'; -import { useRoom } from '../../useRoom'; - -const FLOOR: string = 'floor'; -const WALLPAPER: string = 'wallpaper'; -const LANDSCAPE: string = 'landscape'; -const POSTER: string = 'poster'; - -const useFurniturePresentWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ classId, setClassId ] = useState(-1); - const [ itemType, setItemType ] = useState(null); - const [ text, setText ] = useState(null); - const [ isOwnerOfFurniture, setIsOwnerOfFurniture ] = useState(false); - const [ senderName, setSenderName ] = useState(null); - const [ senderFigure, setSenderFigure ] = useState(null); - const [ placedItemId, setPlacedItemId ] = useState(-1); - const [ placedItemType, setPlacedItemType ] = useState(null); - const [ placedInRoom, setPlacedInRoom ] = useState(false); - const [ imageUrl, setImageUrl ] = useState(null); - const { roomSession = null } = useRoom(); - - const onClose = () => - { - setObjectId(-1); - setClassId(-1); - setItemType(null); - setText(null); - setIsOwnerOfFurniture(false); - setSenderName(null); - setSenderFigure(null); - setPlacedItemId(-1); - setPlacedItemType(null); - setPlacedInRoom(false); - setImageUrl(null); - } - - const openPresent = () => - { - if(objectId === -1) return; - - roomSession.openGift(objectId); - - GetRoomEngine().changeObjectModelData(GetRoomEngine().activeRoomId, objectId, RoomObjectCategory.FLOOR, RoomObjectVariable.FURNITURE_DISABLE_PICKING_ANIMATION, 1); - } - - const imageListener: IGetImageListener = useMemo(() => - { - // async fix image - return { - imageReady: (id, texture, image) => - { - (async () => - { - if(!image && texture) - { - image = await TextureUtils.generateImage(texture); - } - - setImageUrl(image.src); - })(); - }, - imageFailed: null - } - }, []); - - useNitroEvent(RoomSessionPresentEvent.RSPE_PRESENT_OPENED, event => - { - let furniData: IFurnitureData = null; - - if(event.itemType === ProductTypeEnum.FLOOR) - { - furniData = GetSessionDataManager().getFloorItemData(event.classId); - } - else if(event.itemType === ProductTypeEnum.WALL) - { - furniData = GetSessionDataManager().getWallItemData(event.classId); - } - - let isOwnerOfFurni = false; - - if(event.placedInRoom) - { - const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, event.placedItemId, RoomObjectCategory.FLOOR); - - if(roomObject) isOwnerOfFurni = IsOwnerOfFurniture(roomObject); - } - - let giftImage: string = null; - - switch(event.itemType) - { - case ProductTypeEnum.WALL: { - if(furniData) - { - switch(furniData.className) - { - case FLOOR: - case LANDSCAPE: - case WALLPAPER: - let imageType = null; - let message = null; - - if(furniData.className === FLOOR) - { - imageType = 'packagecard_icon_floor'; - message = LocalizeText('inventory.furni.item.floor.name'); - } - - else if(furniData.className === LANDSCAPE) - { - imageType = 'packagecard_icon_landscape'; - message = LocalizeText('inventory.furni.item.landscape.name'); - } - - else - { - imageType = 'packagecard_icon_wallpaper'; - message = LocalizeText('inventory.furni.item.wallpaper.name'); - } - - setText(message); - //setImageUrl(getGiftImageUrl(imageType)); - break; - case POSTER: { - const productCode = event.productCode; - - let extras: string = null; - - if(productCode.indexOf('poster') === 0) extras = productCode.replace('poster', ''); - - const productData = GetSessionDataManager().getProductData(productCode); - - let name: string = null; - - if(productData) name = productData.name; - else if(furniData) name = furniData.name; - - setText(name); - setImageUrl(GetRoomEngine().getFurnitureWallIconUrl(event.classId, extras)); - - break; - } - default: { - setText(furniData.name || null); - setImageUrl(GetRoomEngine().getFurnitureWallIconUrl(event.classId)); - break; - } - } - } - - break; - } - case ProductTypeEnum.HABBO_CLUB: - setText(LocalizeText('widget.furni.present.hc')); - //setImageUrl(getGiftImageUrl('packagecard_icon_hc')); - break; - default: { - if(event.placedItemType === ProductTypeEnum.PET) - { - const petfigureString = event.petFigureString; - - if(petfigureString && petfigureString.length) - { - const petFigureData = new PetFigureData(petfigureString); - - (async () => - { - const petImage = GetRoomEngine().getRoomObjectPetImage(petFigureData.typeId, petFigureData.paletteId, petFigureData.color, new Vector3d(90), 64, imageListener, true, 0, petFigureData.customParts); - - if(petImage) setImageUrl((await petImage.getImage()).src); - })(); - } - } - else - { - (async () => - { - const furniImage = GetRoomEngine().getFurnitureFloorImage(event.classId, new Vector3d(90), 64, imageListener); - - if(furniImage) setImageUrl((await furniImage.getImage()).src); - })(); - } - - const productData = GetSessionDataManager().getProductData(event.productCode); - - setText((productData && productData.name) || furniData.name); - break; - } - } - - setObjectId(0); - setClassId(event.classId); - setItemType(event.itemType); - setIsOwnerOfFurniture(isOwnerOfFurni); - setPlacedItemId(event.placedItemId); - setPlacedItemType(event.placedItemType); - setPlacedInRoom(event.placedInRoom); - }); - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_PRESENT, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return null; - - onClose(); - - setObjectId(event.objectId); - setClassId(-1); - setText((roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA) || '')); - setIsOwnerOfFurniture(IsOwnerOfFurniture(roomObject)); - setSenderName((roomObject.model.getValue(RoomObjectVariable.FURNITURE_PURCHASER_NAME) || null)); - setSenderFigure((roomObject.model.getValue(RoomObjectVariable.FURNITURE_PURCHASER_FIGURE) || null)); - }); - - useFurniRemovedEvent((objectId !== -1), event => - { - if(event.id === objectId) onClose(); - - if(event.id === placedItemId) - { - if(placedInRoom) setPlacedInRoom(false); - } - }); - - return { objectId, classId, itemType, text, isOwnerOfFurniture, senderName, senderFigure, placedItemId, placedItemType, placedInRoom, imageUrl, openPresent, onClose }; -} - -export const useFurniturePresentWidget = useFurniturePresentWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureRoomLinkWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureRoomLinkWidget.ts deleted file mode 100644 index 31180a0..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureRoomLinkWidget.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { GetGuestRoomMessageComposer, GetGuestRoomResultEvent, GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { SendMessageComposer } from '../../../../api'; -import { useMessageEvent, useNitroEvent } from '../../../events'; - -const INTERNALLINK = 'internalLink'; - -const useFurnitureRoomLinkWidgetState = () => -{ - const [ roomIdToEnter, setRoomIdToEnter ] = useState(0); - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_ROOM_LINK, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - const data = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA); - - let roomId = data[INTERNALLINK]; - - if(!roomId || !roomId.length) roomId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_INTERNAL_LINK); - - if(!roomId || !roomId.length) return; - - roomId = parseInt(roomId, 10); - - if(isNaN(roomId)) return; - - setRoomIdToEnter(roomId); - - SendMessageComposer(new GetGuestRoomMessageComposer(roomId, false, false)); - }); - - useMessageEvent(GetGuestRoomResultEvent, event => - { - if(!roomIdToEnter) return; - - const parser = event.getParser(); - - if(parser.data.roomId !== roomIdToEnter) return; - - setRoomIdToEnter(0); - }); - - return {}; -} - -export const useFurnitureRoomLinkWidget = useFurnitureRoomLinkWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureSpamWallPostItWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureSpamWallPostItWidget.ts deleted file mode 100644 index 3226382..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureSpamWallPostItWidget.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { AddSpamWallPostItMessageComposer, GetRoomEngine, RequestSpamWallPostItMessageEvent, RoomObjectCategory } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { SendMessageComposer } from '../../../../api'; -import { useMessageEvent } from '../../../events'; -import { useInventoryFurni } from '../../../inventory'; - -const useFurnitureSpamWallPostItWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ itemType, setItemType ] = useState(''); - const [ location, setLocation ] = useState(''); - const [ color, setColor ] = useState('0'); - const [ text, setText ] = useState(''); - const [ canModify, setCanModify ] = useState(false); - const { getWallItemById = null } = useInventoryFurni(); - - const onClose = () => - { - SendMessageComposer(new AddSpamWallPostItMessageComposer(objectId, location, color, text)); - - setObjectId(-1); - setCategory(-1); - setItemType(''); - setLocation(''); - setColor('0'); - setText(''); - setCanModify(false); - } - - useMessageEvent(RequestSpamWallPostItMessageEvent, event => - { - const parser = event.getParser(); - - setObjectId(parser.itemId); - setCategory(RoomObjectCategory.WALL); - - const inventoryItem = getWallItemById(parser.itemId); - - let itemType = 'post_it'; - - if(inventoryItem) - { - const wallItemType = GetRoomEngine().getFurnitureWallName(inventoryItem.type); - - if(wallItemType.match('post_it_')) itemType = wallItemType; - } - - setItemType(itemType); - setLocation(parser.location); - setColor('FFFF33'); - setText(''); - setCanModify(true); - }); - - return { objectId, color, setColor, text, setText, canModify, onClose }; -} - -export const useFurnitureSpamWallPostItWidget = useFurnitureSpamWallPostItWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureStackHeightWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureStackHeightWidget.ts deleted file mode 100644 index 846f14e..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureStackHeightWidget.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { FurnitureStackHeightComposer, FurnitureStackHeightEvent, GetRoomEngine, RoomEngineTriggerWidgetEvent } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { CanManipulateFurniture, GetRoomSession, SendMessageComposer } from '../../../../api'; -import { useMessageEvent, useNitroEvent } from '../../../events'; -import { useFurniRemovedEvent } from '../../engine'; - -const MAX_HEIGHT: number = 40; - -const useFurnitureStackHeightWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ height, setHeight ] = useState(0); - const [ pendingHeight, setPendingHeight ] = useState(-1); - - const onClose = () => - { - setObjectId(-1); - setCategory(-1); - setHeight(0); - setPendingHeight(-1); - } - - const updateHeight = (height: number, server: boolean = false) => - { - if(!height) height = 0; - - height = Math.abs(height); - - if(!server) ((height > MAX_HEIGHT) && (height = MAX_HEIGHT)); - - setHeight(parseFloat(height.toFixed(2))); - - if(!server) setPendingHeight(height * 100); - } - - useMessageEvent(FurnitureStackHeightEvent, event => - { - const parser = event.getParser(); - - if(objectId !== parser.furniId) return; - - updateHeight(parser.height, true); - }); - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_STACK_HEIGHT, event => - { - if(!CanManipulateFurniture(GetRoomSession(), event.objectId, event.category)) return; - - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - setObjectId(event.objectId); - setCategory(event.category); - setHeight(roomObject.getLocation().z); - setPendingHeight(-1); - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - useEffect(() => - { - if((objectId === -1) || (pendingHeight === -1)) return; - - const timeout = setTimeout(() => SendMessageComposer(new FurnitureStackHeightComposer(objectId, ~~(pendingHeight))), 10); - - return () => clearTimeout(timeout); - }, [ objectId, pendingHeight ]); - - return { objectId, height, maxHeight: MAX_HEIGHT, onClose, updateHeight }; -} - -export const useFurnitureStackHeightWidget = useFurnitureStackHeightWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureStickieWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureStickieWidget.ts deleted file mode 100644 index 3d745a3..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureStickieWidget.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { GetRoomSession, IsOwnerOfFurniture } from '../../../../api'; -import { useNitroEvent } from '../../../events'; -import { useFurniRemovedEvent } from '../../engine'; - -const useFurnitureStickieWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ color, setColor ] = useState('0'); - const [ text, setText ] = useState(''); - const [ type, setType ] = useState(''); - const [ canModify, setCanModify ] = useState(false); - - const onClose = () => - { - setObjectId(-1); - setCategory(-1); - setColor('0'); - setText(''); - setType(''); - setCanModify(false); - } - - const updateColor = (newColor: string) => - { - if(newColor === color) return; - - setColor(newColor); - - GetRoomEngine().modifyRoomObjectData(objectId, category, newColor, text); - } - - const updateText = (newText: string) => - { - setText(newText); - - GetRoomEngine().modifyRoomObjectData(objectId, category, color, newText); - } - - const trash = () => GetRoomEngine().deleteRoomObject(objectId, category); - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_STICKIE, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - const data = roomObject.model.getValue(RoomObjectVariable.FURNITURE_ITEMDATA); - - if(data.length < 6) return; - - let color: string = null; - let text: string = null; - - if(data.indexOf(' ') > 0) - { - color = data.slice(0, data.indexOf(' ')); - text = data.slice((data.indexOf(' ') + 1), data.length); - } - else - { - color = data; - } - - setObjectId(event.objectId); - setCategory(event.category); - setColor(color || '0'); - setText(text || ''); - setType(roomObject.type || 'post_it'); - setCanModify(GetRoomSession().isRoomOwner || GetSessionDataManager().isModerator || IsOwnerOfFurniture(roomObject)); - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - return { objectId, color, text, type, canModify, updateColor, updateText, trash, onClose }; -} - -export const useFurnitureStickieWidget = useFurnitureStickieWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureTrophyWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureTrophyWidget.ts deleted file mode 100644 index 5808b5f..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureTrophyWidget.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { useNitroEvent } from '../../../events'; -import { useFurniRemovedEvent } from '../../engine'; - -const useFurnitureTrophyWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ color, setColor ] = useState('1'); - const [ senderName, setSenderName ] = useState(''); - const [ date, setDate ] = useState(''); - const [ message, setMessage ] = useState(''); - - const onClose = () => - { - setObjectId(-1); - setCategory(-1); - setColor('1'); - setSenderName(''); - setDate(''); - setMessage(''); - } - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_TROPHY, event => - { - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - let data = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA); - let extra = roomObject.model.getValue(RoomObjectVariable.FURNITURE_EXTRAS); - - if(!extra) extra = '0'; - - setObjectId(event.objectId); - setCategory(event.category); - setColor(roomObject.model.getValue(RoomObjectVariable.FURNITURE_COLOR) || '1'); - - const senderName = data.substring(0, data.indexOf('\t')); - - data = data.substring((senderName.length + 1), data.length); - - const trophyDate = data.substring(0, data.indexOf('\t')); - const trophyText = data.substr((trophyDate.length + 1), data.length); - - setSenderName(senderName); - setDate(trophyDate); - setMessage(trophyText); - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - return { objectId, color, senderName, date, message, onClose }; -} - -export const useFurnitureTrophyWidget = useFurnitureTrophyWidgetState; diff --git a/src/hooks/rooms/widgets/furniture/useFurnitureYoutubeWidget.ts b/src/hooks/rooms/widgets/furniture/useFurnitureYoutubeWidget.ts deleted file mode 100644 index 64c0f0d..0000000 --- a/src/hooks/rooms/widgets/furniture/useFurnitureYoutubeWidget.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { ControlYoutubeDisplayPlaybackMessageComposer, GetRoomEngine, GetSessionDataManager, GetYoutubeDisplayStatusMessageComposer, RoomEngineTriggerWidgetEvent, RoomId, SecurityLevel, SetYoutubeDisplayPlaylistMessageComposer, YoutubeControlVideoMessageEvent, YoutubeDisplayPlaylist, YoutubeDisplayPlaylistsEvent, YoutubeDisplayVideoMessageEvent } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { IsOwnerOfFurniture, SendMessageComposer, YoutubeVideoPlaybackStateEnum } from '../../../../api'; -import { useMessageEvent, useNitroEvent } from '../../../events'; -import { useFurniRemovedEvent } from '../../engine'; - -const CONTROL_COMMAND_PREVIOUS_VIDEO = 0; -const CONTROL_COMMAND_NEXT_VIDEO = 1; -const CONTROL_COMMAND_PAUSE_VIDEO = 2; -const CONTROL_COMMAND_CONTINUE_VIDEO = 3; - -const useFurnitureYoutubeWidgetState = () => -{ - const [ objectId, setObjectId ] = useState(-1); - const [ category, setCategory ] = useState(-1); - const [ videoId, setVideoId ] = useState(null); - const [ videoStart, setVideoStart ] = useState(null); - const [ videoEnd, setVideoEnd ] = useState(null); - const [ currentVideoState, setCurrentVideoState ] = useState(-1); - const [ selectedVideo, setSelectedVideo ] = useState(null); - const [ playlists, setPlaylists ] = useState(null); - const [ hasControl, setHasControl ] = useState(false); - - const onClose = () => - { - setObjectId(-1); - setCategory(-1); - setVideoId(null); - setVideoStart(null); - setVideoEnd(null); - setCurrentVideoState(-1); - setSelectedVideo(null); - setPlaylists(null); - setHasControl(false); - } - - const previous = () => SendMessageComposer(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, CONTROL_COMMAND_PREVIOUS_VIDEO)); - - const next = () => SendMessageComposer(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, CONTROL_COMMAND_NEXT_VIDEO)); - - const pause = () => (hasControl && videoId && videoId.length) && SendMessageComposer(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, CONTROL_COMMAND_PAUSE_VIDEO)); - - const play = () => (hasControl && videoId && videoId.length) && SendMessageComposer(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, CONTROL_COMMAND_CONTINUE_VIDEO)); - - const selectVideo = (video: string) => - { - if(selectedVideo === video) - { - setSelectedVideo(null); - SendMessageComposer(new SetYoutubeDisplayPlaylistMessageComposer(objectId, '')); - - return; - } - - setSelectedVideo(video); - SendMessageComposer(new SetYoutubeDisplayPlaylistMessageComposer(objectId, video)); - } - - useNitroEvent(RoomEngineTriggerWidgetEvent.REQUEST_YOUTUBE, event => - { - if(RoomId.isRoomPreviewerId(event.roomId)) return; - - const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category); - - if(!roomObject) return; - - setObjectId(event.objectId); - setCategory(event.category); - setHasControl(GetSessionDataManager().hasSecurity(SecurityLevel.EMPLOYEE) || IsOwnerOfFurniture(roomObject)); - - SendMessageComposer(new GetYoutubeDisplayStatusMessageComposer(event.objectId)); - }); - - useMessageEvent(YoutubeDisplayVideoMessageEvent, event => - { - const parser = event.getParser(); - - if((objectId === -1) || (objectId !== parser.furniId)) return; - - setVideoId(parser.videoId); - setVideoStart(parser.startAtSeconds); - setVideoEnd(parser.endAtSeconds); - setCurrentVideoState(parser.state); - }); - - useMessageEvent(YoutubeDisplayPlaylistsEvent, event => - { - const parser = event.getParser(); - - if((objectId === -1) || (objectId !== parser.furniId)) return; - - setPlaylists(parser.playlists); - setSelectedVideo(parser.selectedPlaylistId); - setVideoId(null); - setCurrentVideoState(-1); - setVideoEnd(null); - setVideoStart(null); - }); - - useMessageEvent(YoutubeControlVideoMessageEvent, event => - { - const parser = event.getParser(); - - if((objectId === -1) || (objectId !== parser.furniId)) return; - - switch(parser.commandId) - { - case 1: - setCurrentVideoState(YoutubeVideoPlaybackStateEnum.PLAYING); - break; - case 2: - setCurrentVideoState(YoutubeVideoPlaybackStateEnum.PAUSED); - break; - } - }); - - useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event => - { - if((event.id !== objectId) || (event.category !== category)) return; - - onClose(); - }); - - return { objectId, videoId, videoStart, videoEnd, currentVideoState, selectedVideo, playlists, onClose, previous, next, pause, play, selectVideo }; -} - -export const useFurnitureYoutubeWidget = useFurnitureYoutubeWidgetState; diff --git a/src/hooks/rooms/widgets/index.ts b/src/hooks/rooms/widgets/index.ts deleted file mode 100644 index 9984450..0000000 --- a/src/hooks/rooms/widgets/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -export * from './furniture'; -export * from './useAvatarInfoWidget'; -export * from './useChatInputWidget'; -export * from './useChatWidget'; -export * from './useDoorbellWidget'; -export * from './useFilterWordsWidget'; -export * from './useFriendRequestWidget'; -export * from './useFurniChooserWidget'; -export * from './usePetPackageWidget'; -export * from './usePollWidget'; -export * from './useUserChooserWidget'; -export * from './useWordQuizWidget'; diff --git a/src/hooks/rooms/widgets/useAvatarInfoWidget.ts b/src/hooks/rooms/widgets/useAvatarInfoWidget.ts deleted file mode 100644 index 9f5e213..0000000 --- a/src/hooks/rooms/widgets/useAvatarInfoWidget.ts +++ /dev/null @@ -1,355 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, RoomEngineObjectEvent, RoomEngineUseProductEvent, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionPetInfoUpdateEvent, RoomSessionPetStatusUpdateEvent, RoomSessionUserDataUpdateEvent } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { AvatarInfoFurni, AvatarInfoName, AvatarInfoPet, AvatarInfoRentableBot, AvatarInfoUser, AvatarInfoUtilities, CanManipulateFurniture, FurniCategory, IAvatarInfo, IsOwnerOfFurniture, RoomWidgetUpdateRoomObjectEvent, UseProductItem } from '../../../api'; -import { useNitroEvent, useUiEvent } from '../../events'; -import { useFriends } from '../../friends'; -import { useWired } from '../../wired'; -import { useObjectDeselectedEvent, useObjectRollOutEvent, useObjectRollOverEvent, useObjectSelectedEvent } from '../engine'; -import { useRoom } from '../useRoom'; - -const useAvatarInfoWidgetState = () => -{ - const [ avatarInfo, setAvatarInfo ] = useState(null); - const [ activeNameBubble, setActiveNameBubble ] = useState(null); - const [ nameBubbles, setNameBubbles ] = useState([]); - const [ productBubbles, setProductBubbles ] = useState([]); - const [ confirmingProduct, setConfirmingProduct ] = useState(null); - const [ pendingPetId, setPendingPetId ] = useState(-1); - const [ isDecorating, setIsDecorating ] = useState(false); - const { friends = [] } = useFriends(); - const { selectObjectForWired = null } = useWired(); - const { roomSession = null } = useRoom(); - - const removeNameBubble = (index: number) => - { - setNameBubbles(prevValue => - { - const newValue = [ ...prevValue ]; - - newValue.splice(index, 1); - - return newValue; - }); - } - - const removeProductBubble = (index: number) => - { - setProductBubbles(prevValue => - { - const newValue = [ ...prevValue ]; - const item = newValue.splice(index, 1)[0]; - - if(confirmingProduct === item) setConfirmingProduct(null); - - return newValue; - }); - } - - const updateConfirmingProduct = (product: UseProductItem) => - { - setConfirmingProduct(product); - setProductBubbles([]); - } - - const getObjectName = (objectId: number, category: number) => - { - const name = AvatarInfoUtilities.getObjectName(objectId, category); - - if(!name) return; - - setActiveNameBubble(name); - - if(category !== RoomObjectCategory.UNIT) setProductBubbles([]); - } - - const getObjectInfo = (objectId: number, category: number) => - { - let info: IAvatarInfo = null; - - switch(category) - { - case RoomObjectCategory.FLOOR: - case RoomObjectCategory.WALL: - info = AvatarInfoUtilities.getFurniInfo(objectId, category); - - if(info) selectObjectForWired(objectId, category); - break; - case RoomObjectCategory.UNIT: { - const userData = roomSession.userDataManager.getUserDataByIndex(objectId); - - if(!userData) break; - - switch(userData.type) - { - case RoomObjectType.PET: - roomSession.userDataManager.requestPetInfo(userData.webID); - setPendingPetId(userData.webID); - break; - case RoomObjectType.USER: - info = AvatarInfoUtilities.getUserInfo(category, userData); - break; - case RoomObjectType.BOT: - info = AvatarInfoUtilities.getBotInfo(category, userData); - break; - case RoomObjectType.RENTABLE_BOT: - info = AvatarInfoUtilities.getRentableBotInfo(category, userData); - break; - } - } - - } - - if(!info) return; - - setAvatarInfo(info); - } - - const processUsableRoomObject = (objectId: number) => - { - } - - const refreshPetInfo = () => - { - // roomSession.userDataManager.requestPetInfo(petData.id); - } - - useNitroEvent(RoomSessionUserDataUpdateEvent.USER_DATA_UPDATED, event => - { - if(!event.addedUsers.length) return; - - let addedNameBubbles: AvatarInfoName[] = []; - - event.addedUsers.forEach(user => - { - if(user.webID === GetSessionDataManager().userId || user.type !== RoomObjectType.USER) return; - - if(friends.find(friend => (friend.id === user.webID))) - { - addedNameBubbles.push(new AvatarInfoName(user.roomIndex, RoomObjectCategory.UNIT, user.webID, user.name, user.type, true)); - } - }); - - if(!addedNameBubbles.length) return; - - setNameBubbles(prevValue => - { - const newValue = [ ...prevValue ]; - - addedNameBubbles.forEach(bubble => - { - const oldIndex = newValue.findIndex(oldBubble => (oldBubble.id === bubble.id)); - - if(oldIndex > -1) newValue.splice(oldIndex, 1); - - newValue.push(bubble); - }); - - return newValue; - }); - }); - - useNitroEvent(RoomSessionPetInfoUpdateEvent.PET_INFO, event => - { - const petData = event.petInfo; - - if(!petData) return; - - if(petData.id !== pendingPetId) return; - - const petInfo = AvatarInfoUtilities.getPetInfo(petData); - - if(!petInfo) return; - - setAvatarInfo(petInfo); - setPendingPetId(-1); - }); - - useNitroEvent(RoomSessionPetStatusUpdateEvent.PET_STATUS_UPDATE, event => - { - /* var _local_2:Boolean; - var _local_3:Boolean; - var _local_4:Boolean; - var _local_5:Boolean; - var _local_6:RoomUserData; - var _local_7:_Str_4828; - if (((!(this._container == null)) && (!(this._container.events == null)))) - { - _local_2 = k.canBreed; - _local_3 = k.canHarvest; - _local_4 = k.canRevive; - _local_5 = k.hasBreedingPermission; - _local_6 = this._Str_19958(k.petId); - if (_local_6 == null) - { - Logger.log((("Could not find pet with the id: " + k.petId) + " given by petStatusUpdate")); - return; - } - _local_7 = new _Str_4828(_local_6.roomObjectId, _local_2, _local_3, _local_4, _local_5); - this._container.events.dispatchEvent(_local_7); */ - }); - - useNitroEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY, event => - { - // this._Str_23199((k as RoomEngineUseProductEvent).inventoryStripId, (k as RoomEngineUseProductEvent).furnitureTypeId); - }); - - useNitroEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM, event => - { - const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, event.objectId, RoomObjectCategory.FLOOR); - - if(!roomObject || !IsOwnerOfFurniture(roomObject)) return; - - const ownerId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID); - const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); - const furniData = GetSessionDataManager().getFloorItemData(typeId); - const parts = furniData.customParams.split(' '); - const part = (parts.length ? parseInt(parts[0]) : -1); - - if(part === -1) return; - - const useProductBubbles: UseProductItem[] = []; - const roomObjects = GetRoomEngine().getRoomObjects(roomSession.roomId, RoomObjectCategory.UNIT); - - for(const roomObject of roomObjects) - { - const userData = roomSession.userDataManager.getUserDataByIndex(roomObject.id); - - let replace = false; - - if(!userData || (userData.type !== RoomObjectType.PET)) - { - - } - else - { - if(userData.ownerId === ownerId) - { - if(userData.hasSaddle && (furniData.specialType === FurniCategory.PET_SADDLE)) replace = true; - - const figureParts = userData.figure.split(' '); - const figurePart = (figureParts.length ? parseInt(figureParts[0]) : -1); - - if(figurePart === part) - { - if(furniData.specialType === FurniCategory.MONSTERPLANT_REVIVAL) - { - if(!userData.canRevive) continue; - } - - if(furniData.specialType === FurniCategory.MONSTERPLANT_REBREED) - { - if((userData.petLevel < 7) || userData.canRevive || userData.canBreed) continue; - } - - if(furniData.specialType === FurniCategory.MONSTERPLANT_FERTILIZE) - { - if((userData.petLevel >= 7) || userData.canRevive) continue; - } - - useProductBubbles.push(new UseProductItem(userData.roomIndex, RoomObjectCategory.UNIT, userData.name, event.objectId, roomObject.id, -1, replace)); - } - } - } - } - - setConfirmingProduct(null); - - if(useProductBubbles.length) setProductBubbles(useProductBubbles); - }); - - useNitroEvent(RoomEngineObjectEvent.REQUEST_MANIPULATION, event => - { - if(!CanManipulateFurniture(roomSession, event.objectId, event.category)) return; - - setIsDecorating(true); - }); - - useObjectSelectedEvent(event => - { - getObjectInfo(event.id, event.category); - }); - - useObjectDeselectedEvent(event => - { - setAvatarInfo(null); - setProductBubbles([]); - }); - - useObjectRollOverEvent(event => - { - if(avatarInfo || (event.category !== RoomObjectCategory.UNIT)) return; - - getObjectName(event.id, event.category); - }); - - useObjectRollOutEvent(event => - { - if(!activeNameBubble || (event.category !== RoomObjectCategory.UNIT) || (activeNameBubble.roomIndex !== event.id)) return; - - setActiveNameBubble(null); - }); - - useUiEvent([ - RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, - RoomWidgetUpdateRoomObjectEvent.USER_REMOVED - ], event => - { - if(activeNameBubble && (activeNameBubble.category === event.category) && (activeNameBubble.roomIndex === event.id)) setActiveNameBubble(null); - - if(event.category === RoomObjectCategory.UNIT) - { - let index = nameBubbles.findIndex(bubble => (bubble.roomIndex === event.id)); - - if(index > -1) setNameBubbles(prevValue => prevValue.filter(bubble => (bubble.roomIndex === event.id))); - - index = productBubbles.findIndex(bubble => (bubble.id === event.id)); - - if(index > -1) setProductBubbles(prevValue => prevValue.filter(bubble => (bubble.id !== event.id))); - } - - else if(event.category === RoomObjectCategory.FLOOR) - { - const index = productBubbles.findIndex(bubble => (bubble.id === event.id)); - - if(index > -1) setProductBubbles(prevValue => prevValue.filter(bubble => (bubble.requestRoomObjectId !== event.id))); - } - - if(avatarInfo) - { - if(avatarInfo instanceof AvatarInfoFurni) - { - if(avatarInfo.id === event.id) setAvatarInfo(null); - } - - else if((avatarInfo instanceof AvatarInfoUser) || (avatarInfo instanceof AvatarInfoRentableBot) || (avatarInfo instanceof AvatarInfoPet)) - { - if(avatarInfo.roomIndex === event.id) setAvatarInfo(null); - } - } - }); - - useEffect(() => - { - if(!avatarInfo) return; - - setActiveNameBubble(null); - setNameBubbles([]); - setProductBubbles([]); - }, [ avatarInfo ]); - - useEffect(() => - { - if(!activeNameBubble) return; - - setNameBubbles([]); - }, [ activeNameBubble ]); - - useEffect(() => - { - roomSession.isDecorating = isDecorating; - }, [ roomSession, isDecorating ]); - - return { avatarInfo, setAvatarInfo, activeNameBubble, setActiveNameBubble, nameBubbles, productBubbles, confirmingProduct, isDecorating, setIsDecorating, removeNameBubble, removeProductBubble, updateConfirmingProduct, getObjectName }; -} - -export const useAvatarInfoWidget = useAvatarInfoWidgetState; diff --git a/src/hooks/rooms/widgets/useChatInputWidget.ts b/src/hooks/rooms/widgets/useChatInputWidget.ts deleted file mode 100644 index db47e02..0000000 --- a/src/hooks/rooms/widgets/useChatInputWidget.ts +++ /dev/null @@ -1,282 +0,0 @@ -import { AvatarExpressionEnum, CreateLinkEvent, GetEventDispatcher, GetRoomEngine, GetSessionDataManager, GetTicker, HabboClubLevelEnum, RoomControllerLevel, RoomEngineObjectEvent, RoomObjectCategory, RoomRotatingEffect, RoomSessionChatEvent, RoomSettingsComposer, RoomShakingEffect, RoomZoomEvent, TextureUtils } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { ChatMessageTypeEnum, GetClubMemberLevel, GetConfigurationValue, LocalizeText, SendMessageComposer } from '../../../api'; -import { useNitroEvent } from '../../events'; -import { useNotification } from '../../notification'; -import { useObjectSelectedEvent } from '../engine'; -import { useRoom } from '../useRoom'; - -const useChatInputWidgetState = () => -{ - const [ selectedUsername, setSelectedUsername ] = useState(''); - const [ isTyping, setIsTyping ] = useState(false); - const [ typingStartedSent, setTypingStartedSent ] = useState(false); - const [ isIdle, setIsIdle ] = useState(false); - const [ floodBlocked, setFloodBlocked ] = useState(false); - const [ floodBlockedSeconds, setFloodBlockedSeconds ] = useState(0); - const { showNitroAlert = null, showConfirm = null } = useNotification(); - const { roomSession = null } = useRoom(); - - const sendChat = (text: string, chatType: number, recipientName: string = '', styleId: number = 0) => - { - if(text === '') return null; - - const parts = text.split(' '); - - if(parts.length > 0) - { - const firstPart = parts[0]; - let secondPart = ''; - - if(parts.length > 1) secondPart = parts[1]; - - if((firstPart.charAt(0) === ':') && (secondPart === 'x')) - { - const selectedAvatarId = GetRoomEngine().selectedAvatarId; - - if(selectedAvatarId > -1) - { - const userData = roomSession.userDataManager.getUserDataByIndex(selectedAvatarId); - - if(userData) - { - secondPart = userData.name; - text = text.replace(' x', (' ' + userData.name)); - } - } - } - - switch(firstPart.toLowerCase()) - { - case ':shake': - RoomShakingEffect.init(2500, 5000); - RoomShakingEffect.turnVisualizationOn(); - - return null; - - case ':rotate': - RoomRotatingEffect.init(2500, 5000); - RoomRotatingEffect.turnVisualizationOn(); - - return null; - case ':d': - case ';d': - if(GetClubMemberLevel() === HabboClubLevelEnum.VIP) - { - roomSession.sendExpressionMessage(AvatarExpressionEnum.LAUGH.ordinal); - } - - break; - case 'o/': - case '_o/': - roomSession.sendExpressionMessage(AvatarExpressionEnum.WAVE.ordinal); - - return null; - case ':kiss': - if(GetClubMemberLevel() === HabboClubLevelEnum.VIP) - { - roomSession.sendExpressionMessage(AvatarExpressionEnum.BLOW.ordinal); - - return null; - } - - break; - case ':jump': - if(GetClubMemberLevel() === HabboClubLevelEnum.VIP) - { - roomSession.sendExpressionMessage(AvatarExpressionEnum.JUMP.ordinal); - - return null; - } - - break; - case ':idle': - roomSession.sendExpressionMessage(AvatarExpressionEnum.IDLE.ordinal); - - return null; - case '_b': - roomSession.sendExpressionMessage(AvatarExpressionEnum.RESPECT.ordinal); - - return null; - case ':sign': - roomSession.sendSignMessage(parseInt(secondPart)); - - return null; - case ':iddqd': - case ':flip': - GetEventDispatcher().dispatchEvent(new RoomZoomEvent(roomSession.roomId, -1, true)); - - return null; - case ':zoom': - GetEventDispatcher().dispatchEvent(new RoomZoomEvent(roomSession.roomId, parseFloat(secondPart), false)); - - return null; - case ':screenshot': - const texture = GetRoomEngine().createTextureFromRoom(roomSession.roomId, 1); - - (async () => - { - const image = new Image(); - - image.src = await TextureUtils.generateImageUrl(texture); - - const newWindow = window.open(''); - newWindow.document.write(image.outerHTML); - })(); - return null; - case ':pickall': - if(roomSession.isRoomOwner || GetSessionDataManager().isModerator) - { - showConfirm(LocalizeText('room.confirm.pick_all'), () => - { - GetSessionDataManager().sendSpecialCommandMessage(':pickall'); - }, - null, null, null, LocalizeText('generic.alert.title')); - } - - return null; - case ':ejectall': - if (roomSession.isRoomOwner || GetSessionDataManager().isModerator || roomSession.controllerLevel >= RoomControllerLevel.GUEST) - { - showConfirm(LocalizeText('room.confirm.eject_all'), () => - { - GetSessionDataManager().sendSpecialCommandMessage(':ejectall'); - }, - null, null, null, LocalizeText('generic.alert.title')); - } - return null; - case ':furni': - CreateLinkEvent('furni-chooser/'); - return null; - case ':chooser': - CreateLinkEvent('user-chooser/'); - return null; - case ':floor': - case ':bcfloor': - if(roomSession.controllerLevel >= RoomControllerLevel.ROOM_OWNER) CreateLinkEvent('floor-editor/show'); - - return null; - case ':togglefps': { - if(GetTicker().maxFPS > 0) GetTicker().maxFPS = 0; - else GetTicker().maxFPS = GetConfigurationValue('system.animation.fps'); - - return null; - } - case ':client': - case ':nitro': - case ':billsonnn': - showNitroAlert(); - return null; - case ':settings': - if(roomSession.isRoomOwner || GetSessionDataManager().isModerator) - { - SendMessageComposer(new RoomSettingsComposer(roomSession.roomId)); - } - - return null; - } - } - - switch(chatType) - { - case ChatMessageTypeEnum.CHAT_DEFAULT: - roomSession.sendChatMessage(text, styleId); - break; - case ChatMessageTypeEnum.CHAT_SHOUT: - roomSession.sendShoutMessage(text, styleId); - break; - case ChatMessageTypeEnum.CHAT_WHISPER: - roomSession.sendWhisperMessage(recipientName, text, styleId); - break; - } - } - - useNitroEvent(RoomSessionChatEvent.FLOOD_EVENT, event => - { - setFloodBlocked(true); - setFloodBlockedSeconds(parseFloat(event.message)); - }); - - useObjectSelectedEvent(event => - { - if(event.category !== RoomObjectCategory.UNIT) return; - - const userData = roomSession.userDataManager.getUserDataByIndex(event.id); - - if(!userData) return; - - setSelectedUsername(userData.name); - }); - - useNitroEvent(RoomEngineObjectEvent.DESELECTED, event => setSelectedUsername('')); - - useEffect(() => - { - if(!floodBlocked) return; - - let seconds = 0; - - const interval = setInterval(() => - { - setFloodBlockedSeconds(prevValue => - { - seconds = ((prevValue || 0) - 1); - - return seconds; - }); - - if(seconds < 0) - { - clearInterval(interval); - - setFloodBlocked(false); - } - }, 1000); - - return () => clearInterval(interval); - }, [ floodBlocked ]); - - useEffect(() => - { - if(!isIdle) return; - - let timeout: ReturnType = null; - - if(isIdle) - { - timeout = setTimeout(() => - { - setIsIdle(false); - setIsTyping(false) - }, 10000); - } - - return () => clearTimeout(timeout); - }, [ isIdle ]); - - useEffect(() => - { - if(isTyping) - { - if(!typingStartedSent) - { - setTypingStartedSent(true); - - roomSession.sendChatTypingMessage(isTyping); - } - } - else - { - if(typingStartedSent) - { - setTypingStartedSent(false); - - roomSession.sendChatTypingMessage(isTyping); - } - } - }, [ roomSession, isTyping, typingStartedSent ]); - - return { selectedUsername, floodBlocked, floodBlockedSeconds, setIsTyping, setIsIdle, sendChat }; -} - -export const useChatInputWidget = useChatInputWidgetState; diff --git a/src/hooks/rooms/widgets/useChatWidget.ts b/src/hooks/rooms/widgets/useChatWidget.ts deleted file mode 100644 index a723a51..0000000 --- a/src/hooks/rooms/widgets/useChatWidget.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { GetGuestRoomResultEvent, GetRoomEngine, PetFigureData, RoomChatSettings, RoomChatSettingsEvent, RoomDragEvent, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionChatEvent, RoomUserData, SystemChatStyleEnum } from '@nitrots/nitro-renderer'; -import { useEffect, useMemo, useRef, useState } from 'react'; -import { ChatBubbleMessage, ChatBubbleUtilities, ChatEntryType, ChatHistoryCurrentDate, GetConfigurationValue, GetRoomObjectScreenLocation, IRoomChatSettings, LocalizeText, PlaySound, RoomChatFormatter } from '../../../api'; -import { useMessageEvent, useNitroEvent } from '../../events'; -import { useRoom } from '../useRoom'; -import { useChatHistory } from './../../chat-history'; - -const useChatWidgetState = () => -{ - const [ chatMessages, setChatMessages ] = useState([]); - const [ chatSettings, setChatSettings ] = useState({ - mode: RoomChatSettings.CHAT_MODE_FREE_FLOW, - weight: RoomChatSettings.CHAT_BUBBLE_WIDTH_NORMAL, - speed: RoomChatSettings.CHAT_SCROLL_SPEED_NORMAL, - distance: 50, - protection: RoomChatSettings.FLOOD_FILTER_NORMAL - }); - const { roomSession = null } = useRoom(); - const { addChatEntry } = useChatHistory(); - const isDisposed = useRef(false); - - const getScrollSpeed = useMemo(() => - { - if(!chatSettings) return 6000; - - switch(chatSettings.speed) - { - case RoomChatSettings.CHAT_SCROLL_SPEED_FAST: - return 3000; - case RoomChatSettings.CHAT_SCROLL_SPEED_NORMAL: - return 6000; - case RoomChatSettings.CHAT_SCROLL_SPEED_SLOW: - return 12000; - } - }, [ chatSettings ]); - - useNitroEvent(RoomSessionChatEvent.CHAT_EVENT, async event => - { - const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, event.objectId, RoomObjectCategory.UNIT); - const bubbleLocation = roomObject ? GetRoomObjectScreenLocation(roomSession.roomId, roomObject?.id, RoomObjectCategory.UNIT) : { x: 0, y: 0 }; - const userData = roomObject ? roomSession.userDataManager.getUserDataByIndex(event.objectId) : new RoomUserData(-1); - - let username = ''; - let avatarColor = 0; - let imageUrl: string = null; - let chatType = event.chatType; - let styleId = event.style; - let userType = 0; - let petType = -1; - let text = event.message; - - if(userData) - { - userType = userData.type; - - const figure = userData.figure; - - switch(userType) - { - case RoomObjectType.PET: - imageUrl = await ChatBubbleUtilities.getPetImage(figure, 2, true, 64, roomObject.model.getValue(RoomObjectVariable.FIGURE_POSTURE)); - petType = new PetFigureData(figure).typeId; - break; - case RoomObjectType.USER: - imageUrl = await ChatBubbleUtilities.getUserImage(figure); - break; - case RoomObjectType.RENTABLE_BOT: - case RoomObjectType.BOT: - styleId = SystemChatStyleEnum.BOT; - break; - } - - avatarColor = ChatBubbleUtilities.AVATAR_COLOR_CACHE.get(figure); - username = userData.name; - } - - switch(chatType) - { - case RoomSessionChatEvent.CHAT_TYPE_RESPECT: - text = LocalizeText('widgets.chatbubble.respect', [ 'username' ], [ username ]); - - if(GetConfigurationValue('respect.options')['enabled']) PlaySound(GetConfigurationValue('respect.options')['sound']); - - break; - case RoomSessionChatEvent.CHAT_TYPE_PETREVIVE: - case RoomSessionChatEvent.CHAT_TYPE_PET_REBREED_FERTILIZE: - case RoomSessionChatEvent.CHAT_TYPE_PET_SPEED_FERTILIZE: { - let textKey = 'widget.chatbubble.petrevived'; - - if(chatType === RoomSessionChatEvent.CHAT_TYPE_PET_REBREED_FERTILIZE) - { - textKey = 'widget.chatbubble.petrefertilized;'; - } - - else if(chatType === RoomSessionChatEvent.CHAT_TYPE_PET_SPEED_FERTILIZE) - { - textKey = 'widget.chatbubble.petspeedfertilized'; - } - - let targetUserName: string = null; - - const newRoomObject = GetRoomEngine().getRoomObject(roomSession.roomId, event.extraParam, RoomObjectCategory.UNIT); - - if(newRoomObject) - { - const newUserData = roomSession.userDataManager.getUserDataByIndex(roomObject.id); - - if(newUserData) targetUserName = newUserData.name; - } - - text = LocalizeText(textKey, [ 'petName', 'userName' ], [ username, targetUserName ]); - break; - } - case RoomSessionChatEvent.CHAT_TYPE_PETRESPECT: - text = LocalizeText('widget.chatbubble.petrespect', [ 'petname' ], [ username ]); - break; - case RoomSessionChatEvent.CHAT_TYPE_PETTREAT: - text = LocalizeText('widget.chatbubble.pettreat', [ 'petname' ], [ username ]); - break; - case RoomSessionChatEvent.CHAT_TYPE_HAND_ITEM_RECEIVED: - text = LocalizeText('widget.chatbubble.handitem', [ 'username', 'handitem' ], [ username, LocalizeText(('handitem' + event.extraParam)) ]); - break; - case RoomSessionChatEvent.CHAT_TYPE_MUTE_REMAINING: { - const hours = ((event.extraParam > 0) ? Math.floor((event.extraParam / 3600)) : 0).toString(); - const minutes = ((event.extraParam > 0) ? Math.floor((event.extraParam % 3600) / 60) : 0).toString(); - const seconds = (event.extraParam % 60).toString(); - - text = LocalizeText('widget.chatbubble.mutetime', [ 'hours', 'minutes', 'seconds' ], [ hours, minutes, seconds ]); - break; - } - } - - const formattedText = RoomChatFormatter(text); - const color = (avatarColor && (('#' + (avatarColor.toString(16).padStart(6, '0'))) || null)); - - const chatMessage = new ChatBubbleMessage( - userData.roomIndex, - RoomObjectCategory.UNIT, - roomSession.roomId, - text, - formattedText, - username, - { x: bubbleLocation.x, y: bubbleLocation.y }, - chatType, - styleId, - imageUrl, - color); - - setChatMessages(prevValue => [ ...prevValue, chatMessage ]); - addChatEntry({ id: -1, webId: userData.webID, entityId: userData.roomIndex, name: username, imageUrl, style: styleId, chatType: chatType, entityType: userData.type, message: formattedText, timestamp: ChatHistoryCurrentDate(), type: ChatEntryType.TYPE_CHAT, roomId: roomSession.roomId, color }); - }); - - useNitroEvent(RoomDragEvent.ROOM_DRAG, event => - { - if(!chatMessages.length || (event.roomId !== roomSession.roomId)) return; - - const offsetX = event.offsetX; - - chatMessages.forEach(chat => (chat.elementRef && (chat.left += offsetX))); - }); - - useMessageEvent(GetGuestRoomResultEvent, event => - { - const parser = event.getParser(); - - if(!parser.roomEnter) return; - - setChatSettings(parser.chat); - }); - - useMessageEvent(RoomChatSettingsEvent, event => - { - const parser = event.getParser(); - - setChatSettings(parser.chat); - }); - - useEffect(() => - { - isDisposed.current = false; - - return () => - { - isDisposed.current = true; - } - }, []); - - return { chatMessages, setChatMessages, chatSettings, getScrollSpeed }; -} - -export const useChatWidget = useChatWidgetState; diff --git a/src/hooks/rooms/widgets/useDoorbellWidget.ts b/src/hooks/rooms/widgets/useDoorbellWidget.ts deleted file mode 100644 index 7cf5051..0000000 --- a/src/hooks/rooms/widgets/useDoorbellWidget.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { RoomSessionDoorbellEvent } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { GetRoomSession } from '../../../api'; -import { useNitroEvent } from '../../events'; - -const useDoorbellWidgetState = () => -{ - const [ users, setUsers ] = useState([]); - - const addUser = (userName: string) => - { - if(users.indexOf(userName) >= 0) return; - - setUsers([ ...users, userName ]); - } - - const removeUser = (userName: string) => - { - const index = users.indexOf(userName); - - if(index === -1) return; - - const newUsers = [ ...users ]; - - newUsers.splice(index, 1); - - setUsers(newUsers); - } - - const answer = (userName: string, flag: boolean) => - { - GetRoomSession().sendDoorbellApprovalMessage(userName, flag); - - removeUser(userName); - } - - useNitroEvent(RoomSessionDoorbellEvent.DOORBELL, event => addUser(event.userName)); - useNitroEvent(RoomSessionDoorbellEvent.RSDE_REJECTED, event => removeUser(event.userName)); - useNitroEvent(RoomSessionDoorbellEvent.RSDE_ACCEPTED, event => removeUser(event.userName)); - - return { users, addUser, removeUser, answer }; -} - -export const useDoorbellWidget = useDoorbellWidgetState; diff --git a/src/hooks/rooms/widgets/useFilterWordsWidget.ts b/src/hooks/rooms/widgets/useFilterWordsWidget.ts deleted file mode 100644 index 3811682..0000000 --- a/src/hooks/rooms/widgets/useFilterWordsWidget.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { RoomFilterSettingsMessageEvent } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { useMessageEvent } from '../../events'; - -const useFilterWordsWidgetState = () => -{ - const [ wordsFilter, setWordsFilter ] = useState(null); - const [ isVisible, setIsVisible ] = useState(false); - - const onClose = () => setIsVisible(false); - - useMessageEvent(RoomFilterSettingsMessageEvent, event => - { - const parser = event.getParser(); - - setIsVisible(true); - setWordsFilter(parser.words); - }); - - return { wordsFilter, isVisible, setWordsFilter, onClose }; -} - -export const useFilterWordsWidget = useFilterWordsWidgetState; diff --git a/src/hooks/rooms/widgets/useFriendRequestWidget.ts b/src/hooks/rooms/widgets/useFriendRequestWidget.ts deleted file mode 100644 index 82bf6a2..0000000 --- a/src/hooks/rooms/widgets/useFriendRequestWidget.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { RoomObjectCategory, RoomObjectUserType } from '@nitrots/nitro-renderer'; -import { useEffect, useMemo, useState } from 'react'; -import { GetRoomSession, MessengerRequest } from '../../../api'; -import { useFriends } from '../../friends'; -import { useUserAddedEvent, useUserRemovedEvent } from '../engine'; - -const useFriendRequestWidgetState = () => -{ - const [ activeRequests, setActiveRequests ] = useState<{ roomIndex: number, request: MessengerRequest }[]>([]); - const { requests = [], dismissedRequestIds = [], setDismissedRequestIds = null } = useFriends(); - - const displayedRequests = useMemo(() => activeRequests.filter(request => (dismissedRequestIds.indexOf(request.request.requesterUserId) === -1)), [ activeRequests, dismissedRequestIds ]); - - const hideFriendRequest = (userId: number) => - { - setDismissedRequestIds(prevValue => - { - if(prevValue.indexOf(userId) >= 0) return prevValue; - - const newValue = [ ...prevValue ]; - - newValue.push(userId); - - return newValue; - }); - } - - useUserAddedEvent(true, event => - { - if(event.category !== RoomObjectCategory.UNIT) return; - - const userData = GetRoomSession().userDataManager.getUserDataByIndex(event.id); - - if(!userData || (userData.type !== RoomObjectUserType.getTypeNumber(RoomObjectUserType.USER))) return; - - const request = requests.find(request => (request.requesterUserId === userData.webID)); - - if(!request || activeRequests.find(request => (request.request.requesterUserId === userData.webID))) return; - - const newValue = [ ...activeRequests ]; - - newValue.push({ roomIndex: userData.roomIndex, request }); - - setActiveRequests(newValue); - }); - - useUserRemovedEvent(true, event => - { - if(event.category !== RoomObjectCategory.UNIT) return; - - const index = activeRequests.findIndex(request => (request.roomIndex === event.id)); - - if(index === -1) return; - - const newValue = [ ...activeRequests ]; - - newValue.splice(index, 1); - - setActiveRequests(newValue); - }); - - useEffect(() => - { - const newDisplayedRequests: { roomIndex: number, request: MessengerRequest }[] = []; - - for(const request of requests) - { - const userData = GetRoomSession().userDataManager.getUserData(request.requesterUserId); - - if(!userData) continue; - - newDisplayedRequests.push({ roomIndex: userData.roomIndex, request }); - } - - setActiveRequests(newDisplayedRequests); - }, [ requests ]); - - return { displayedRequests, hideFriendRequest }; -} - -export const useFriendRequestWidget = useFriendRequestWidgetState; diff --git a/src/hooks/rooms/widgets/useFurniChooserWidget.ts b/src/hooks/rooms/widgets/useFurniChooserWidget.ts deleted file mode 100644 index 428db2c..0000000 --- a/src/hooks/rooms/widgets/useFurniChooserWidget.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GetRoomEngine, GetSessionDataManager, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { GetRoomSession, LocalizeText, RoomObjectItem } from '../../../api'; -import { useFurniAddedEvent, useFurniRemovedEvent } from '../engine'; -import { useRoom } from '../useRoom'; - -const useFurniChooserWidgetState = () => -{ - const [ items, setItems ] = useState(null); - const { roomSession = null } = useRoom(); - - const onClose = () => setItems(null); - - const selectItem = (item: RoomObjectItem) => item && GetRoomEngine().selectRoomObject(GetRoomSession().roomId, item.id, item.category); - - const populateChooser = () => - { - const sessionDataManager = GetSessionDataManager(); - const wallObjects = GetRoomEngine().getRoomObjects(roomSession.roomId, RoomObjectCategory.WALL); - const floorObjects = GetRoomEngine().getRoomObjects(roomSession.roomId, RoomObjectCategory.FLOOR); - - const wallItems = wallObjects.map(roomObject => - { - if(roomObject.id < 0) return null; - - let name = roomObject.type; - - if(name.startsWith('poster')) - { - name = LocalizeText(`poster_${ name.replace('poster', '') }_name`); - } - else - { - const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); - const furniData = sessionDataManager.getWallItemData(typeId); - - if(furniData && furniData.name.length) name = furniData.name; - } - - return new RoomObjectItem(roomObject.id, RoomObjectCategory.WALL, name); - }); - - const floorItems = floorObjects.map(roomObject => - { - if(roomObject.id < 0) return null; - - let name = roomObject.type; - - const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); - const furniData = sessionDataManager.getFloorItemData(typeId); - - if(furniData && furniData.name.length) name = furniData.name; - - return new RoomObjectItem(roomObject.id, RoomObjectCategory.FLOOR, name); - }); - - setItems([ ...wallItems, ...floorItems ].sort((a, b) => ((a.name < b.name) ? -1 : 1))); - } - - useFurniAddedEvent(!!items, event => - { - if(event.id < 0) return; - - const roomObject = GetRoomEngine().getRoomObject(GetRoomSession().roomId, event.id, event.category); - - if(!roomObject) return; - - let item: RoomObjectItem = null; - - switch(event.category) - { - case RoomObjectCategory.WALL: { - let name = roomObject.type; - - if(name.startsWith('poster')) - { - name = LocalizeText(`poster_${ name.replace('poster', '') }_name`); - } - else - { - const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); - const furniData = GetSessionDataManager().getWallItemData(typeId); - - if(furniData && furniData.name.length) name = furniData.name; - } - - item = new RoomObjectItem(roomObject.id, RoomObjectCategory.WALL, name); - - break; - } - case RoomObjectCategory.FLOOR: { - let name = roomObject.type; - - const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); - const furniData = GetSessionDataManager().getFloorItemData(typeId); - - if(furniData && furniData.name.length) name = furniData.name; - - item = new RoomObjectItem(roomObject.id, RoomObjectCategory.FLOOR, name); - } - } - - setItems(prevValue => [ ...prevValue, item ].sort((a, b) => ((a.name < b.name) ? -1 : 1))); - }); - - useFurniRemovedEvent(!!items, event => - { - if(event.id < 0) return; - - setItems(prevValue => - { - const newValue = [ ...prevValue ]; - - for(let i = 0; i < newValue.length; i++) - { - const existingValue = newValue[i]; - - if((existingValue.id !== event.id) || (existingValue.category !== event.category)) continue; - - newValue.splice(i, 1); - - break; - } - - return newValue; - }); - }); - - return { items, onClose, selectItem, populateChooser }; -} - -export const useFurniChooserWidget = useFurniChooserWidgetState; diff --git a/src/hooks/rooms/widgets/usePetPackageWidget.ts b/src/hooks/rooms/widgets/usePetPackageWidget.ts deleted file mode 100644 index 1de3f91..0000000 --- a/src/hooks/rooms/widgets/usePetPackageWidget.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { GetRoomEngine, OpenPetPackageMessageComposer, RoomObjectCategory, RoomSessionPetPackageEvent } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { LocalizeText, SendMessageComposer } from '../../../api'; -import { useNitroEvent } from '../../events'; - -const usePetPackageWidgetState = () => -{ - const [ isVisible, setIsVisible ] = useState(false); - const [ objectId, setObjectId ] = useState(-1); - const [ objectType, setObjectType ] = useState(''); - const [ petName, setPetName ] = useState(''); - const [ errorResult, setErrorResult ] = useState(''); - - const onClose = () => - { - setErrorResult(''); - setPetName(''); - setObjectType(''); - setObjectId(-1); - setIsVisible(false); - } - - const onConfirm = () => - { - SendMessageComposer(new OpenPetPackageMessageComposer(objectId, petName)); - } - - const onChangePetName = (petName: string) => - { - setPetName(petName); - if (errorResult.length > 0) setErrorResult(''); - } - - const getErrorResultForCode = (errorCode: number) => - { - if (!errorCode || errorCode === 0) return; - - switch(errorCode) - { - case 1: - return LocalizeText('catalog.alert.petname.long'); - case 2: - return LocalizeText('catalog.alert.petname.short'); - case 3: - return LocalizeText('catalog.alert.petname.chars'); - case 4: - default: - return LocalizeText('catalog.alert.petname.bobba'); - } - } - - useNitroEvent(RoomSessionPetPackageEvent.RSOPPE_OPEN_PET_PACKAGE_REQUESTED, event => - { - if (!event) return; - - const roomObject = GetRoomEngine().getRoomObject(event.session.roomId, event.objectId, RoomObjectCategory.FLOOR); - - setObjectId(event.objectId); - setObjectType(roomObject.type); - setIsVisible(true); - }); - - useNitroEvent(RoomSessionPetPackageEvent.RSOPPE_OPEN_PET_PACKAGE_RESULT, event => - { - if (!event) return; - - if (event.nameValidationStatus === 0) onClose(); - - if (event.nameValidationStatus !== 0) setErrorResult(getErrorResultForCode(event.nameValidationStatus)); - }); - - return { isVisible, errorResult, petName, objectType, onChangePetName, onConfirm, onClose }; -} - -export const usePetPackageWidget = usePetPackageWidgetState; diff --git a/src/hooks/rooms/widgets/usePollWidget.ts b/src/hooks/rooms/widgets/usePollWidget.ts deleted file mode 100644 index 6132378..0000000 --- a/src/hooks/rooms/widgets/usePollWidget.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { RoomSessionPollEvent } from '@nitrots/nitro-renderer'; -import { DispatchUiEvent, RoomWidgetPollUpdateEvent } from '../../../api'; -import { useNitroEvent } from '../../events'; -import { useRoom } from '../useRoom'; - -const usePollWidgetState = () => -{ - const { roomSession = null } = useRoom(); - - const startPoll = (pollId: number) => roomSession.sendPollStartMessage(pollId); - - const rejectPoll = (pollId: number) => roomSession.sendPollRejectMessage(pollId); - - const answerPoll = (pollId: number, questionId: number, answers: string[]) => roomSession.sendPollAnswerMessage(pollId, questionId, answers); - - useNitroEvent(RoomSessionPollEvent.OFFER, event => - { - const pollEvent = new RoomWidgetPollUpdateEvent(RoomWidgetPollUpdateEvent.OFFER, event.id); - - pollEvent.summary = event.summary; - pollEvent.headline = event.headline; - - DispatchUiEvent(pollEvent); - }); - - useNitroEvent(RoomSessionPollEvent.ERROR, event => - { - const pollEvent = new RoomWidgetPollUpdateEvent(RoomWidgetPollUpdateEvent.ERROR, event.id); - - pollEvent.summary = event.summary; - pollEvent.headline = event.headline; - - DispatchUiEvent(pollEvent); - }); - - useNitroEvent(RoomSessionPollEvent.CONTENT, event => - { - const pollEvent = new RoomWidgetPollUpdateEvent(RoomWidgetPollUpdateEvent.CONTENT, event.id); - - pollEvent.startMessage = event.startMessage; - pollEvent.endMessage = event.endMessage; - pollEvent.numQuestions = event.numQuestions; - pollEvent.questionArray = event.questionArray; - pollEvent.npsPoll = event.npsPoll; - - DispatchUiEvent(pollEvent); - }); - - return { startPoll, rejectPoll, answerPoll }; -} - -export const usePollWidget = usePollWidgetState; diff --git a/src/hooks/rooms/widgets/useUserChooserWidget.ts b/src/hooks/rooms/widgets/useUserChooserWidget.ts deleted file mode 100644 index 40202a3..0000000 --- a/src/hooks/rooms/widgets/useUserChooserWidget.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { GetRoomEngine, RoomObjectCategory } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { GetRoomSession, RoomObjectItem } from '../../../api'; -import { useUserAddedEvent, useUserRemovedEvent } from '../engine'; -import { useRoom } from '../useRoom'; - -const useUserChooserWidgetState = () => -{ - const [ items, setItems ] = useState(null); - const { roomSession = null } = useRoom(); - - const onClose = () => setItems(null); - - const selectItem = (item: RoomObjectItem) => item && GetRoomEngine().selectRoomObject(GetRoomSession().roomId, item.id, item.category); - - const populateChooser = () => - { - const roomSession = GetRoomSession(); - const roomObjects = GetRoomEngine().getRoomObjects(roomSession.roomId, RoomObjectCategory.UNIT); - - setItems(roomObjects - .map(roomObject => - { - if(roomObject.id < 0) return null; - - const userData = roomSession.userDataManager.getUserDataByIndex(roomObject.id); - - if(!userData) return null; - - return new RoomObjectItem(userData.roomIndex, RoomObjectCategory.UNIT, userData.name); - }) - .sort((a, b) => ((a.name < b.name) ? -1 : 1))); - } - - useUserAddedEvent(!!items, event => - { - if(event.id < 0) return; - - const userData = GetRoomSession().userDataManager.getUserDataByIndex(event.id); - - if(!userData) return; - - setItems(prevValue => - { - const newValue = [ ...prevValue ]; - - newValue.push(new RoomObjectItem(userData.roomIndex, RoomObjectCategory.UNIT, userData.name)); - newValue.sort((a, b) => ((a.name < b.name) ? -1 : 1)); - - return newValue; - }); - }); - - useUserRemovedEvent(!!items, event => - { - if(event.id < 0) return; - - setItems(prevValue => - { - const newValue = [ ...prevValue ]; - - for(let i = 0; i < newValue.length; i++) - { - const existingValue = newValue[i]; - - if((existingValue.id !== event.id) || (existingValue.category !== event.category)) continue; - - newValue.splice(i, 1); - - break; - } - - return newValue; - }); - }); - - return { items, onClose, selectItem, populateChooser }; -} - -export const useUserChooserWidget = useUserChooserWidgetState; diff --git a/src/hooks/rooms/widgets/useWordQuizWidget.ts b/src/hooks/rooms/widgets/useWordQuizWidget.ts deleted file mode 100644 index 757f763..0000000 --- a/src/hooks/rooms/widgets/useWordQuizWidget.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { AvatarAction, GetRoomEngine, IQuestion, RoomSessionWordQuizEvent } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { VoteValue } from '../../../api'; -import { useNitroEvent } from '../../events'; -import { useRoom } from '../useRoom'; -import { usePollWidget } from './usePollWidget'; - -const DEFAULT_DISPLAY_DELAY = 4000; -const SIGN_FADE_DELAY = 3; - -const useWordQuizWidgetState = () => -{ - const [ pollId, setPollId ] = useState(-1); - const [ question, setQuestion ] = useState(null); - const [ answerSent, setAnswerSent ] = useState(false); - const [ questionClearTimeout, setQuestionClearTimeout ] = useState>(null); - const [ answerCounts, setAnswerCounts ] = useState>(new Map()); - const [ userAnswers, setUserAnswers ] = useState>(new Map()); - const { answerPoll = null } = usePollWidget(); - const { roomSession = null } = useRoom(); - - const clearQuestion = () => - { - setPollId(-1); - setQuestion(null); - } - - const vote = (vote: string) => - { - if(answerSent || !question) return; - - answerPoll(pollId, question.id, [ vote ]); - - setAnswerSent(true); - } - - useNitroEvent(RoomSessionWordQuizEvent.ANSWERED, event => - { - const userData = roomSession.userDataManager.getUserData(event.userId); - - if(!userData) return; - - setAnswerCounts(event.answerCounts); - - setUserAnswers(prevValue => - { - if(!prevValue.has(userData.roomIndex)) - { - const newValue = new Map(userAnswers); - - newValue.set(userData.roomIndex, { value: event.value, secondsLeft: SIGN_FADE_DELAY }); - - return newValue; - } - - return prevValue; - }); - - GetRoomEngine().updateRoomObjectUserGesture(roomSession.roomId, userData.roomIndex, AvatarAction.getGestureId((event.value === '0') ? AvatarAction.GESTURE_SAD : AvatarAction.GESTURE_SMILE)); - }); - - useNitroEvent(RoomSessionWordQuizEvent.FINISHED, event => - { - if(question && (question.id === event.questionId)) - { - setAnswerCounts(event.answerCounts); - setAnswerSent(true); - - setQuestionClearTimeout(prevValue => - { - if(prevValue) clearTimeout(prevValue); - - return setTimeout(() => clearQuestion(), DEFAULT_DISPLAY_DELAY); - }); - } - - setUserAnswers(new Map()); - }); - - useNitroEvent(RoomSessionWordQuizEvent.QUESTION, event => - { - setPollId(event.id); - setQuestion(event.question); - setAnswerSent(false); - setAnswerCounts(new Map()); - setUserAnswers(new Map()); - - setQuestionClearTimeout(prevValue => - { - if(prevValue) clearTimeout(prevValue); - - if(event.duration > 0) - { - const delay = event.duration < 1000 ? DEFAULT_DISPLAY_DELAY : event.duration; - - return setTimeout(() => clearQuestion(), delay); - } - - return null; - }); - }); - - useEffect(() => - { - const checkSignFade = () => - { - setUserAnswers(prevValue => - { - const keysToRemove: number[] = []; - - prevValue.forEach((value, key) => - { - value.secondsLeft--; - - if(value.secondsLeft <= 0) keysToRemove.push(key); - }); - - if(keysToRemove.length === 0) return prevValue; - - const copy = new Map(prevValue); - - keysToRemove.forEach(key => copy.delete(key)); - - return copy; - }); - } - - const interval = setInterval(() => checkSignFade(), 1000); - - return () => clearInterval(interval); - }, []); - - useEffect(() => - { - return () => - { - setQuestionClearTimeout(prevValue => - { - if(prevValue) clearTimeout(prevValue); - - return null; - }); - } - }, []); - - return { question, answerSent, answerCounts, userAnswers, vote }; -} - -export const useWordQuizWidget = useWordQuizWidgetState; diff --git a/src/hooks/session/index.ts b/src/hooks/session/index.ts deleted file mode 100644 index e61c7f3..0000000 --- a/src/hooks/session/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useSessionInfo'; diff --git a/src/hooks/session/useSessionInfo.ts b/src/hooks/session/useSessionInfo.ts deleted file mode 100644 index 122991d..0000000 --- a/src/hooks/session/useSessionInfo.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { FigureUpdateEvent, GetSessionDataManager, RoomUnitChatStyleComposer, UserInfoDataParser, UserInfoEvent, UserSettingsEvent } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { useBetween } from 'use-between'; -import { SendMessageComposer } from '../../api'; -import { useMessageEvent } from '../events'; - -const useSessionInfoState = () => -{ - const [ userInfo, setUserInfo ] = useState(null); - const [ userFigure, setUserFigure ] = useState(null); - const [ chatStyleId, setChatStyleId ] = useState(0); - const [ userRespectRemaining, setUserRespectRemaining ] = useState(0); - const [ petRespectRemaining, setPetRespectRemaining ] = useState(0); - - const updateChatStyleId = (styleId: number) => - { - setChatStyleId(styleId); - - SendMessageComposer(new RoomUnitChatStyleComposer(styleId)); - } - - const respectUser = (userId: number) => - { - GetSessionDataManager().giveRespect(userId); - - setUserRespectRemaining(GetSessionDataManager().respectsLeft); - } - - const respectPet = (petId: number) => - { - GetSessionDataManager().givePetRespect(petId); - - setPetRespectRemaining(GetSessionDataManager().respectsPetLeft); - } - - useMessageEvent(UserInfoEvent, event => - { - const parser = event.getParser(); - - setUserInfo(parser.userInfo); - setUserFigure(parser.userInfo.figure); - setUserRespectRemaining(parser.userInfo.respectsRemaining); - setPetRespectRemaining(parser.userInfo.respectsPetRemaining); - }); - - useMessageEvent(FigureUpdateEvent, event => - { - const parser = event.getParser(); - - setUserFigure(parser.figure); - }); - - useMessageEvent(UserSettingsEvent, event => - { - const parser = event.getParser(); - - setChatStyleId(parser.chatType); - }); - - return { userInfo, userFigure, chatStyleId, userRespectRemaining, petRespectRemaining, respectUser, respectPet, updateChatStyleId }; -} - -export const useSessionInfo = () => useBetween(useSessionInfoState); diff --git a/src/hooks/useLocalStorage.ts b/src/hooks/useLocalStorage.ts deleted file mode 100644 index 1e55fb9..0000000 --- a/src/hooks/useLocalStorage.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { NitroLogger } from '@nitrots/nitro-renderer'; -import { Dispatch, SetStateAction, useState } from 'react'; -import { GetLocalStorage, SetLocalStorage } from '../api'; - -const useLocalStorageState = (key: string, initialValue: T): [ T, Dispatch>] => -{ - const [ storedValue, setStoredValue ] = useState(() => - { - if(typeof window === 'undefined') return initialValue; - - try - { - const item = GetLocalStorage(key); - - return item ?? initialValue; - } - - catch(error) - { - return initialValue; - } - }); - - const setValue = (value: T) => - { - try - { - const valueToStore = value instanceof Function ? value(storedValue) : value; - - setStoredValue(valueToStore); - - if(typeof window !== 'undefined') SetLocalStorage(key, valueToStore); - } - - catch(error) - { - NitroLogger.error(error); - } - } - - return [ storedValue, setValue ]; -} - -export const useLocalStorage = useLocalStorageState; diff --git a/src/hooks/useSharedVisibility.ts b/src/hooks/useSharedVisibility.ts deleted file mode 100644 index b55855b..0000000 --- a/src/hooks/useSharedVisibility.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { useCallback, useMemo, useState } from 'react'; - -export const useSharedVisibility = () => -{ - const [ activeIds, setActiveIds ] = useState([]); - - const isVisible = useMemo(() => !!activeIds.length, [ activeIds ]); - - const activate = useCallback(() => - { - let id = -1; - - setActiveIds(prevValue => - { - const newValue = [ ...prevValue ]; - - id = newValue.length ? (newValue[(newValue.length - 1)] + 1) : 0; - - newValue.push(id); - - return newValue; - }); - - return id; - }, []); - - const deactivate = useCallback((id: number) => - { - setActiveIds(prevValue => - { - const newValue = [ ...prevValue ]; - - const index = newValue.indexOf(id); - - if(index === -1) return prevValue; - - newValue.splice(index, 1); - - return newValue; - }); - }, []); - - return { isVisible, activate, deactivate }; -} diff --git a/src/hooks/wired/index.ts b/src/hooks/wired/index.ts deleted file mode 100644 index dc79020..0000000 --- a/src/hooks/wired/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useWired'; diff --git a/src/hooks/wired/useWired.ts b/src/hooks/wired/useWired.ts deleted file mode 100644 index 5a6cb65..0000000 --- a/src/hooks/wired/useWired.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { ConditionDefinition, OpenMessageComposer, Triggerable, TriggerDefinition, UpdateActionMessageComposer, UpdateConditionMessageComposer, UpdateTriggerMessageComposer, WiredActionDefinition, WiredFurniActionEvent, WiredFurniConditionEvent, WiredFurniTriggerEvent, WiredOpenEvent, WiredSaveSuccessEvent } from '@nitrots/nitro-renderer'; -import { useEffect, useState } from 'react'; -import { useBetween } from 'use-between'; -import { IsOwnerOfFloorFurniture, LocalizeText, SendMessageComposer, WiredFurniType, WiredSelectionVisualizer } from '../../api'; -import { useMessageEvent } from '../events'; -import { useNotification } from '../notification'; - -const useWiredState = () => -{ - const [ trigger, setTrigger ] = useState(null); - const [ intParams, setIntParams ] = useState([]); - const [ stringParam, setStringParam ] = useState(''); - const [ furniIds, setFurniIds ] = useState([]); - const [ actionDelay, setActionDelay ] = useState(0); - const [ allowsFurni, setAllowsFurni ] = useState(WiredFurniType.STUFF_SELECTION_OPTION_NONE); - const { showConfirm = null } = useNotification(); - - const saveWired = () => - { - const save = (trigger: Triggerable) => - { - if(!trigger) return; - - if(trigger instanceof WiredActionDefinition) - { - SendMessageComposer(new UpdateActionMessageComposer(trigger.id, intParams, stringParam, furniIds, actionDelay, trigger.stuffTypeSelectionCode)); - } - - else if(trigger instanceof TriggerDefinition) - { - SendMessageComposer(new UpdateTriggerMessageComposer(trigger.id, intParams, stringParam, furniIds, trigger.stuffTypeSelectionCode)); - } - - else if(trigger instanceof ConditionDefinition) - { - SendMessageComposer(new UpdateConditionMessageComposer(trigger.id, intParams, stringParam, furniIds, trigger.stuffTypeSelectionCode)); - } - } - - if(!IsOwnerOfFloorFurniture(trigger.id)) - { - showConfirm(LocalizeText('wiredfurni.nonowner.change.confirm.body'), () => - { - save(trigger) - }, null, null, null, LocalizeText('wiredfurni.nonowner.change.confirm.title')); - } - else - { - save(trigger); - } - } - - const selectObjectForWired = (objectId: number, category: number) => - { - if(!trigger || !allowsFurni) return; - - if(objectId <= 0) return; - - setFurniIds(prevValue => - { - const newFurniIds = [ ...prevValue ]; - - const index = prevValue.indexOf(objectId); - - if(index >= 0) - { - newFurniIds.splice(index, 1); - - WiredSelectionVisualizer.hide(objectId); - } - - else if(newFurniIds.length < trigger.maximumItemSelectionCount) - { - newFurniIds.push(objectId); - - WiredSelectionVisualizer.show(objectId); - } - - return newFurniIds; - }); - } - - useMessageEvent(WiredOpenEvent, event => - { - const parser = event.getParser(); - - SendMessageComposer(new OpenMessageComposer(parser.stuffId)); - }); - - useMessageEvent(WiredSaveSuccessEvent, event => - { - const parser = event.getParser(); - - setTrigger(null); - }); - - useMessageEvent(WiredFurniActionEvent, event => - { - const parser = event.getParser(); - - setTrigger(parser.definition); - }); - - useMessageEvent(WiredFurniConditionEvent, event => - { - const parser = event.getParser(); - - setTrigger(parser.definition); - }); - - useMessageEvent(WiredFurniTriggerEvent, event => - { - const parser = event.getParser(); - - setTrigger(parser.definition); - }); - - useEffect(() => - { - if(!trigger) return; - - return () => - { - setIntParams([]); - setStringParam(''); - setActionDelay(0); - setFurniIds(prevValue => - { - if(prevValue && prevValue.length) WiredSelectionVisualizer.clearSelectionShaderFromFurni(prevValue); - - return []; - }); - setAllowsFurni(WiredFurniType.STUFF_SELECTION_OPTION_NONE); - } - }, [ trigger ]); - - return { trigger, setTrigger, intParams, setIntParams, stringParam, setStringParam, furniIds, setFurniIds, actionDelay, setActionDelay, setAllowsFurni, saveWired, selectObjectForWired }; -} - -export const useWired = () => useBetween(useWiredState); diff --git a/src/index.scss b/src/index.scss deleted file mode 100644 index 5f3ecbb..0000000 --- a/src/index.scss +++ /dev/null @@ -1,26 +0,0 @@ -@import './assets/styles'; - -html, -body { - padding: 0; - width: 100%; - height: 100%; - overflow: hidden; - user-select: none; - scrollbar-width: thin; - - .image-rendering-pixelated { - image-rendering: pixelated; - image-rendering: -moz-crisp-edges; - } - - * { - -webkit-font-smoothing: antialiased; - } -} - -img { - object-fit: none; -} - -@import './App'; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..92db0e5 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,21 @@ +import { AbstractRenderer, BrowserAdapter, DOMAdapter, HelloSystem, TextureSource } from 'pixi.js'; + +HelloSystem.defaultOptions.hello = true; +AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat = false; +TextureSource.defaultOptions.scaleMode = (!(window.devicePixelRatio % 1)) ? 'nearest' : 'linear'; +DOMAdapter.set(BrowserAdapter); + +export * from '@nitrots/api'; +export * from '@nitrots/assets'; +export * from '@nitrots/avatar'; +export * from '@nitrots/camera'; +export * from '@nitrots/communication'; +export * from '@nitrots/configuration'; +export * from '@nitrots/events'; +export * from '@nitrots/localization'; +export * from '@nitrots/room'; +export * from '@nitrots/session'; +export * from '@nitrots/sound'; +export * from '@nitrots/utils'; +export * from './DevTools'; +export * from './pixi-proxy'; diff --git a/src/index.tsx b/src/index.tsx deleted file mode 100644 index 196309d..0000000 --- a/src/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { createRoot } from 'react-dom/client'; -import { App } from './App'; -import './index.scss'; - -createRoot(document.getElementById('root')).render(); diff --git a/src/pixi-proxy/NitroAdjustmentFilter.ts b/src/pixi-proxy/NitroAdjustmentFilter.ts new file mode 100644 index 0000000..7818fa4 --- /dev/null +++ b/src/pixi-proxy/NitroAdjustmentFilter.ts @@ -0,0 +1,4 @@ +import { AdjustmentFilter } from 'pixi-filters'; + +export class NitroAdjustmentFilter extends AdjustmentFilter +{} diff --git a/src/pixi-proxy/NitroAlphaFilter.ts b/src/pixi-proxy/NitroAlphaFilter.ts new file mode 100644 index 0000000..35eb3aa --- /dev/null +++ b/src/pixi-proxy/NitroAlphaFilter.ts @@ -0,0 +1,4 @@ +import { AlphaFilter } from 'pixi.js'; + +export class NitroAlphaFilter extends AlphaFilter +{} diff --git a/src/pixi-proxy/NitroContainer.ts b/src/pixi-proxy/NitroContainer.ts new file mode 100644 index 0000000..978aed2 --- /dev/null +++ b/src/pixi-proxy/NitroContainer.ts @@ -0,0 +1,4 @@ +import { Container } from 'pixi.js'; + +export class NitroContainer extends Container +{} diff --git a/src/pixi-proxy/NitroFilter.ts b/src/pixi-proxy/NitroFilter.ts new file mode 100644 index 0000000..53928e1 --- /dev/null +++ b/src/pixi-proxy/NitroFilter.ts @@ -0,0 +1,4 @@ +import { Filter } from 'pixi.js'; + +export class NitroFilter extends Filter +{} diff --git a/src/pixi-proxy/NitroRectangle.ts b/src/pixi-proxy/NitroRectangle.ts new file mode 100644 index 0000000..9ced33b --- /dev/null +++ b/src/pixi-proxy/NitroRectangle.ts @@ -0,0 +1,4 @@ +import { Rectangle } from 'pixi.js'; + +export class NitroRectangle extends Rectangle +{} diff --git a/src/pixi-proxy/NitroRenderTexture.ts b/src/pixi-proxy/NitroRenderTexture.ts new file mode 100644 index 0000000..fd6f19f --- /dev/null +++ b/src/pixi-proxy/NitroRenderTexture.ts @@ -0,0 +1,4 @@ +import { RenderTexture } from 'pixi.js'; + +export class NitroRenderTexture extends RenderTexture +{} diff --git a/src/pixi-proxy/NitroSprite.ts b/src/pixi-proxy/NitroSprite.ts new file mode 100644 index 0000000..9a994ec --- /dev/null +++ b/src/pixi-proxy/NitroSprite.ts @@ -0,0 +1,5 @@ +import { Sprite as SpriteBase } from 'pixi.js'; + +export class NitroSprite extends SpriteBase +{ +} diff --git a/src/pixi-proxy/NitroTexture.ts b/src/pixi-proxy/NitroTexture.ts new file mode 100644 index 0000000..dd70aeb --- /dev/null +++ b/src/pixi-proxy/NitroTexture.ts @@ -0,0 +1,4 @@ +import { Texture } from 'pixi.js'; + +export class NitroTexture extends Texture +{} diff --git a/src/pixi-proxy/NitroTicker.ts b/src/pixi-proxy/NitroTicker.ts new file mode 100644 index 0000000..0b35d6c --- /dev/null +++ b/src/pixi-proxy/NitroTicker.ts @@ -0,0 +1,3 @@ +import { Ticker } from 'pixi.js'; + +export type NitroTicker = Ticker; diff --git a/src/pixi-proxy/index.ts b/src/pixi-proxy/index.ts new file mode 100644 index 0000000..1ff5b32 --- /dev/null +++ b/src/pixi-proxy/index.ts @@ -0,0 +1,9 @@ +export * from './NitroAdjustmentFilter'; +export * from './NitroAlphaFilter'; +export * from './NitroContainer'; +export * from './NitroFilter'; +export * from './NitroRectangle'; +export * from './NitroRenderTexture'; +export * from './NitroSprite'; +export * from './NitroTexture'; +export * from './NitroTicker'; diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts deleted file mode 100644 index 6431bc5..0000000 --- a/src/react-app-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/src/workers/IntervalWebWorker.ts b/src/workers/IntervalWebWorker.ts deleted file mode 100644 index 978c80a..0000000 --- a/src/workers/IntervalWebWorker.ts +++ /dev/null @@ -1,26 +0,0 @@ -export default () => -{ - let interval: ReturnType = null; - - // eslint-disable-next-line no-restricted-globals - self.onmessage = (message: MessageEvent) => - { - if(!message) return; - - const data: { [index: string]: any } = message.data; - - switch(data.action) - { - case 'START': - interval = setInterval(() => postMessage(null), data.content); - break; - case 'STOP': - if(interval) - { - clearInterval(interval); - interval = null; - } - break; - } - } -} diff --git a/src/workers/WorkerBuilder.ts b/src/workers/WorkerBuilder.ts deleted file mode 100644 index b848893..0000000 --- a/src/workers/WorkerBuilder.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class WorkerBuilder extends Worker -{ - constructor(worker) - { - const code = worker.toString(); - const blob = new Blob([ `(${ code })()` ]); - - super(URL.createObjectURL(blob)); - } -} diff --git a/tsconfig.json b/tsconfig.json index 9912440..eceefbc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,29 +1,31 @@ { + "compileOnSave": false, "compilerOptions": { "baseUrl": "./src", - "target": "es6", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "esModuleInterop": true, + "importHelpers": true, + "isolatedModules": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, "allowJs": true, "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": false, - "downlevelIteration": true, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": false, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, "noEmit": true, - "jsx": "react-jsx" + "strict": false, + "strictNullChecks": false, + "target": "ES6", + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "module": "ES6" }, "include": [ - "src", - "node_modules/@nitrots/nitro-renderer/src/**/*.ts", - ] + "src", "packages/utils/src/FurniId.ts", "packages/room/src/messages", "packages/room/src/utils", "packages/room/src/object/logic", "packages/room/src/object/visualization", "packages/room/src/object/RoomObject.ts", "packages/room/src/object/RoomObjectModel.ts", "packages/utils/src/NumberBank.ts", "packages/utils/src/RoomId.ts", "packages/utils/src/ColorConverter.ts", "packages/utils/src/PointMath.ts", "packages/room/src/renderer/cache", "packages/room/src/renderer/RoomSpriteCanvas.ts", "packages/room/src/renderer/RoomRendererFactory.ts", "packages/room/src/renderer/RoomRenderer.ts", "packages/room/src/RoomInstance.ts", "packages/room/src/RoomManager.ts", "packages/room/src/RoomObjectManager.ts", "packages/room/src/RoomPreviewer.ts", "packages/room/src/object/RoomWallData.ts", "packages/room/src/object/RoomPlaneParser.ts", "packages/room/src/object/RoomPlaneMaskData.ts", "packages/room/src/object/RoomPlaneData.ts", "packages/room/src/object/RoomPlaneBitmapMaskParser.ts", "packages/room/src/object/RoomPlaneBitmapMaskData.ts", "packages/room/src/RoomObjectVisualizationFactory.ts", "packages/room/src/object/RoomMapMaskData.ts", "packages/room/src/object/RoomMapData.ts", "packages/room/src/object/RoomFloorHole.ts", "packages/room/src/RoomVariableEnum.ts", "packages/room/src/RoomObjectLogicFactory.ts", "packages/room/src/RoomObjectEventHandler.ts", "packages/room/src/RoomMessageHandler.ts", "packages/room/src/RoomEngine.ts", "packages/room/src/RoomContentLoader.ts", "packages/room/src/PetColorResult.ts", "packages/room/src/ImageResult.ts", "packages/utils/src/Node3D.ts", "packages/utils/src/Matrix4x4.ts", "packages/utils/src/LegacyExternalInterface.ts", "packages/utils/src/HabboWebTools.ts", "packages/utils/src/motion", "packages/avatar/src/actions", "packages/avatar/animation", "packages/avatar/cache", "packages/avatar/src/data", "packages/avatar/geometry", "packages/avatar/src/pets", "packages/avatar/src/structure/animation", "packages/avatar/src/structure/figure", "packages/avatar/src/structure/parts", "packages/avatar/structure/AvatarAnimationData.ts", "packages/avatar/structure/AvatarCanvas.ts", "packages/avatar/structure/FigureSetData.ts", "packages/avatar/structure/index.ts", "packages/avatar/structure/PartSetsData.ts", "packages/avatar/src/cache/AvatarImageCache.ts", "packages/localization/src/LocalizationManager.ts", "packages/localization/src/GetLocalization.ts", "packages/localization/src/BadgeBaseAndLevel.ts" ] } diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..92498d8 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,28 @@ +// vite.config.js +import typescript from '@rollup/plugin-typescript'; +import { resolve } from 'path'; +import { defineConfig } from 'vite'; + +const resolvePath = str => resolve(__dirname, str); + +export default defineConfig({ + plugins: [ + typescript({ + 'target': 'es6', + 'rootDir': resolvePath('./src'), + 'declaration': true, + exclude: resolvePath('./node_modules/**'), + allowSyntheticDefaultImports: true + }) + ], + build: { + lib: { + entry: resolve(__dirname, 'src/index.ts'), + name: 'nitro-renderer', + fileName: 'nitro-renderer' + } + }, + server: { + host: '127.0.0.1' + } +}); diff --git a/vite.config.mjs b/vite.config.mjs deleted file mode 100644 index 7d6d25d..0000000 --- a/vite.config.mjs +++ /dev/null @@ -1,32 +0,0 @@ -// vite.config.js -import react from '@vitejs/plugin-react'; -import { resolve } from 'path'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - plugins: [ react() ], - resolve: { - alias: { - '@': resolve(__dirname, 'src'), - '~': resolve(__dirname, 'node_modules') - } - }, - build: { - assetsInlineLimit: 102400, - chunkSizeWarningLimit: 200000, - rollupOptions: { - output: { - assetFileNames: 'src/assets/[name].[ext]', - manualChunks: id => - { - if(id.includes('node_modules')) - { - if(id.includes('@nitrots/nitro-renderer')) return 'nitro-renderer'; - - return 'vendor'; - } - } - } - } - } -}) diff --git a/yarn.lock b/yarn.lock index c54b602..ce04fcd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,334 +7,120 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@ampproject/remapping@^2.2.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" - integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.24" +"@esbuild/aix-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" + integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== -"@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.1", "@babel/code-frame@^7.24.2": - version "7.24.2" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" - integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== - dependencies: - "@babel/highlight" "^7.24.2" - picocolors "^1.0.0" +"@esbuild/android-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" + integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== -"@babel/compat-data@^7.23.5": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.1.tgz#31c1f66435f2a9c329bb5716a6d6186c516c3742" - integrity sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA== +"@esbuild/android-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" + integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== -"@babel/core@^7.23.5": - version "7.24.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.3.tgz#568864247ea10fbd4eff04dda1e05f9e2ea985c3" - integrity sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.24.2" - "@babel/generator" "^7.24.1" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.24.1" - "@babel/parser" "^7.24.1" - "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.1" - "@babel/types" "^7.24.0" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" +"@esbuild/android-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" + integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== -"@babel/generator@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.1.tgz#e67e06f68568a4ebf194d1c6014235344f0476d0" - integrity sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A== - dependencies: - "@babel/types" "^7.24.0" - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^2.5.1" +"@esbuild/darwin-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" + integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== -"@babel/helper-compilation-targets@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" - integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== - dependencies: - "@babel/compat-data" "^7.23.5" - "@babel/helper-validator-option" "^7.23.5" - browserslist "^4.22.2" - lru-cache "^5.1.1" - semver "^6.3.1" +"@esbuild/darwin-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" + integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== -"@babel/helper-environment-visitor@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" - integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== +"@esbuild/freebsd-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" + integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== -"@babel/helper-function-name@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" - integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/types" "^7.23.0" +"@esbuild/freebsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" + integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== -"@babel/helper-hoist-variables@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" +"@esbuild/linux-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" + integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== -"@babel/helper-module-imports@^7.22.15": - version "7.24.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz#6ac476e6d168c7c23ff3ba3cf4f7841d46ac8128" - integrity sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg== - dependencies: - "@babel/types" "^7.24.0" +"@esbuild/linux-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" + integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== -"@babel/helper-module-transforms@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" - integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.20" +"@esbuild/linux-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" + integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== -"@babel/helper-plugin-utils@^7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz#945681931a52f15ce879fd5b86ce2dae6d3d7f2a" - integrity sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w== +"@esbuild/linux-loong64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" + integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== -"@babel/helper-simple-access@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" - integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== - dependencies: - "@babel/types" "^7.22.5" +"@esbuild/linux-mips64el@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" + integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== -"@babel/helper-split-export-declaration@^7.22.6": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" - integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== - dependencies: - "@babel/types" "^7.22.5" +"@esbuild/linux-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" + integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== -"@babel/helper-string-parser@^7.23.4": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" - integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== +"@esbuild/linux-riscv64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" + integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== +"@esbuild/linux-s390x@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" + integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== -"@babel/helper-validator-option@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" - integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== +"@esbuild/linux-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" + integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== -"@babel/helpers@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.1.tgz#183e44714b9eba36c3038e442516587b1e0a1a94" - integrity sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg== - dependencies: - "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.1" - "@babel/types" "^7.24.0" +"@esbuild/netbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" + integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== -"@babel/highlight@^7.24.2": - version "7.24.2" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.2.tgz#3f539503efc83d3c59080a10e6634306e0370d26" - integrity sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - picocolors "^1.0.0" +"@esbuild/openbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" + integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== -"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.24.0", "@babel/parser@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.1.tgz#1e416d3627393fab1cb5b0f2f1796a100ae9133a" - integrity sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg== +"@esbuild/sunos-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" + integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== -"@babel/plugin-transform-react-jsx-self@^7.23.3": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.1.tgz#a21d866d8167e752c6a7c4555dba8afcdfce6268" - integrity sha512-kDJgnPujTmAZ/9q2CN4m2/lRsUUPDvsG3+tSHWUJIzMGTt5U/b/fwWd3RO3n+5mjLrsBrVa5eKFRVSQbi3dF1w== - dependencies: - "@babel/helper-plugin-utils" "^7.24.0" +"@esbuild/win32-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" + integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== -"@babel/plugin-transform-react-jsx-source@^7.23.3": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.1.tgz#a2dedb12b09532846721b5df99e52ef8dc3351d0" - integrity sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA== - dependencies: - "@babel/helper-plugin-utils" "^7.24.0" +"@esbuild/win32-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" + integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== -"@babel/runtime@^7.21.0", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.7": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.1.tgz#431f9a794d173b53720e69a6464abc6f0e2a5c57" - integrity sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/template@^7.22.15", "@babel/template@^7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" - integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== - dependencies: - "@babel/code-frame" "^7.23.5" - "@babel/parser" "^7.24.0" - "@babel/types" "^7.24.0" - -"@babel/traverse@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.1.tgz#d65c36ac9dd17282175d1e4a3c49d5b7988f530c" - integrity sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ== - dependencies: - "@babel/code-frame" "^7.24.1" - "@babel/generator" "^7.24.1" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.24.1" - "@babel/types" "^7.24.0" - debug "^4.3.1" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" - integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== - dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@esbuild/aix-ppc64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" - integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== - -"@esbuild/android-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" - integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== - -"@esbuild/android-arm@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" - integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== - -"@esbuild/android-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" - integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== - -"@esbuild/darwin-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb" - integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== - -"@esbuild/darwin-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" - integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== - -"@esbuild/freebsd-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" - integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== - -"@esbuild/freebsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" - integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== - -"@esbuild/linux-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" - integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== - -"@esbuild/linux-arm@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" - integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== - -"@esbuild/linux-ia32@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" - integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== - -"@esbuild/linux-loong64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" - integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== - -"@esbuild/linux-mips64el@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" - integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== - -"@esbuild/linux-ppc64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" - integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== - -"@esbuild/linux-riscv64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" - integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== - -"@esbuild/linux-s390x@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" - integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== - -"@esbuild/linux-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" - integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== - -"@esbuild/netbsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" - integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== - -"@esbuild/openbsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" - integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== - -"@esbuild/sunos-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" - integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== - -"@esbuild/win32-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" - integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== - -"@esbuild/win32-ia32@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" - integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== - -"@esbuild/win32-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" - integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== +"@esbuild/win32-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" + integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" @@ -383,41 +169,9 @@ integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" - integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== - -"@jridgewell/gen-mapping@^0.3.5": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" - integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== - dependencies: - "@jridgewell/set-array" "^1.2.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" - integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== - -"@jridgewell/set-array@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" - integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.25" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" + version "2.0.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" + integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -440,243 +194,143 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@popperjs/core@^2.11.6": - version "2.11.8" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" - integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== +"@pixi/colord@^2.9.6": + version "2.9.6" + resolved "https://registry.yarnpkg.com/@pixi/colord/-/colord-2.9.6.tgz#7e4e7851480da6fd3cef4e331f008d60be7e1204" + integrity sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA== -"@react-aria/ssr@^3.5.0": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.9.2.tgz#01b756965cd6e32b95217f968f513eb3bd6ee44b" - integrity sha512-0gKkgDYdnq1w+ey8KzG9l+H5Z821qh9vVjztk55rUg71vTk/Eaebeir+WtzcLLwTjw3m/asIjx8Y59y1lJZhBw== +"@pixi/gif@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@pixi/gif/-/gif-3.0.0.tgz#dbd3e1bfb2a5d83a84965f5b517cc5dcb8407862" + integrity sha512-0am94k1SEwacW6anOiNT9vt3vnefEaiMxkg30nMwvqU3XkIO6sSsFBgQM3UArjDG/quYsujjyZZkyhl7yBF6GQ== + +"@rollup/plugin-typescript@^11.1.6": + version "11.1.6" + resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz#724237d5ec12609ec01429f619d2a3e7d4d1b22b" + integrity sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA== dependencies: - "@swc/helpers" "^0.5.0" + "@rollup/pluginutils" "^5.1.0" + resolve "^1.22.1" -"@restart/hooks@^0.4.9": - version "0.4.16" - resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.16.tgz#95ae8ac1cc7e2bd4fed5e39800ff85604c6d59fb" - integrity sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w== +"@rollup/pluginutils@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" + integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== dependencies: - dequal "^2.0.3" + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" -"@restart/ui@^1.6.8": - version "1.6.8" - resolved "https://registry.yarnpkg.com/@restart/ui/-/ui-1.6.8.tgz#61b73503d4690e2f0f58992d4d6ae1e89c276791" - integrity sha512-6ndCv3oZ7r9vuP1Ok9KH55TM1/UkdBnP/fSraW0DFDMbPMzWKhVKeFAIEUCRCSdzayjZDcFYK6xbMlipN9dmMA== - dependencies: - "@babel/runtime" "^7.21.0" - "@popperjs/core" "^2.11.6" - "@react-aria/ssr" "^3.5.0" - "@restart/hooks" "^0.4.9" - "@types/warning" "^3.0.0" - dequal "^2.0.3" - dom-helpers "^5.2.0" - uncontrollable "^8.0.1" - warning "^4.0.3" +"@rollup/rollup-android-arm-eabi@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.1.tgz#11aaa02a933864b87f0b31cf2b755734e1f22787" + integrity sha512-iU2Sya8hNn1LhsYyf0N+L4Gf9Qc+9eBTJJJsaOGUp+7x4n2M9dxTt8UvhJl3oeftSjblSlpCfvjA/IfP3g5VjQ== -"@rollup/rollup-android-arm-eabi@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.2.tgz#fbf098f49d96a8cac9056f22f5fd80906ef3af85" - integrity sha512-3XFIDKWMFZrMnao1mJhnOT1h2g0169Os848NhhmGweEcfJ4rCi+3yMCOLG4zA61rbJdkcrM/DjVZm9Hg5p5w7g== +"@rollup/rollup-android-arm64@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.1.tgz#b1e606fb4b46b38dc32bf010d513449462d669e9" + integrity sha512-wlzcWiH2Ir7rdMELxFE5vuM7D6TsOcJ2Yw0c3vaBR3VOsJFVTx9xvwnAvhgU5Ii8Gd6+I11qNHwndDscIm0HXg== -"@rollup/rollup-android-arm64@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.2.tgz#0d2448251040fce19a98eee505dff5b3c8ec9b98" - integrity sha512-GdxxXbAuM7Y/YQM9/TwwP+L0omeE/lJAR1J+olu36c3LqqZEBdsIWeQ91KBe6nxwOnb06Xh7JS2U5ooWU5/LgQ== +"@rollup/rollup-darwin-arm64@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.1.tgz#dc21df1be9402671a8b6b15a93dd5953c68ec114" + integrity sha512-YRXa1+aZIFN5BaImK+84B3uNK8C6+ynKLPgvn29X9s0LTVCByp54TB7tdSMHDR7GTV39bz1lOmlLDuedgTwwHg== -"@rollup/rollup-darwin-arm64@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.2.tgz#78db4d4da5b1b84c22adbe25c8a4961b3f22d3af" - integrity sha512-mCMlpzlBgOTdaFs83I4XRr8wNPveJiJX1RLfv4hggyIVhfB5mJfN4P8Z6yKh+oE4Luz+qq1P3kVdWrCKcMYrrA== +"@rollup/rollup-darwin-x64@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.1.tgz#397dcc4427d774f29b9954676893574ac563bf0b" + integrity sha512-opjWJ4MevxeA8FhlngQWPBOvVWYNPFkq6/25rGgG+KOy0r8clYwL1CFd+PGwRqqMFVQ4/Qd3sQu5t7ucP7C/Uw== -"@rollup/rollup-darwin-x64@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.2.tgz#fcc05af54379f8ee5c7e954987d4514c6fd0fb42" - integrity sha512-yUoEvnH0FBef/NbB1u6d3HNGyruAKnN74LrPAfDQL3O32e3k3OSfLrPgSJmgb3PJrBZWfPyt6m4ZhAFa2nZp2A== +"@rollup/rollup-linux-arm-gnueabihf@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.1.tgz#d851fd49d617e7792e7cde8e5a95ca51ea520fe5" + integrity sha512-uBkwaI+gBUlIe+EfbNnY5xNyXuhZbDSx2nzzW8tRMjUmpScd6lCQYKY2V9BATHtv5Ef2OBq6SChEP8h+/cxifQ== -"@rollup/rollup-linux-arm-gnueabihf@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.2.tgz#2ce200efa1ef4a56ee2af7b453edc74a259d7d31" - integrity sha512-GYbLs5ErswU/Xs7aGXqzc3RrdEjKdmoCrgzhJWyFL0r5fL3qd1NPcDKDowDnmcoSiGJeU68/Vy+OMUluRxPiLQ== +"@rollup/rollup-linux-arm64-gnu@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.1.tgz#e41a271ae51f79ffee6fb2b5597cc81b4ef66ad9" + integrity sha512-0bK9aG1kIg0Su7OcFTlexkVeNZ5IzEsnz1ept87a0TUgZ6HplSgkJAnFpEVRW7GRcikT4GlPV0pbtVedOaXHQQ== -"@rollup/rollup-linux-arm64-gnu@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.2.tgz#5a24aac882bff9abfda3f45f6f1db2166c342a4a" - integrity sha512-L1+D8/wqGnKQIlh4Zre9i4R4b4noxzH5DDciyahX4oOz62CphY7WDWqJoQ66zNR4oScLNOqQJfNSIAe/6TPUmQ== +"@rollup/rollup-linux-arm64-musl@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.1.tgz#d3b4cd6ef18d0aa7103129755e0c535701624fac" + integrity sha512-qB6AFRXuP8bdkBI4D7UPUbE7OQf7u5OL+R94JE42Z2Qjmyj74FtDdLGeriRyBDhm4rQSvqAGCGC01b8Fu2LthQ== -"@rollup/rollup-linux-arm64-musl@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.2.tgz#f1fb4c6f961d3f3397231a99e621d199200e4ea9" - integrity sha512-tK5eoKFkXdz6vjfkSTCupUzCo40xueTOiOO6PeEIadlNBkadH1wNOH8ILCPIl8by/Gmb5AGAeQOFeLev7iZDOA== +"@rollup/rollup-linux-riscv64-gnu@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.1.tgz#215101b2bb768cce2f2227145b8dd5c3c716c259" + integrity sha512-sHig3LaGlpNgDj5o8uPEoGs98RII8HpNIqFtAI8/pYABO8i0nb1QzT0JDoXF/pxzqO+FkxvwkHZo9k0NJYDedg== -"@rollup/rollup-linux-powerpc64le-gnu@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.13.2.tgz#46b2463d94ac3af3e0f7a2947b695397bc13b755" - integrity sha512-zvXvAUGGEYi6tYhcDmb9wlOckVbuD+7z3mzInCSTACJ4DQrdSLPNUeDIcAQW39M3q6PDquqLWu7pnO39uSMRzQ== +"@rollup/rollup-linux-x64-gnu@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.1.tgz#34a12fa305e167105eab70dbf577cd41e5199709" + integrity sha512-nD3YcUv6jBJbBNFvSbp0IV66+ba/1teuBcu+fBBPZ33sidxitc6ErhON3JNavaH8HlswhWMC3s5rgZpM4MtPqQ== -"@rollup/rollup-linux-riscv64-gnu@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.2.tgz#47b932ee59a5395a3a341b0493e361d9e6032cf2" - integrity sha512-C3GSKvMtdudHCN5HdmAMSRYR2kkhgdOfye4w0xzyii7lebVr4riCgmM6lRiSCnJn2w1Xz7ZZzHKuLrjx5620kw== +"@rollup/rollup-linux-x64-musl@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.1.tgz#3f000b5a92a32b844e385e1166979c87882930a3" + integrity sha512-7/XVZqgBby2qp/cO0TQ8uJK+9xnSdJ9ct6gSDdEr4MfABrjTyrW6Bau7HQ73a2a5tPB7hno49A0y1jhWGDN9OQ== -"@rollup/rollup-linux-s390x-gnu@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.13.2.tgz#8e14a1b3c3b9a4440c70a9c1ba12d32aa21f9712" - integrity sha512-l4U0KDFwzD36j7HdfJ5/TveEQ1fUTjFFQP5qIt9gBqBgu1G8/kCaq5Ok05kd5TG9F8Lltf3MoYsUMw3rNlJ0Yg== +"@rollup/rollup-win32-arm64-msvc@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.1.tgz#27977d91f5059645ebb3b7fbf4429982de2278d3" + integrity sha512-CYc64bnICG42UPL7TrhIwsJW4QcKkIt9gGlj21gq3VV0LL6XNb1yAdHVp1pIi9gkts9gGcT3OfUYHjGP7ETAiw== -"@rollup/rollup-linux-x64-gnu@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.2.tgz#270e939194b66df77bcb33dd9a5ddf7784bd7997" - integrity sha512-xXMLUAMzrtsvh3cZ448vbXqlUa7ZL8z0MwHp63K2IIID2+DeP5iWIT6g1SN7hg1VxPzqx0xZdiDM9l4n9LRU1A== +"@rollup/rollup-win32-ia32-msvc@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.1.tgz#0d252acd5af0274209c74374867ee8b949843d75" + integrity sha512-LN+vnlZ9g0qlHGlS920GR4zFCqAwbv2lULrR29yGaWP9u7wF5L7GqWu9Ah6/kFZPXPUkpdZwd//TNR+9XC9hvA== -"@rollup/rollup-linux-x64-musl@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.2.tgz#e8dd0f3c2046acbda2934490b36552e856a3bc6a" - integrity sha512-M/JYAWickafUijWPai4ehrjzVPKRCyDb1SLuO+ZyPfoXgeCEAlgPkNXewFZx0zcnoIe3ay4UjXIMdXQXOZXWqA== +"@rollup/rollup-win32-x64-msvc@4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.1.tgz#cd8d175e001c212d5ac71c7827ef1d5c5e14494c" + integrity sha512-n+vkrSyphvmU0qkQ6QBNXCGr2mKjhP08mPRM/Xp5Ck2FV4NrHU+y6axzDeixUrCBHVUS51TZhjqrKBBsHLKb2Q== -"@rollup/rollup-win32-arm64-msvc@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.2.tgz#f8b65a4a7e7a6b383e7b14439129b2f474ff123c" - integrity sha512-2YWwoVg9KRkIKaXSh0mz3NmfurpmYoBBTAXA9qt7VXk0Xy12PoOP40EFuau+ajgALbbhi4uTj3tSG3tVseCjuA== +"@types/css-font-loading-module@^0.0.12": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@types/css-font-loading-module/-/css-font-loading-module-0.0.12.tgz#65494833928823f998fbe8e86312821875d80db5" + integrity sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA== -"@rollup/rollup-win32-ia32-msvc@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.2.tgz#bc1c5a4fbc4337d6cb15da80a4de95fd53ab3573" - integrity sha512-2FSsE9aQ6OWD20E498NYKEQLneShWes0NGMPQwxWOdws35qQXH+FplabOSP5zEe1pVjurSDOGEVCE2agFwSEsw== +"@types/earcut@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@types/earcut/-/earcut-2.1.4.tgz#5811d7d333048f5a7573b22ddc84923e69596da6" + integrity sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ== -"@rollup/rollup-win32-x64-msvc@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.2.tgz#851959c4c1c3c6647aba1f388198c8243aed6917" - integrity sha512-7h7J2nokcdPePdKykd8wtc8QqqkqxIrUz7MHj6aNr8waBRU//NLDVnNjQnqQO6fqtjrtCdftpbTuOKAyrAQETQ== - -"@swc/helpers@^0.5.0": - version "0.5.8" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.8.tgz#65d56b1961487fd99795ffd8c68edb7a591571fb" - integrity sha512-lruDGw3pnfM3wmZHeW7JuhkGQaJjPyiKjxeGhdmfoOT53Ic9qb5JLDNaK2HUdl1zLDeX28H221UvKjfdvSLVMg== - dependencies: - tslib "^2.4.0" - -"@tanstack/react-virtual@3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.2.0.tgz#fb70f9c6baee753a5a0f7618ac886205d5a02af9" - integrity sha512-OEdMByf2hEfDa6XDbGlZN8qO6bTjlNKqjM3im9JG+u3mCL8jALy0T/67oDI001raUUPh1Bdmfn4ZvPOV5knpcg== - dependencies: - "@tanstack/virtual-core" "3.2.0" - -"@tanstack/virtual-core@3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.2.0.tgz#874d36135e4badce2719e7bdc556ce240cbaff14" - integrity sha512-P5XgYoAw/vfW65byBbJQCw+cagdXDT/qH6wmABiLt4v4YBT2q2vqCOhihe+D1Nt325F/S/0Tkv6C5z0Lv+VBQQ== - -"@types/babel__core@^7.20.5": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" - integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== - dependencies: - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.8" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" - integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" - integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd" - integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== - dependencies: - "@babel/types" "^7.20.7" - -"@types/estree@1.0.5": +"@types/estree@1.0.5", "@types/estree@^1.0.0": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/howler@^2.2.11": + version "2.2.11" + resolved "https://registry.yarnpkg.com/@types/howler/-/howler-2.2.11.tgz#a75c4ab5666aee5fcfbd5de15d35dbaaa3d3f070" + integrity sha512-7aBoUL6RbSIrqKnpEgfa1wSNUBK06mn08siP2QI0zYk7MXfEJAaORc4tohamQYqCqVESoDyRWSdQn2BOKWj2Qw== + "@types/json-schema@^7.0.12": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/node@^20.11.30": - version "20.12.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.2.tgz#9facdd11102f38b21b4ebedd9d7999663343d72e" - integrity sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ== - dependencies: - undici-types "~5.26.4" - -"@types/prop-types@*": - version "15.7.12" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" - integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== - -"@types/react-dom@^18.2.22": - version "18.2.23" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.23.tgz#112338760f622a16d64271b408355f2f27f6302c" - integrity sha512-ZQ71wgGOTmDYpnav2knkjr3qXdAFu0vsk8Ci5w3pGAIdj7/kKAyn+VsQDhXsmzzzepAiI9leWMmubXz690AI/A== - dependencies: - "@types/react" "*" - -"@types/react-slider@^1.3.6": - version "1.3.6" - resolved "https://registry.yarnpkg.com/@types/react-slider/-/react-slider-1.3.6.tgz#6f5602be93ab1cb3d273428c87aa227ad2ff68ff" - integrity sha512-RS8XN5O159YQ6tu3tGZIQz1/9StMLTg/FCIPxwqh2gwVixJnlfIodtVx+fpXVMZHe7A58lAX1Q4XTgAGOQaCQg== - dependencies: - "@types/react" "*" - -"@types/react-transition-group@^4.4.6": - version "4.4.10" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac" - integrity sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q== - dependencies: - "@types/react" "*" - -"@types/react@*", "@types/react@>=16.9.11", "@types/react@^18.2.67": - version "18.2.73" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.73.tgz#0579548ad122660d99e00499d22e33b81e73ed94" - integrity sha512-XcGdod0Jjv84HOC7N5ziY3x+qL0AfmubvKOZ9hJjJ2yd5EE+KYjWhdOjt387e9HPheHkdggF9atTifMRtyAaRA== - dependencies: - "@types/prop-types" "*" - csstype "^3.0.2" +"@types/pako@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/pako/-/pako-2.0.3.tgz#b6993334f3af27c158f3fe0dfeeba987c578afb1" + integrity sha512-bq0hMV9opAcrmE0Byyo0fY3Ew4tgOevJmQ9grUhpXQhYfyLJ1Kqg3P33JT5fdbT2AjeAjR51zqqVjAL/HMkx7Q== "@types/semver@^7.5.0": version "7.5.8" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== -"@types/warning@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.3.tgz#d1884c8cc4a426d1ac117ca2611bf333834c6798" - integrity sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q== - -"@typescript-eslint/eslint-plugin@^7.3.1": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz#1dc52fe48454d5b54be2d5f089680452f1628a5a" - integrity sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ== +"@typescript-eslint/eslint-plugin@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.1.tgz#dd71fc5c7ecec745ca26ece506d84d203a205c0e" + integrity sha512-zioDz623d0RHNhvx0eesUmGfIjzrk18nSBC8xewepKXbBvN/7c1qImV7Hg8TI1URTxKax7/zxfxj3Uph8Chcuw== dependencies: "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "7.5.0" - "@typescript-eslint/type-utils" "7.5.0" - "@typescript-eslint/utils" "7.5.0" - "@typescript-eslint/visitor-keys" "7.5.0" + "@typescript-eslint/scope-manager" "7.1.1" + "@typescript-eslint/type-utils" "7.1.1" + "@typescript-eslint/utils" "7.1.1" + "@typescript-eslint/visitor-keys" "7.1.1" debug "^4.3.4" graphemer "^1.4.0" ignore "^5.2.4" @@ -684,47 +338,47 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/parser@^7.3.1": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.5.0.tgz#1eeff36309ac2253c905dd4a88b4b71b72a358ed" - integrity sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ== +"@typescript-eslint/parser@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.1.1.tgz#6a9d0a5c9ccdf5dbd3cb8c949728c64e24e07d1f" + integrity sha512-ZWUFyL0z04R1nAEgr9e79YtV5LbafdOtN7yapNbn1ansMyaegl2D4bL7vHoJ4HPSc4CaLwuCVas8CVuneKzplQ== dependencies: - "@typescript-eslint/scope-manager" "7.5.0" - "@typescript-eslint/types" "7.5.0" - "@typescript-eslint/typescript-estree" "7.5.0" - "@typescript-eslint/visitor-keys" "7.5.0" + "@typescript-eslint/scope-manager" "7.1.1" + "@typescript-eslint/types" "7.1.1" + "@typescript-eslint/typescript-estree" "7.1.1" + "@typescript-eslint/visitor-keys" "7.1.1" debug "^4.3.4" -"@typescript-eslint/scope-manager@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz#70f0a7361430ab1043a5f97386da2a0d8b2f4d56" - integrity sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA== +"@typescript-eslint/scope-manager@7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.1.1.tgz#9e301803ff8e21a74f50c6f89a4baccad9a48f93" + integrity sha512-cirZpA8bJMRb4WZ+rO6+mnOJrGFDd38WoXCEI57+CYBqta8Yc8aJym2i7vyqLL1vVYljgw0X27axkUXz32T8TA== dependencies: - "@typescript-eslint/types" "7.5.0" - "@typescript-eslint/visitor-keys" "7.5.0" + "@typescript-eslint/types" "7.1.1" + "@typescript-eslint/visitor-keys" "7.1.1" -"@typescript-eslint/type-utils@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz#a8faa403232da3a3901655387c7082111f692cf9" - integrity sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw== +"@typescript-eslint/type-utils@7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.1.1.tgz#aee820d5bedd39b83c18585a526cc520ddb7a226" + integrity sha512-5r4RKze6XHEEhlZnJtR3GYeCh1IueUHdbrukV2KSlLXaTjuSfeVF8mZUVPLovidCuZfbVjfhi4c0DNSa/Rdg5g== dependencies: - "@typescript-eslint/typescript-estree" "7.5.0" - "@typescript-eslint/utils" "7.5.0" + "@typescript-eslint/typescript-estree" "7.1.1" + "@typescript-eslint/utils" "7.1.1" debug "^4.3.4" ts-api-utils "^1.0.1" -"@typescript-eslint/types@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.5.0.tgz#0a284bcdef3cb850ec9fd57992df9f29d6bde1bc" - integrity sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg== +"@typescript-eslint/types@7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.1.1.tgz#ca33ba7cf58224fb46a84fea62593c2c53cd795f" + integrity sha512-KhewzrlRMrgeKm1U9bh2z5aoL4s7K3tK5DwHDn8MHv0yQfWFz/0ZR6trrIHHa5CsF83j/GgHqzdbzCXJ3crx0Q== -"@typescript-eslint/typescript-estree@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz#aa5031c511874420f6b5edd90f8e4021525ee776" - integrity sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ== +"@typescript-eslint/typescript-estree@7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.1.tgz#09c54af0151a1b05d0875c0fc7fe2ec7a2476ece" + integrity sha512-9ZOncVSfr+sMXVxxca2OJOPagRwT0u/UHikM2Rd6L/aB+kL/QAuTnsv6MeXtjzCJYb8PzrXarypSGIPx3Jemxw== dependencies: - "@typescript-eslint/types" "7.5.0" - "@typescript-eslint/visitor-keys" "7.5.0" + "@typescript-eslint/types" "7.1.1" + "@typescript-eslint/visitor-keys" "7.1.1" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -732,25 +386,25 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.5.0.tgz#bbd963647fbbe9ffea033f42c0fb7e89bb19c858" - integrity sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw== +"@typescript-eslint/utils@7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.1.1.tgz#bdeeb789eee4af5d3fb5400a69566d4dbf97ff3b" + integrity sha512-thOXM89xA03xAE0lW7alstvnyoBUbBX38YtY+zAUcpRPcq9EIhXPuJ0YTv948MbzmKh6e1AUszn5cBFK49Umqg== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "7.5.0" - "@typescript-eslint/types" "7.5.0" - "@typescript-eslint/typescript-estree" "7.5.0" + "@typescript-eslint/scope-manager" "7.1.1" + "@typescript-eslint/types" "7.1.1" + "@typescript-eslint/typescript-estree" "7.1.1" semver "^7.5.4" -"@typescript-eslint/visitor-keys@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz#8abcac66f93ef20b093e87a400c2d21e3a6d55ee" - integrity sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA== +"@typescript-eslint/visitor-keys@7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.1.tgz#e6538a58c9b157f03bcbb29e3b6a92fe39a6ab0d" + integrity sha512-yTdHDQxY7cSoCcAtiBzVzxleJhkGB9NncSIyMYe2+OGON1ZsP9zOPws/Pqgopa65jvknOjlk/w7ulPlZ78PiLQ== dependencies: - "@typescript-eslint/types" "7.5.0" + "@typescript-eslint/types" "7.1.1" eslint-visitor-keys "^3.4.1" "@ungap/structured-clone@^1.2.0": @@ -758,16 +412,15 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@vitejs/plugin-react@^4.2.1": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz#744d8e4fcb120fc3dbaa471dadd3483f5a304bb9" - integrity sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ== - dependencies: - "@babel/core" "^7.23.5" - "@babel/plugin-transform-react-jsx-self" "^7.23.3" - "@babel/plugin-transform-react-jsx-source" "^7.23.3" - "@types/babel__core" "^7.20.5" - react-refresh "^0.14.0" +"@webgpu/types@^0.1.40": + version "0.1.40" + resolved "https://registry.yarnpkg.com/@webgpu/types/-/types-0.1.40.tgz#cf72d1df6f9f8adc5d39556041f20ff2e8a58885" + integrity sha512-/BBkHLS6/eQjyWhY2H7Dx5DHcVrS2ICj9owvSRdgtQT6KcafLZA86tPze0xAOsd4FbsYKCUBUQyNi87q7gV7kw== + +"@xmldom/xmldom@^0.8.10": + version "0.8.10" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" + integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== acorn-jsx@^5.3.2: version "5.3.2" @@ -794,13 +447,6 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -808,164 +454,21 @@ ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== - dependencies: - dequal "^2.0.3" - -array-buffer-byte-length@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" - integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== - dependencies: - call-bind "^1.0.5" - is-array-buffer "^3.0.4" - -array-includes@^3.1.6, array-includes@^3.1.7: - version "3.1.8" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" - integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - get-intrinsic "^1.2.4" - is-string "^1.0.7" - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.findlast@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz#3e4fbcb30a15a7f5bf64cf2faae22d139c2e4904" - integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - es-shim-unscopables "^1.0.2" - -array.prototype.findlastindex@^1.2.3: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz#8c35a755c72908719453f87145ca011e39334d0d" - integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - es-shim-unscopables "^1.0.2" - -array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.flatmap@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.toreversed@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz#b989a6bf35c4c5051e1dc0325151bf8088954eba" - integrity sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.tosorted@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz#c8c89348337e51b8a3c48a9227f9ce93ceedcba8" - integrity sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg== - dependencies: - call-bind "^1.0.5" - define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.1.0" - es-shim-unscopables "^1.0.2" - -arraybuffer.prototype.slice@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz#097972f4255e41bc3425e37dc3f6421cf9aefde6" - integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== - dependencies: - array-buffer-byte-length "^1.0.1" - call-bind "^1.0.5" - define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.2.1" - get-intrinsic "^1.2.3" - is-array-buffer "^3.0.4" - is-shared-array-buffer "^1.0.2" - -ast-types-flow@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" - integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== - -available-typed-arrays@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" - integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== - dependencies: - possible-typed-array-names "^1.0.0" - -axe-core@=4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" - integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== - -axobject-query@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" - integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== - dependencies: - dequal "^2.0.3" - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -binary-extensions@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" - integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -981,53 +484,18 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.2, braces@~3.0.2: +braces@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" -browserslist@^4.22.2: - version "4.23.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" - integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== - dependencies: - caniuse-lite "^1.0.30001587" - electron-to-chromium "^1.4.668" - node-releases "^2.0.14" - update-browserslist-db "^1.0.13" - -call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" - integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - set-function-length "^1.2.1" - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -caniuse-lite@^1.0.30001587: - version "1.0.30001603" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001603.tgz#605046a5bdc95ba4a92496d67e062522dce43381" - integrity sha512-iL2iSS0eDILMb9n5yKQoTBim9jMZ0Yrk8g0N9K7UzYyWnfIKzXBZD5ngpM37ZcL/cv0Mli8XtVMRYMQAfFpi5Q== - -chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - chalk@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -1036,33 +504,6 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -"chokidar@>=3.0.0 <4.0.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" - integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -classnames@^2.3.2: - version "2.5.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" - integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -1070,11 +511,6 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -1085,11 +521,6 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== - cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -1099,58 +530,7 @@ cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" -csstype@^3.0.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" - integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== - -damerau-levenshtein@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== - -data-view-buffer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2" - integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== - dependencies: - call-bind "^1.0.6" - es-errors "^1.3.0" - is-data-view "^1.0.1" - -data-view-byte-length@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz#90721ca95ff280677eb793749fce1011347669e2" - integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== - dependencies: - call-bind "^1.0.7" - es-errors "^1.3.0" - is-data-view "^1.0.1" - -data-view-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz#5e0bbfb4828ed2d1b9b400cd8a7d119bca0ff18a" - integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== - dependencies: - call-bind "^1.0.6" - es-errors "^1.3.0" - is-data-view "^1.0.1" - -debug@^2.6.6: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: +debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1162,29 +542,6 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -define-data-property@^1.0.1, define-data-property@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" - integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - gopd "^1.0.1" - -define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -dequal@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" - integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== - dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -1192,13 +549,6 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -1206,274 +556,45 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-helpers@^5.0.1, dom-helpers@^5.2.0, dom-helpers@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" - integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== - dependencies: - "@babel/runtime" "^7.8.7" - csstype "^3.0.2" +earcut@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.4.tgz#6d02fd4d68160c114825d06890a92ecaae60343a" + integrity sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ== -electron-to-chromium@^1.4.668: - version "1.4.723" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.723.tgz#827da30c96b316684d352c3d81430029df01bb8e" - integrity sha512-rxFVtrMGMFROr4qqU6n95rUi9IlfIm+lIAt+hOToy/9r6CDv0XiEcQdC3VP71y1pE5CFTzKV0RvxOGYCPWWHPw== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2: - version "1.23.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" - integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== - dependencies: - array-buffer-byte-length "^1.0.1" - arraybuffer.prototype.slice "^1.0.3" - available-typed-arrays "^1.0.7" - call-bind "^1.0.7" - data-view-buffer "^1.0.1" - data-view-byte-length "^1.0.1" - data-view-byte-offset "^1.0.0" - es-define-property "^1.0.0" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - es-set-tostringtag "^2.0.3" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.6" - get-intrinsic "^1.2.4" - get-symbol-description "^1.0.2" - globalthis "^1.0.3" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - has-proto "^1.0.3" - has-symbols "^1.0.3" - hasown "^2.0.2" - internal-slot "^1.0.7" - is-array-buffer "^3.0.4" - is-callable "^1.2.7" - is-data-view "^1.0.1" - is-negative-zero "^2.0.3" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.3" - is-string "^1.0.7" - is-typed-array "^1.1.13" - is-weakref "^1.0.2" - object-inspect "^1.13.1" - object-keys "^1.1.1" - object.assign "^4.1.5" - regexp.prototype.flags "^1.5.2" - safe-array-concat "^1.1.2" - safe-regex-test "^1.0.3" - string.prototype.trim "^1.2.9" - string.prototype.trimend "^1.0.8" - string.prototype.trimstart "^1.0.8" - typed-array-buffer "^1.0.2" - typed-array-byte-length "^1.0.1" - typed-array-byte-offset "^1.0.2" - typed-array-length "^1.0.6" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.15" - -es-define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" - integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== - dependencies: - get-intrinsic "^1.2.4" - -es-errors@^1.1.0, es-errors@^1.2.1, es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - -es-iterator-helpers@^1.0.15, es-iterator-helpers@^1.0.17: - version "1.0.18" - resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz#4d3424f46b24df38d064af6fbbc89274e29ea69d" - integrity sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.0" - es-errors "^1.3.0" - es-set-tostringtag "^2.0.3" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - globalthis "^1.0.3" - has-property-descriptors "^1.0.2" - has-proto "^1.0.3" - has-symbols "^1.0.3" - internal-slot "^1.0.7" - iterator.prototype "^1.1.2" - safe-array-concat "^1.1.2" - -es-object-atoms@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941" - integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== - dependencies: - es-errors "^1.3.0" - -es-set-tostringtag@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" - integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== - dependencies: - get-intrinsic "^1.2.4" - has-tostringtag "^1.0.2" - hasown "^2.0.1" - -es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" - integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== - dependencies: - hasown "^2.0.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -esbuild@^0.20.1: - version "0.20.2" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1" - integrity sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g== +esbuild@^0.19.3: + version "0.19.12" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.12.tgz#dc82ee5dc79e82f5a5c3b4323a2a641827db3e04" + integrity sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg== optionalDependencies: - "@esbuild/aix-ppc64" "0.20.2" - "@esbuild/android-arm" "0.20.2" - "@esbuild/android-arm64" "0.20.2" - "@esbuild/android-x64" "0.20.2" - "@esbuild/darwin-arm64" "0.20.2" - "@esbuild/darwin-x64" "0.20.2" - "@esbuild/freebsd-arm64" "0.20.2" - "@esbuild/freebsd-x64" "0.20.2" - "@esbuild/linux-arm" "0.20.2" - "@esbuild/linux-arm64" "0.20.2" - "@esbuild/linux-ia32" "0.20.2" - "@esbuild/linux-loong64" "0.20.2" - "@esbuild/linux-mips64el" "0.20.2" - "@esbuild/linux-ppc64" "0.20.2" - "@esbuild/linux-riscv64" "0.20.2" - "@esbuild/linux-s390x" "0.20.2" - "@esbuild/linux-x64" "0.20.2" - "@esbuild/netbsd-x64" "0.20.2" - "@esbuild/openbsd-x64" "0.20.2" - "@esbuild/sunos-x64" "0.20.2" - "@esbuild/win32-arm64" "0.20.2" - "@esbuild/win32-ia32" "0.20.2" - "@esbuild/win32-x64" "0.20.2" - -escalade@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" - integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + "@esbuild/aix-ppc64" "0.19.12" + "@esbuild/android-arm" "0.19.12" + "@esbuild/android-arm64" "0.19.12" + "@esbuild/android-x64" "0.19.12" + "@esbuild/darwin-arm64" "0.19.12" + "@esbuild/darwin-x64" "0.19.12" + "@esbuild/freebsd-arm64" "0.19.12" + "@esbuild/freebsd-x64" "0.19.12" + "@esbuild/linux-arm" "0.19.12" + "@esbuild/linux-arm64" "0.19.12" + "@esbuild/linux-ia32" "0.19.12" + "@esbuild/linux-loong64" "0.19.12" + "@esbuild/linux-mips64el" "0.19.12" + "@esbuild/linux-ppc64" "0.19.12" + "@esbuild/linux-riscv64" "0.19.12" + "@esbuild/linux-s390x" "0.19.12" + "@esbuild/linux-x64" "0.19.12" + "@esbuild/netbsd-x64" "0.19.12" + "@esbuild/openbsd-x64" "0.19.12" + "@esbuild/sunos-x64" "0.19.12" + "@esbuild/win32-arm64" "0.19.12" + "@esbuild/win32-ia32" "0.19.12" + "@esbuild/win32-x64" "0.19.12" escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-import-resolver-node@^0.3.9: - version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" - integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== - dependencies: - debug "^3.2.7" - is-core-module "^2.13.0" - resolve "^1.22.4" - -eslint-module-utils@^2.8.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz#52f2404300c3bd33deece9d7372fb337cc1d7c34" - integrity sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q== - dependencies: - debug "^3.2.7" - -eslint-plugin-import@^2.29.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" - integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== - dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" - semver "^6.3.1" - tsconfig-paths "^3.15.0" - -eslint-plugin-jsx-a11y@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz#2fa9c701d44fcd722b7c771ec322432857fcbad2" - integrity sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA== - dependencies: - "@babel/runtime" "^7.23.2" - aria-query "^5.3.0" - array-includes "^3.1.7" - array.prototype.flatmap "^1.3.2" - ast-types-flow "^0.0.8" - axe-core "=4.7.0" - axobject-query "^3.2.1" - damerau-levenshtein "^1.0.8" - emoji-regex "^9.2.2" - es-iterator-helpers "^1.0.15" - hasown "^2.0.0" - jsx-ast-utils "^3.3.5" - language-tags "^1.0.9" - minimatch "^3.1.2" - object.entries "^1.1.7" - object.fromentries "^2.0.7" - -eslint-plugin-react-hooks@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" - integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== - -eslint-plugin-react@^7.34.1: - version "7.34.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz#6806b70c97796f5bbfb235a5d3379ece5f4da997" - integrity sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw== - dependencies: - array-includes "^3.1.7" - array.prototype.findlast "^1.2.4" - array.prototype.flatmap "^1.3.2" - array.prototype.toreversed "^1.1.2" - array.prototype.tosorted "^1.1.3" - doctrine "^2.1.0" - es-iterator-helpers "^1.0.17" - estraverse "^5.3.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.1.2" - object.entries "^1.1.7" - object.fromentries "^2.0.7" - object.hasown "^1.1.3" - object.values "^1.1.7" - prop-types "^15.8.1" - resolve "^2.0.0-next.5" - semver "^6.3.1" - string.prototype.matchall "^4.0.10" - eslint-scope@^7.2.2: version "7.2.2" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" @@ -1554,17 +675,27 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: +estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -fast-deep-equal@3.1.3, fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -1633,13 +764,6 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1655,47 +779,7 @@ function-bind@^1.1.2: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" - integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - functions-have-names "^1.2.3" - -functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" - integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -get-symbol-description@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" - integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== - dependencies: - call-bind "^1.0.5" - es-errors "^1.3.0" - get-intrinsic "^1.2.4" - -glob-parent@^5.1.2, glob-parent@~5.1.2: +glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -1721,11 +805,6 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - globals@^13.19.0: version "13.24.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" @@ -1733,13 +812,6 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" -globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -1752,74 +824,33 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - graphemer@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" - integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== - dependencies: - es-define-property "^1.0.0" - -has-proto@^1.0.1, has-proto@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" - integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" - integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== - dependencies: - has-symbols "^1.0.3" - -hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: +hasown@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: function-bind "^1.1.2" +howler@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/howler/-/howler-2.2.4.tgz#bd3df4a4f68a0118a51e4bd84a2bfc2e93e6e5a1" + integrity sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w== + ignore@^5.2.0, ignore@^5.2.4: version "5.3.1" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== -immutable@^4.0.0: - version "4.3.5" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0" - integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw== - import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -1846,128 +877,25 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -internal-slot@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" - integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== - dependencies: - es-errors "^1.3.0" - hasown "^2.0.0" - side-channel "^1.0.4" - -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -is-array-buffer@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" - integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - -is-async-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" - integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== - dependencies: - has-tostringtag "^1.0.0" - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-core-module@^2.13.0, is-core-module@^2.13.1: +is-core-module@^2.13.0: version "2.13.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: hasown "^2.0.0" -is-data-view@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.1.tgz#4b4d3a511b70f3dc26d42c03ca9ca515d847759f" - integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== - dependencies: - is-typed-array "^1.1.13" - -is-date-object@^1.0.1, is-date-object@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-finalizationregistry@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" - integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== - dependencies: - call-bind "^1.0.2" - -is-generator-function@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" -is-map@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" - integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== - -is-negative-zero@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" - integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -1978,92 +906,15 @@ is-path-inside@^3.0.3: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-set@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" - integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== - -is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" - integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== - dependencies: - call-bind "^1.0.7" - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.13: - version "1.1.13" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" - integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== - dependencies: - which-typed-array "^1.1.14" - -is-weakmap@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" - integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-weakset@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.3.tgz#e801519df8c0c43e12ff2834eead84ec9e624007" - integrity sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ== - dependencies: - call-bind "^1.0.7" - get-intrinsic "^1.2.4" - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -iterator.prototype@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" - integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== - dependencies: - define-properties "^1.2.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - reflect.getprototypeof "^1.0.4" - set-function-name "^2.0.1" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +ismobilejs@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ismobilejs/-/ismobilejs-1.1.1.tgz#c56ca0ae8e52b24ca0f22ba5ef3215a2ddbbaa0e" + integrity sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw== js-yaml@^4.1.0: version "4.1.0" @@ -2072,11 +923,6 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -2092,28 +938,6 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json5@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -json5@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: - version "3.3.5" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" - integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== - dependencies: - array-includes "^3.1.6" - array.prototype.flat "^1.3.1" - object.assign "^4.1.4" - object.values "^1.1.6" - keyv@^4.5.3: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -2121,18 +945,6 @@ keyv@^4.5.3: dependencies: json-buffer "3.0.1" -language-subtag-registry@^0.3.20: - version "0.3.22" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== - -language-tags@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" - integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== - dependencies: - language-subtag-registry "^0.3.20" - levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -2141,11 +953,6 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -load-script@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/load-script/-/load-script-1.0.0.tgz#0491939e0bee5643ee494a7e3da3d2bac70c6ca4" - integrity sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA== - locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -2158,20 +965,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -2206,26 +999,11 @@ minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" @@ -2236,87 +1014,6 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -node-releases@^2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" - integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.4, object.assign@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" - integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== - dependencies: - call-bind "^1.0.5" - define-properties "^1.2.1" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.entries@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.8.tgz#bffe6f282e01f4d17807204a24f8edd823599c41" - integrity sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - -object.fromentries@^2.0.7: - version "2.0.8" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" - integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - -object.groupby@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" - integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - -object.hasown@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.4.tgz#e270ae377e4c120cdcb7656ce66884a6218283dc" - integrity sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg== - dependencies: - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - -object.values@^1.1.6, object.values@^1.1.7: - version "1.2.0" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b" - integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -2350,6 +1047,11 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +pako@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -2357,6 +1059,11 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-svg-path@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/parse-svg-path/-/parse-svg-path-0.1.2.tgz#7a7ec0d1eb06fa5325c7d3e009b859a09b5d49eb" + integrity sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -2387,56 +1094,45 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: +picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -possible-typed-array-names@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" - integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== +pixi-filters@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/pixi-filters/-/pixi-filters-6.0.0.tgz#36f480f87b8f66b259db40acb7a6b134e570c473" + integrity sha512-9wJn4bfQKak+lefyk9BSCenhMBvGQi2t4Uz+BVqw6WK8wM2NgqeTC64mhXRtrdYeCG9gIFX0Lc6q1S8rBqwJbg== -postcss@^8.4.38: - version "8.4.38" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" - integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== +pixi.js@^8.0.4, pixi.js@~8.0.4: + version "8.0.4" + resolved "https://registry.yarnpkg.com/pixi.js/-/pixi.js-8.0.4.tgz#77449a82354d29fb39c78c3ca23602bf6082e136" + integrity sha512-UAa3WU5FV4kjwjYosbG3pi1QvTBKSLPH7BOLkw5X4g12+Xxew3YwMiM+V1EQL4/65hDn5Z3jhFC3xVAsHFJcsQ== + dependencies: + "@pixi/colord" "^2.9.6" + "@types/css-font-loading-module" "^0.0.12" + "@types/earcut" "^2.1.4" + "@webgpu/types" "^0.1.40" + "@xmldom/xmldom" "^0.8.10" + earcut "^2.2.4" + eventemitter3 "^5.0.1" + ismobilejs "^1.1.1" + parse-svg-path "^0.1.2" + +postcss@^8.4.35: + version "8.4.35" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.35.tgz#60997775689ce09011edf083a549cea44aabe2f7" + integrity sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA== dependencies: nanoid "^3.3.7" picocolors "^1.0.0" - source-map-js "^1.2.0" + source-map-js "^1.0.2" prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prop-types-extra@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" - integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== - dependencies: - react-is "^16.3.2" - warning "^4.0.0" - -prop-types@15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - -prop-types@^15.6.2, prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - punycode@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -2447,126 +1143,12 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -react-bootstrap@^2.2.2: - version "2.10.2" - resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-2.10.2.tgz#3b609eb0170e31b3d9ace297d3a016c202a42642" - integrity sha512-UvB7mRqQjivdZNxJNEA2yOQRB7L9N43nBnKc33K47+cH90/ujmnMwatTCwQLu83gLhrzAl8fsa6Lqig/KLghaA== - dependencies: - "@babel/runtime" "^7.22.5" - "@restart/hooks" "^0.4.9" - "@restart/ui" "^1.6.8" - "@types/react-transition-group" "^4.4.6" - classnames "^2.3.2" - dom-helpers "^5.2.1" - invariant "^2.2.4" - prop-types "^15.8.1" - prop-types-extra "^1.1.0" - react-transition-group "^4.4.5" - uncontrollable "^7.2.1" - warning "^4.0.3" - -react-dom@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.0" - -react-icons@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.0.1.tgz#1694e11bfa2a2888cab47dcc30154ce90485feee" - integrity sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw== - -react-is@^16.13.1, react-is@^16.3.2, react-is@^16.8.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - -react-refresh@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" - integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== - -react-slider@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/react-slider/-/react-slider-2.0.6.tgz#8c7ff0301211f7c3ff32aa0163b33bdab6258559" - integrity sha512-gJxG1HwmuMTJ+oWIRCmVWvgwotNCbByTwRkFZC6U4MBsHqJBmxwbYRJUmxy4Tke1ef8r9jfXjgkmY/uHOCEvbA== - dependencies: - prop-types "^15.8.1" - -react-transition-group@^4.4.5: - version "4.4.5" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" - integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== - dependencies: - "@babel/runtime" "^7.5.5" - dom-helpers "^5.0.1" - loose-envify "^1.4.0" - prop-types "^15.6.2" - -react-youtube@^7.13.1: - version "7.14.0" - resolved "https://registry.yarnpkg.com/react-youtube/-/react-youtube-7.14.0.tgz#0505d86491521ca94ef0afb74af3f7936dc7bc86" - integrity sha512-SUHZ4F4pd1EHmQu0CV0KSQvAs5KHOT5cfYaq4WLCcDbU8fBo1ouTXaAOIASWbrz8fHwg+G1evfoSIYpV2AwSAg== - dependencies: - fast-deep-equal "3.1.3" - prop-types "15.7.2" - youtube-player "5.5.2" - -react@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== - dependencies: - loose-envify "^1.1.0" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -reflect.getprototypeof@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz#3ab04c32a8390b770712b7a8633972702d278859" - integrity sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.1" - es-errors "^1.3.0" - get-intrinsic "^1.2.4" - globalthis "^1.0.3" - which-builtin-type "^1.1.3" - -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -regexp.prototype.flags@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" - integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== - dependencies: - call-bind "^1.0.6" - define-properties "^1.2.1" - es-errors "^1.3.0" - set-function-name "^2.0.1" - resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.22.4: +resolve@^1.22.1: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -2575,15 +1157,6 @@ resolve@^1.22.4: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^2.0.0-next.5: - version "2.0.0-next.5" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" - integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -2596,28 +1169,26 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rollup@^4.13.0: - version "4.13.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.13.2.tgz#ac57d2dc48e8f5562f5a6daadb9caee590069262" - integrity sha512-MIlLgsdMprDBXC+4hsPgzWUasLO9CE4zOkj/u6j+Z6j5A4zRY+CtiXAdJyPtgCsc42g658Aeh1DlrdVEJhsL2g== +rollup@^4.2.0: + version "4.12.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.12.1.tgz#0659cb02551cde4c5b210e9bd3af050b5b5b415d" + integrity sha512-ggqQKvx/PsB0FaWXhIvVkSWh7a/PCLQAsMjBc+nA2M8Rv2/HG0X6zvixAB7KyZBRtifBUhy5k8voQX/mRnABPg== dependencies: "@types/estree" "1.0.5" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.13.2" - "@rollup/rollup-android-arm64" "4.13.2" - "@rollup/rollup-darwin-arm64" "4.13.2" - "@rollup/rollup-darwin-x64" "4.13.2" - "@rollup/rollup-linux-arm-gnueabihf" "4.13.2" - "@rollup/rollup-linux-arm64-gnu" "4.13.2" - "@rollup/rollup-linux-arm64-musl" "4.13.2" - "@rollup/rollup-linux-powerpc64le-gnu" "4.13.2" - "@rollup/rollup-linux-riscv64-gnu" "4.13.2" - "@rollup/rollup-linux-s390x-gnu" "4.13.2" - "@rollup/rollup-linux-x64-gnu" "4.13.2" - "@rollup/rollup-linux-x64-musl" "4.13.2" - "@rollup/rollup-win32-arm64-msvc" "4.13.2" - "@rollup/rollup-win32-ia32-msvc" "4.13.2" - "@rollup/rollup-win32-x64-msvc" "4.13.2" + "@rollup/rollup-android-arm-eabi" "4.12.1" + "@rollup/rollup-android-arm64" "4.12.1" + "@rollup/rollup-darwin-arm64" "4.12.1" + "@rollup/rollup-darwin-x64" "4.12.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.12.1" + "@rollup/rollup-linux-arm64-gnu" "4.12.1" + "@rollup/rollup-linux-arm64-musl" "4.12.1" + "@rollup/rollup-linux-riscv64-gnu" "4.12.1" + "@rollup/rollup-linux-x64-gnu" "4.12.1" + "@rollup/rollup-linux-x64-musl" "4.12.1" + "@rollup/rollup-win32-arm64-msvc" "4.12.1" + "@rollup/rollup-win32-ia32-msvc" "4.12.1" + "@rollup/rollup-win32-x64-msvc" "4.12.1" fsevents "~2.3.2" run-parallel@^1.1.9: @@ -2627,46 +1198,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-array-concat@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb" - integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== - dependencies: - call-bind "^1.0.7" - get-intrinsic "^1.2.4" - has-symbols "^1.0.3" - isarray "^2.0.5" - -safe-regex-test@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" - integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== - dependencies: - call-bind "^1.0.6" - es-errors "^1.3.0" - is-regex "^1.1.4" - -sass@^1.72.0: - version "1.72.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.72.0.tgz#5b9978943fcfb32b25a6a5acb102fc9dabbbf41c" - integrity sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA== - dependencies: - chokidar ">=3.0.0 <4.0.0" - immutable "^4.0.0" - source-map-js ">=0.6.2 <2.0.0" - -scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== - dependencies: - loose-envify "^1.1.0" - -semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - semver@^7.5.4: version "7.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" @@ -2674,28 +1205,6 @@ semver@^7.5.4: dependencies: lru-cache "^6.0.0" -set-function-length@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" - integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - -set-function-name@^2.0.1, set-function-name@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" - integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - functions-have-names "^1.2.3" - has-property-descriptors "^1.0.2" - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -2708,76 +1217,15 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -side-channel@^1.0.4, side-channel@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" - integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== - dependencies: - call-bind "^1.0.7" - es-errors "^1.3.0" - get-intrinsic "^1.2.4" - object-inspect "^1.13.1" - -sister@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/sister/-/sister-3.0.2.tgz#bb3e39f07b1f75bbe1945f29a27ff1e5a2f26be4" - integrity sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA== - slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" - integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== - -string.prototype.matchall@^4.0.10: - version "4.0.11" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz#1092a72c59268d2abaad76582dccc687c0297e0a" - integrity sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - get-intrinsic "^1.2.4" - gopd "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.7" - regexp.prototype.flags "^1.5.2" - set-function-name "^2.0.2" - side-channel "^1.0.6" - -string.prototype.trim@^1.2.9: - version "1.2.9" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" - integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.0" - es-object-atoms "^1.0.0" - -string.prototype.trimend@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz#3651b8513719e8a9f48de7f2f77640b26652b229" - integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - -string.prototype.trimstart@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" - integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== strip-ansi@^6.0.1: version "6.0.1" @@ -2786,23 +1234,11 @@ strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -2820,11 +1256,6 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -2837,17 +1268,7 @@ ts-api-utils@^1.0.1: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== -tsconfig-paths@^3.15.0: - version "3.15.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" - integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@^2.4.0: +tslib@^2.3.1: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -2864,92 +1285,10 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -typed-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" - integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== - dependencies: - call-bind "^1.0.7" - es-errors "^1.3.0" - is-typed-array "^1.1.13" - -typed-array-byte-length@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67" - integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== - dependencies: - call-bind "^1.0.7" - for-each "^0.3.3" - gopd "^1.0.1" - has-proto "^1.0.3" - is-typed-array "^1.1.13" - -typed-array-byte-offset@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063" - integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== - dependencies: - available-typed-arrays "^1.0.7" - call-bind "^1.0.7" - for-each "^0.3.3" - gopd "^1.0.1" - has-proto "^1.0.3" - is-typed-array "^1.1.13" - -typed-array-length@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" - integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== - dependencies: - call-bind "^1.0.7" - for-each "^0.3.3" - gopd "^1.0.1" - has-proto "^1.0.3" - is-typed-array "^1.1.13" - possible-typed-array-names "^1.0.0" - -typescript@^5.4.2: - version "5.4.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.3.tgz#5c6fedd4c87bee01cd7a528a30145521f8e0feff" - integrity sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -uncontrollable@^7.2.1: - version "7.2.1" - resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-7.2.1.tgz#1fa70ba0c57a14d5f78905d533cf63916dc75738" - integrity sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ== - dependencies: - "@babel/runtime" "^7.6.3" - "@types/react" ">=16.9.11" - invariant "^2.2.4" - react-lifecycles-compat "^3.0.4" - -uncontrollable@^8.0.1: - version "8.0.4" - resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-8.0.4.tgz#a0a8307f638795162fafd0550f4a1efa0f8c5eb6" - integrity sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ== - -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== - -update-browserslist-db@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" - integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" +typescript@~5.4.2: + version "5.4.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" + integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== uri-js@^4.2.2: version "4.4.1" @@ -2958,79 +1297,17 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -use-between@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/use-between/-/use-between-1.3.5.tgz#8f9db513414d204e0046c5692828e209cec4d564" - integrity sha512-IP9eJfszZr0aah/6i/pzaM7n/QgMPwWKJ+mnWqT5O0qFhLnztPbkVC6L7zI6ygeBIMJHfmUGvsw0b28pyrEGSA== - -vite@^5.1.6: - version "5.2.7" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.7.tgz#e1b8a985eb54fcb9467d7f7f009d87485016df6e" - integrity sha512-k14PWOKLI6pMaSzAuGtT+Cf0YmIx12z9YGon39onaJNy8DLBfBJrzg9FQEmkAM5lpHBZs9wksWAsyF/HkpEwJA== +vite@^5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.5.tgz#bdbc2b15e8000d9cc5172f059201178f9c9de5fb" + integrity sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q== dependencies: - esbuild "^0.20.1" - postcss "^8.4.38" - rollup "^4.13.0" + esbuild "^0.19.3" + postcss "^8.4.35" + rollup "^4.2.0" optionalDependencies: fsevents "~2.3.3" -warning@^4.0.0, warning@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" - integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== - dependencies: - loose-envify "^1.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-builtin-type@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz#b1b8443707cc58b6e9bf98d32110ff0c2cbd029b" - integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== - dependencies: - function.prototype.name "^1.1.5" - has-tostringtag "^1.0.0" - is-async-function "^2.0.0" - is-date-object "^1.0.5" - is-finalizationregistry "^1.0.2" - is-generator-function "^1.0.10" - is-regex "^1.1.4" - is-weakref "^1.0.2" - isarray "^2.0.5" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" - -which-collection@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0" - integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== - dependencies: - is-map "^2.0.3" - is-set "^2.0.3" - is-weakmap "^2.0.2" - is-weakset "^2.0.3" - -which-typed-array@^1.1.14, which-typed-array@^1.1.15, which-typed-array@^1.1.9: - version "1.1.15" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" - integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== - dependencies: - available-typed-arrays "^1.0.7" - call-bind "^1.0.7" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.2" - which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -3043,11 +1320,6 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" @@ -3057,12 +1329,3 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -youtube-player@5.5.2: - version "5.5.2" - resolved "https://registry.yarnpkg.com/youtube-player/-/youtube-player-5.5.2.tgz#052b86b1eabe21ff331095ffffeae285fa7f7cb5" - integrity sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ== - dependencies: - debug "^2.6.6" - load-script "^1.0.0" - sister "^3.0.0"

=}Y{jUbKv|>{iBlCS#_r4Mx0C{4rZ{ zKTWDhsz@rgxHP)7>}}ax8LiE}%>X*7^rrQbDgzsN>*Z4FuW98rWjWWjthueRrRpWo zW!Ms5wDy}2`?FX|`%h+{ERkH8sZbF8~pmacHWRWNIob-&?N zmX@A|DK{!dl^brgD^+b5=e%v#Z?!)OWzgw05xpU5h)p6;J6tkOasvTBI zm3b9$=eOzwe)K8c$;kb16PIh|TRiuuef=-b6X`SbnfKq~Lqj?YWj&oRC6SK6snMk{ zvCSv)x~hE<#^$iUi%GP40;%18!i}KtF?5CPvjh`D!n=aL?exoE-HF`Hb zamKoEV4J$DKJBEmr#xwS^6X5LiavUZp`7 z@ZoRr%Z)4pSGsQJSZ9AR#ByMp?}zWl#K)S34M?SHNo8~Q%=Wdfm;@a9J1z!|9p+@$ zXLoLw5UY2Tc5d%P&%7Q~czq?;UjF{br#|EYYIRhb_I0X^*L+2YCDJk!+psPq?JAvY zS2t(HF4dpqxIs03K%J`4JNV_QQM86me*Qji|V&Lcu^8UQuU%fQFxooVgrE0aL ziK4hxnbaMPY2_A$7VRD>5BtG!Ob*8Qt|^bIlz5er&)pC6r`!9{OF2ul%fTEO(tVD8 zkMaqf2a(0>rBciiYH0|w7z>q`KXu^ZCF}{8_gDfiC(=CXGL)-db8PVwOsbBfBC)TG}YQ=!(Svn_tz~GFi&a3 zZerIw{vD`rkE}cI_K9zj=1Zme>{b7~g2G;srcw9pcl33!NpY$=th=4Z$D!DM)wJ^5 zt3%s^_5H->%CB}`leU>VnHOI)7DbubN%CUW+AHp;)@k@ZBGN3gQCy9(rL53+AJ-`E zJ#JaPZI@mZ(k>EY?iG5oqd%;p0phhqYeTad`DANma@)}oBW*w5;QTi#hg*v+Hm-`5 z$dS(W^qbhs!&UBR-~Nx8GcVtjmUlI~4SS4vY^=>m<~lH>m8GwxGx*R?O~0d`w|%#L z_*c;Dt;{FyMMu8n?!K0yCPEA5QUHaJfn`;6{z2e~wMHj4=YmcRiT^OZQqZt}WU`O`e0zE$>`MxEZ#W?*HRnl) z)SnqAVnJi@x+`J+4x{gG3p`+POrI3LuHL3jxUu&>V6Tq2%3}B4E~{GYmiK1Brp9^7 z7t7w(SFKr9%{RQ7cY@j*f<2BlxO0^Wvj^>uezB7##&cCQXWRFKe2==14(HitL+**5 z5e8bP0!4Q!+br8|9U!)KrjWDIkZh7X@7A0{y(DUvdi z2BPSrwsKXpR8^O>@11R&79)qyhG|A_)szX0NbDrJC`h4qE`FYI6c@y$m7$O?@0bkGl{ zyQYba<@|IMBSns%fZ$7K+PN2LPND7XUE0o zZM(uBCX0tb3vnu)^6WJD4n zECDlNjy|1nm^D9b)`T3;aYOw~R#_Of8CN$;1+_EP9xd!~ul?zZTIr)mT z2@K-2!p=(HBi;i|sABEHGe2@SXalve0hC{$#L~zGrxfdZr_!qhAHK({4&Egz@6gaL{!Dhs5Z z%f`k=u^D8bM$(uNVG%(RcgHvXEkpD@`+ENCsJNdVp~is=hBYTg*otivq*u8DIFijR zlbHP+D2IP4yXd{b^_rX}!71{r=#C*vWF-?qB0@em17kPAC5Wf3yNG}|$d^%opeSM* zN;_gG^Q`%}V?4=P*jjX8kUTNwL4%_yp*Rwr z<-gx&%?R#zx8n)TkQ$7*MxOA*>qcldH0(A7dkSom4Pz!80QbPvJI&~+fSs%dY>Q;j z{x!x37I@jrEw~Tj$7-mwAb>Gz!6I%3(=q4uQ3btzN)B-IPoK5%T2cRZs>b>jdR4kk GVgCo|iCsYe diff --git a/src/assets/images/navigator/models/model_z.png b/src/assets/images/navigator/models/model_z.png deleted file mode 100644 index 0809c916b96f7c368f60dfd69728c693aa3bf1db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4087 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 F;=e!=M=$^Y diff --git a/src/assets/images/navigator/thumbnail_placeholder.png b/src/assets/images/navigator/thumbnail_placeholder.png deleted file mode 100644 index be26f84767d2a6287b8ba3f23328b9ba6d4fbd6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1801 zcmV+k2ln`hP)g2qjnz!va1 zi&rtbrvN=&*+ZUjAtK!i%B6Cy$K4IJE>H1iLjd2d2}@+dIv`n_{;__5mLq z9WDO5^~@pDXaU{?yA`qz`0()11wv!A2Cs_U0yzZigB}9B8g@-&O9oq@TZ0#eu9eLe zV2p!HGVi z{l55N87a_bXJ@_OQ!aQ`R+m7w07LdtY|LgFfQ-=anhRY6JQ+I&IVOX7S0UA84h>NP zx-@t+bZR!o4060KYlGi?0$c+cBe#Y}XLT%cN*5v3WnV^1*fpR_44PG-t$T9Pj)#=p zp-#h?&4_JO5Br+}NwhlXqgrk#V9$)TMRUpbMW zHLz4@{+Sg#2(4vvs6=3!CY1%gD=jS}wRO^lfaP+bL!WD9$Oj&k)uC+0Rwz_cIT~N) z=JpF0A3u2^{yjIh|LM)+dx}Fs^R^KFJ<(a63vH>n0LX)`&*w@1OInr=ZNnr%hXz3o z9qJlx{sF7+K!F|x`%D)G^C6U)l{i$NZ1q==lkmUMS%8Zbu6@2 zlO=4r49{kY&r6Y%^(zIf^~;tvjsnuGrr5rky^r<}n{N<|3kz-C z8}yY9X@`T>U9B_W87sAZysn3!wN7CuXoqb%wxMOTY0v~Nem*NxED4?p|mi>Dn3{CU#Q+VNxlXWquq z8tlX7T?w{!2u*{7O){hD0VSzCz|+pRP&9bJY4_%eKho(~W+n;+-Ea>Icke*Nl?E)d*O zI!XNc;_(ySc1mD4$H5q zKKbj03+)&N1^)8i&s|)5u(SB!!JlSeTpp**%}p1jU}FyaSKDFnwR;Zv?~gj{^O=1f zmFDBheZ~$1mvP7l{rVNl$>uk2x>)SKB?iTY_xnFzTI~IFsRIUF zK&GgCBhjfecouZZ(YwQ~^*%Hk5PQ(e2my0!{uy8+Fh|v(W5GimO7uac+ynm<_~7BX z*jEGayWhRj0|qb%D>PjmKEM9-stb}qd5&sqfcO@K>*`E>8f9T($-raLE|(t*IfL5>H2(hTMAL%~6L220l{(%|4F zOGi;?c!h|m!BXI$XBi~Vl?iEm12PA<)bMO*(|H|Rq!vGtfh{#yD|C`(4^L2YX-x73drHQlA-;4rG#)`YnRgGOeOdM8(+tjh^UP9 ztna|JK~Bm3*cu)JF9I!{5P5#1No)~{TH5j+Ms8`^SZ z7XAZ{AHM=e^b}xPbHxp&Oi;6Px{8zx&c3KK=Q=~o@RO4h7nTgt2DK1a?)+TftZTw^ zE>Z3>{P_6QzzJQ703HGkEk8sJ9_97m6da%tedsw<~^0LoM1^ATMce@^Qzjn zW1|_4=$4XFt4*8yz3-$9xAfsHfhTo0$Jjx$74T&5Pbz`a3~vd%5_jC?B?Vqv0i~F00000NkvXXu0mjfBEV%1 diff --git a/src/assets/images/nitro/nitro-dark.svg b/src/assets/images/nitro/nitro-dark.svg deleted file mode 100644 index 20cc533..0000000 --- a/src/assets/images/nitro/nitro-dark.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/assets/images/nitro/nitro-light.svg b/src/assets/images/nitro/nitro-light.svg deleted file mode 100644 index 5706684..0000000 --- a/src/assets/images/nitro/nitro-light.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/assets/images/nitro/nitro-n-dark.svg b/src/assets/images/nitro/nitro-n-dark.svg deleted file mode 100644 index f8d0ebd..0000000 --- a/src/assets/images/nitro/nitro-n-dark.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/assets/images/nitro/nitro-n-light.svg b/src/assets/images/nitro/nitro-n-light.svg deleted file mode 100644 index 4dd94fc..0000000 --- a/src/assets/images/nitro/nitro-n-light.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/assets/images/notifications/frank.gif b/src/assets/images/notifications/frank.gif deleted file mode 100644 index 211634f74533f4dd21c474dbdbcde385ee3d675e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1204 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 V(Y~5D$Q0iQK%-ocOnY4Xe*yh$$o>ET diff --git a/src/assets/images/pets/pet-package/pterosaur_egg.png b/src/assets/images/pets/pet-package/pterosaur_egg.png deleted file mode 100644 index 43ee1418ab722ebea561ceb72fe7381d61408c7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1631 zcmb`H`#;kS6vsFBrZul}sYPy~+7MPtjc2oFr*+F(=c zyPnDkY5n_A>6=GaMju~$(adc~uruDh>%kih0Mdu57&dE`yTT)%xs}e-{th7*sRD3NrD`>E*9Ed*>d(H-6yGU!e zOdpG@DJNoB4lZOHGSxQyqC=UG5yrtEjz6^@9tdUgN#(Dy?9*Ju0PDc>%LI337epQ6ko zDpqF-4w8C5UjOy@k4A%|7W(X-Z%Yw28ZnnkVyA6wS4;ma8*@LqdvP(=OL@2?a2}W; z*JN=RembbYh_W#{+p^m*GE*2+4~ojsMKH~kim5~S|NNy=+1WT|pfO)D6QVkCDGht~ zPF}-GuuV3;=0WrDdVp#jc&=@P(VT!j#EtlQ${V2(UNgEuj5vZy_|si9J?DAP)raQQ zAbc>KHzzrC5cBrk0s*gI2hJkQEyGq-e|n&{u5tsAsy;d6V1m6JPUa`z?pP(xAi9Cvuqe%f!e~L`{W*TfE*t&29pW>NeX}V0CB+j2wn_%H zH}Ds4OJvDwVkKj?wO_U-PA+;S953?K6-C8&J)e3pd$E@zd1{?^3p%w@jH~=x6W#e_ zbja!ez*_Kxr(bVdI*I=R?A*L?l{5M3<=6+V8T1}vGO54UG`$;I%;j6oL?xi~Zde=xA2x+SD6zo%g&=xYfv|9rG}~x}qBosx?2dh@Pr{ ziPq+kk6C*^Ov39JWv@g0pXY2sZjCeTd1o6=tCo*-H90dp!;0DD<_%_I zJGzzpTuf&4ZG$B}#%-u)XyI{DI#8 z)kvUyd!p)|-T}?96wQY6<=hs_GeG@!<%uH0=bE3DzA}9@EGv=f!E^j2G8Qeh@y19O zk(m`ii8?2PWU?s$)y-HmqCBDl(G~?frM#Rs{BrS~?wY4DxF*&)i1jnTlM+wZlKk{` zhl2K}sQob!vj;BjE)-VACu`AO-DYij2m%mwO_62S*=3Mo<0I{gf~rLKn(*9Xk2f11 zotRhB*3?2`f#ls)#_rkc8BnbCfU-c6rBETr5c@YYL+DyP(~xiM;V^E8oOC%U(Iw-aY#8Ar4%!z@1x1^6>J<26862AFg(w@%{zE C?iq*x diff --git a/src/assets/images/pets/pet-package/val11_present.png b/src/assets/images/pets/pet-package/val11_present.png deleted file mode 100644 index 3d371b5b3747985100af5278106f3c87b5462982..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2720 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 N002ovPDHLkV1jkP!14e9 diff --git a/src/assets/images/prize/prize_background.png b/src/assets/images/prize/prize_background.png deleted file mode 100644 index ec9c0306536734ee07dc697eec63304e2c0721c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5861 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 diff --git a/src/assets/images/profile/icons/online.gif b/src/assets/images/profile/icons/online.gif deleted file mode 100644 index 3a79838bd329181393f7e91ac17fd74b09d95b8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 666 zcmZ?wbhEHb)L;-`*v!eWbLY;Ej*h6Ps8!)C|7S4#Kg)IZ?p+23hW}syWS{}X|J;7A zA;Hd$0j@@R2F#2=X~mx`tS1;a8FWBOLB=w$v>BY7$+Fktb?)~6(-rz;Guj#&*RTc5 zTQ)(e(z$}YlEhSXen9e`ppZNI&HUZ^7fmb zPDv{4xSvRWTlB~>(o7N|;QpAOSJI%{*tor+J_N}B## zg`fU@`eoVSMS&q6t$t^3cnUEhEaqTfXOIS4tY&c1bF~TQ^PDYz#kW@~bj;0&tW5V< z6|;I_)JMe)t#8WW-r2-!G9k1g+$>|@nUJ!|EbwsQyBIS@6@|D5l}jEe3Lcqxbdw0! zE>5r~5w5lbx|(rsg;et9`?IGrsx)+nXZW;VQF}Xkg*Nx`4K8nL<{h_~ccJ|=XS?}y zqrx`}XSA;PvU0N9%1Imu>k+Y;268ztHqY+ers!aP4N9 caD(Ig2>~yD|7BrzlBlV#Z*1=D5@fIj0HK@smH+?% diff --git a/src/assets/images/profile/icons/tick.png b/src/assets/images/profile/icons/tick.png deleted file mode 100644 index ec8c52fdf71f359dbd22ddeae746f2df2459e03f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^+(695!3HFgJ}hYlQXZZzjv*DddV3hT7!){;ynA1# z5TBDFkvNOD>BY7NwluLn36C0L9BT?L^2s{>Q52qPD)23$t1B*PLf1LbkR&miqY_&l cNrv2JDa>e9Jhg1gZJ?P9p00i_>zopr09Ai08UO$Q diff --git a/src/assets/images/room-spectator/room_spectator_bottom_left.png b/src/assets/images/room-spectator/room_spectator_bottom_left.png deleted file mode 100644 index 01688cb295d0e7551042935ed2f4f3109aba7c77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 461 zcmeAS@N?(olHy`uVBq!ia0vp^(LkKX!3HEf8uQy37#OE`x;TbZ+3@i2r9VQgauiG$dG6K)(p$WA zfY2Bh`DR&W!}Md@@<3wy)VA4A65X&CWQ=vv?%P1-Z-t!K>l$+JvL{BDv*tXQy0J0* zz`vT^e}D1qIkZXm7e__QUdHMjFTTv2bl|^g)l1_`?eCiX7uf6li@Oor9oJ>oET6bO z;!A|kFNuFXjMp`jwad;ey8ftN)Zk2$QJ-%1d*eyXv!fmS6kAWv^3yBpbiJ;zBqefl z>bp|6z5}+=k;Rd{wZ~lJRcD{)IKp&;bI)t5?sc8K+nLJ#&sj2=X`@0J)BDAzH>D)< zUrc>opOsRbaJWr(Ln1dY6j;r28hNF+9l*jrKR2IYH`k`;ayMgv(Zt~C>gTe~DWM4f DB_q~? diff --git a/src/assets/images/room-spectator/room_spectator_bottom_right.png b/src/assets/images/room-spectator/room_spectator_bottom_right.png deleted file mode 100644 index 59c8ef2c2daef66a18a2a2dd18dea786943ace29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 456 zcmeAS@N?(olHy`uVBq!ia0vp^(LkKX!3HEf8uQy37#RCKT^vIyZoR#}F}K-4qAhWj zM$oG-aSFNL5@mM1nb>(kq^Dpaw}2Ac=i(>SHX5VgvaN**K^72w3d4zy9obBEK)eM#_ zONxXXT>zn0*t_`Tt7^25Y8F+H{$gTe~ HDWM4fUf$6q diff --git a/src/assets/images/room-spectator/room_spectator_middle_bottom.png b/src/assets/images/room-spectator/room_spectator_middle_bottom.png deleted file mode 100644 index ba6fdecccebd3460ca5d32675b070dbddbbab852..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^j6kf$!3HE*_k3grQktGFjv*Ddk`odVew@E>@#4q% x2d9Xhh+3-L@3^P_|37=?h`YX(>l|Gf7`EN_?kMv1F9T{~@O1TaS?83{1OP^IAYK3f diff --git a/src/assets/images/room-spectator/room_spectator_middle_left.png b/src/assets/images/room-spectator/room_spectator_middle_left.png deleted file mode 100644 index 6d9aaa7958b41a907aacae0e1025f191f43c5418..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T(!3HF4{HDeLDOFDw$B>F!$vZU9f1NLJ=D>ju t|Ns8}{{Oe@jld0>+K2!5_3>@6VOaQ6#dBs-r7BPZgQu&X%Q~loCIAFlAkzQ< diff --git a/src/assets/images/room-spectator/room_spectator_middle_right.png b/src/assets/images/room-spectator/room_spectator_middle_right.png deleted file mode 100644 index 9d963b3d111202dc6ba066b300ee3e378186d025..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T(!3HF4{HDeLDOFDw$B>F!$q5MwKki?=`0@Uf tsSoS-b69iL{r~s3e!?H$O1(t}3}&7xo*jP_76LUec)I$ztaD0e0sy?l9^n80 diff --git a/src/assets/images/room-spectator/room_spectator_middle_top.png b/src/assets/images/room-spectator/room_spectator_middle_top.png deleted file mode 100644 index f6559cee0eb6b9c10edbe88989d77f6781520a82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{R!3HD)xzixJtr z2d=!_-1X+TmG;Kd-_B^o9Ae>CY`M7NefgJ|9Z$3Qru*~Uf4_bAw9Ezu>1~JF)^12V z9Cl;+Q9i{N^NuO>KVD%i)#q@&fB(I>_w%f4AIvTO9J%rN=Zu8( zm=iNMray6i@WEL3cMtdfij%ir7+<<{DB1AWzVo+Uq)v~j;9Qedm-WwDSyQ}D#E8-3 z-jb-YGl#YxD2ol3UoHAZnLGYaY-8=aC2`-Twf=XFJ761MG!z$;~z zb7RBpW8VtbK-oYkUTL#8CSXNC7En5o8$^J`fsE+mY*1mKNOS^B7%tBW)?y!9$H3lL W`0exJA! z9_ubY7um^Q>gP25^~B(UmeLpn)oH0^jk1+<%`b^x$=}B|ao>Ia$fQXM2ikNuBy#86 z*uYwL{f7PIr8c`aJg+<#G|%?M%g<9bO?mqI?N@%QHws@eXRSJzDE=sJ|6x9-{WjAl z2Ql;Q-gJ@s%hSD5zaOhUomP3wEkEy@Mc>ZUs+en0i_Md_|Kse42rF6qJz@L2XQ!>Q z7?<|erMy{oTB>bf2BW*#ubCTHPcO`7{C*)@`tSUW;o={p_p{Wly|{tgh4bbR9bJ-0V7-{zGz z19E=<^f&~R1qmN+g9!Drw?h~(5jK#*#KUGAsu^&}z?5#_ebcw`{K>AuZ`}tiSb?F= N;OXk;vd$@?2>@0kz9#?x diff --git a/src/assets/images/room-widgets/avatar-info/preview-background.png b/src/assets/images/room-widgets/avatar-info/preview-background.png deleted file mode 100644 index dea4f08dd49c0ddbc562e6eb17c854411d830cab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7756 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 IM6N<$f^1`jw*UYD diff --git a/src/assets/images/room-widgets/camera-widget/btn_down.png b/src/assets/images/room-widgets/camera-widget/btn_down.png deleted file mode 100644 index 76f25da1d9243426aa9bb4852f3121c80e910385..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1000 zcmV>P)S_5?q5U31f=@VAwx@ z&;}@kWx*lHfH0N`Kn#w?W`+d6ei zB|ZuL`M|!uSo7_9{C<5U4OSS$0Nmks(LX=`4+3}(`Pa(}Y4pO72H*ytgnodZ(Hr1B z}I3P0g@ zgWnCk#83F0;CDqo|b)<;FJ;8P2zf>*abI(mVBS-#^ywq4r# z2Q+`W5ke=vHlKw|*sj3i@#Y4Xd`ZTfYK61-*bbL1(u8N$VSOZTGAUeQ(fgv*$V zmzEn#x#X*8Kf%4Clko*RC0t#6pYukA=)(QaC4kDb=n9>MA9$+@m*_40+X9=jxJIwx zs{)w39ntwQgxU-0e8;;1INE@#yx(DWKw}3mY0J6r;M@RilQ&sh4xAc*C8bW~b3BOrE#5CD7I5U#CrXFk}y)@n_++cqwPi^ERRmY zrXmBv-~^Bp9F5HkVYvWQ;K1>L`n}Wu!lH}8jZUr>0faK_E4j>M{VXwn5cn+gkB{G-06v8J`l9WU-%SX>6`zfM1Aj#C&C(Gvb(Rl)mK}gM zJ{tWAK!Pj@V-!F%d=z>U-0Etk6+$ln1%6m`H*i7#q4448-r$`8LgB;Fqkz8(0El1c ztKpMIOeS;%K6K=;+MWfSi;r$SsqN=m09nw5_>k6<+TKfkb#x9ss`c!)XGIs_t6DE@ zdrI^kKC<=Xwr3wPvs+(ncWQmL-M016F=P25q^LW|ggS0mV`jIuQ(G??H`Vqzt;dd; z9oo)3$&$v6dd%$Jc?BK0#8O+8u2myY};BvXxwLS_sAOMQd&60eF(gZ## zxFP^4{G9votAGmvi2Fv!s^~;~dw9tSc6IatzS*1IsyUwpy@Rhlv9|EV@Y&EC`05iY zblhY`KjE8ygpb|&9pN=&Ml){yypRpxsUOoOjTzV%6E>Lf)4rHct;e*T{XM8B_#Io% zY&&brKwF>iKTt2rciRwc*S0<#KIK_9h_;JcpAmnAj&8fS^_lP~=(h)GAlt5LeFl6A z`UxJ^c2(FL7>n-cV*G`dstAKl#m}%fOE`22zA6Cc<%k}SVX3vC9$)w{fItgyonQB|E1~ETFS1AhPqE77`9MV>D3=v|^%}NW)AiNCpF=o+3+cB0y{%U=ZlUzT z=zsO_k2UI-;TA<9^&es`PrZ1N5+?uv002ov JPDHLkV1g3Zz}Wx* diff --git a/src/assets/images/room-widgets/camera-widget/cam_bg.png b/src/assets/images/room-widgets/camera-widget/cam_bg.png deleted file mode 100644 index d6cf994d063352f748ce25d259c4dd3e54645754..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2166 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 diff --git a/src/assets/images/room-widgets/camera-widget/viewfinder.png b/src/assets/images/room-widgets/camera-widget/viewfinder.png deleted file mode 100644 index ab6a9b24f6bfbe61befeddf8e75e1690811a46e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 959 zcmeAS@N?(olHy`uVBq!ia0y~yV6+2a4mO~Oh((P70|RrLr;B4q#jUq@eNVk|5NNx& z#!UJQ)9Hza8z#Q{a=x0c<1l|vC_k6@`$C`=28P=!SFQefI(V!0x6YN)DH|(_58ARW zyJ38~A8NPV+=HY? zq2`7$*dAIE5Bx%7*T&CVmCkcne(CarvpQlvg;&y(WQq3Bv{hy!3{t>X-)^+da%@`v1?sM~#X{vlv{5lGnoFt1q~FISuQ zCG3B7&&`$BrBfOO>}#&F0woiCdj2S*N2pc`=9l%#X|um6hrgfX)-x)yALJser}% zJO7x?#Rw*xA$^9Yz$J~%LJ1zys1X2(A8whz{^{zke==dQj;cZj)~$N=Nn}H|%iEc$ zF2Il$uxsIO;eW{d(D{c0kPAxOH%uXkyOjkhh@@si`ZU3Zhv!AQA?X1|Do6b5>F)dA lJM~sne)@Lm9LU8E>-f1hoe(_ia##<<^>p=fS?83{1OQ0_I2!-} diff --git a/src/assets/images/room-widgets/dimmer-widget/dimmer_banner.png b/src/assets/images/room-widgets/dimmer-widget/dimmer_banner.png deleted file mode 100644 index fdc6e9fabae522025b080149b464c349738c3014..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1041 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 diff --git a/src/assets/images/room-widgets/exchange-credit/exchange-credit-image.png b/src/assets/images/room-widgets/exchange-credit/exchange-credit-image.png deleted file mode 100644 index eef5da6cb5e1bcc91db1e615b5600064da805d73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9507 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 B4|V_m diff --git a/src/assets/images/room-widgets/furni-context-menu/monsterplant-preview.png b/src/assets/images/room-widgets/furni-context-menu/monsterplant-preview.png deleted file mode 100644 index 8d3d771ef46781f618464db09215eff640b7aa74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmbW2`9Bj39LJX{rqSVyJn@v9BoT6@FgbD#Ifh}vMrh8+7$L*s%n?bvupvid_Atwa z4G{^`9GiF?QPP1td;W#z^Ll+g@7L#-&+Gf!_wgM&OAzoZ5C8yxz*aXMxpd>&S&)~T zmmdQXxi}W-Xn6yGAC+C>7QP@eTQdNl6)Sw;%g^oYcWj(*ap?z#XXWMQWyDq$roMa< z(%wyY-d2jvfOvT8IRt~T3AXtKLH8h+y4&l5y=@!uk3$hwmvwaBknn?qrz7viQ(`lbUS3_Byx3Qo&>#0u6g`CC#*h)Sp>celS&k$m&_c*>Ckl zfK`AhQUcD}pk!x>qV$;B0yGVwF_~+M3({@P3O-t=9c@oemxa-KaDP?SG8hb4388cO zhrsw&PDlS=0Aj{^9d}14+{!%?01%=4=VLTvJq!R4cmlp@=ImzKF%62J za68Gr5X=*N-ZUE5h|daBnZ;mL-)lzyJUR*)D>Vcoj1i{$8)m@Nl@TqJRfFuXl}6{z zYbPFsAP2DlG&x*KbopAGN*K|wNV3lv)`JwpuUim7IrUckJCO5E=f#A1?u9 zL5iE^*gOX6^q;YDsZ?UrUjp>h0R2CP;N^S6JbEufnh*H``j&UxUKy8$_krm7r{%Ew zu(b%Z_Cj9vcn;VNK}IMJLq(QFq)8k&vOqJMRU%tJy z^@^3*ro6}}mDyK80_W4&jtNp*YJD4Db*?d*K1kRrv`M=q5cTBKjB zs1m2CQPW+6iWp+;jE^V6!7AU2vUc=6TdtjJQK`^e^kaIO&!Z?dY;E$CY9o~FRIWJq z4}H&l{8n$foa~icmLjtBg4~JL?g-3B;)1!ENQBElX2tbnbe2j!RO9%mfX=1RjI{EL z4yP@XI^AU_D%}qwMWdB>r+un@9S|o7SY?$;vGC zO-=dc6fr@Z|Nfbk2=ANqK(|Fb?~JTr=}DDiu$*NvL@g-tiM46kC|j%;5#T#p`p*Mi>Ri;{gH`enzT z?&8LIROQ#5v5?REs=nlV3F~w6{-XI@v=+=p+Se8{VI(CDeQ%CHkp;}D(^UoI0sU9d z$D2G-5J6;q#?$nqtaUz4gWox$(Z`Z=;CEi(LQa314!wx|?qL?}jZHre#6t%q^COho z**vZdI-#?cCl`g(sCpOt)%=b%VyLBA1N}qyx zz}tt{ReGgiiK$#FF523-2h5zhz~)co_PAu18rl7FK$07yXs@iV(Cv9 zR%TDA%aEu-n!FpHc~iiRK#F7QvVu=@~e z8z`n|8HWZ&_~7{G`MYP>7hYdaX6`E^zE`x=_?{^mu|^Fz;`HJKowM<)@=qaoX@X=ik96b8*ISBu$L@Xy&^-ITY zgUqCzRGz)^Oq?)q>Xp3AL&30N-n-<4{a+(W^ElB;r}wJ*bXU^e+1pC55}_k^V!zsw zzV#apmO!!rab$(7G5z-PbDO9hZNkSVG=HrC8v*5jh-BG;+3ht4;A__}%h*409~@TJ zn2GxhhIRZ{W6#2aAIoAfL3NQ8n0$-gE+J$A!a;j-;CZk3ae13=g2>Osm-gOdJS+f9 z@zD04mN#MUvcY3i?MXy41~Y--F)+>Fru$XqMmFJk<$t9mDZSz90zWiyN90(L?(U+ zoN>PCz!%y`3;3fOx+_s%pvCrE&`~cSPZ$|ZS-)=+ogQHdZ2Tg!AW5HM+ZdBfi6(Vu z>_hJ2-o8YVNnBajf_g2TQ}20{ogE_2R_tLRtLH+pWKtCDrhIm+_n^$#?cXbbpD_eE ztA|W#P&3<_vp;5AVhfm;N7bp$psRJ`8T!=2s4n%cHC^B0cbrep+4&kwyC1Nh(wn>U zDQR<{#sr>C1M<}U%S8x)@!(iel3XF~RP84}q`=}C7^A>P$^Y~D>I(ZjkeYv)SIYkH zhS0L%RFqMxjOO0N?XgOwA@c6#4}~sNZ}H$E(d>5;v{G|(rkNA|LzI~lwlva4VRF9} N0DQ~tCjJIAWP@ diff --git a/src/assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png b/src/assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png deleted file mode 100644 index 45e11f346dcf87cc6d35244e1940d23995ba07c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5719 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 JPDHLkV1o8Ili&aV diff --git a/src/assets/images/room-widgets/playlist-editor/disk_2.png b/src/assets/images/room-widgets/playlist-editor/disk_2.png deleted file mode 100644 index 3033020977be1a2dfe98bdb42d51f4538dc3bd87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 680 zcmV;Z0$2TsP){W9?Yu8`}x6c~}}<$jc|=>qq?c z^;vNZ>a~Q5Z?{{d)9K{3-|xNpf~>*VVgWasO;8tr5s;S0|(QCKcdC|Ep z0Bb;iph}JbXuV#$#bV*5a02)~lm*gqzu&z8f=H*f+pSwJmyuh511MdT9Q+I_1=Qpi z;AXR#2O|vOc+D$tS*R4y<#KV)=hMf-;oz#O@=~_|M+YIe$_@gxfs3G!&*es(1|7D3pzKEe96z zfrB5RAe$eE77G8Fhl(eYiMw8}VRFWA93vdARhKMW zBN*p1L2?uDt}t`3>U`dl&%~tT5O4bDe`}91WOl(m|RsmHeqr z&};IidS$9d_BmXHoY1ur$1(-d!LpA5Haqew5X3iCxVBRgXAX6YQ&Q`>QYZ1$8}s4+ zHHnuT^Kf?A!_|dN-aeN-H87SjEEGK)mpJ+nl7r*_u9wyknA&V}Vu+8C8r)bu-x}d^ zfOM?O58f=?7`6x^xUp@j1h^C+A&1(A$^wpI<1PtkA&1=REJ9}VcKHE36C2i>EEie; O00005Jg!SYhW>Kf>jU^K}G~b=tU5b5g?I}AQ2!Dk@8-Rba~g8s_Jgf$HwlGO5@Mi z?m2y{`a3>2=+>=UxBqr{c=*-gn=bF-rU2gF-dulrdRp=O`}@K70$>IxvIro+U0+`h zzEki#NNOJ+AA>(XKYt(1A0HoA{O;~<@CY2k+w^ren}YHH!CMsua93AXgDbRO1+E5^ zXYcRtgBuVW0S10^bK~YTgLZy?{sY=pgNr~#N&+Bwt-=hN`NhS>;2f3)4ZhXjGDSs@ z)IL8yzg}KmzK`Y)4-YGTdwcssT?Xy+^mK3rWYBPqHV|6@D+@gjl7V3_DGZ^p6^H5;@DSO%*# zETg0!C43G?e%+ukB!*_!0CmjNkpMo! zkUVI7O_M+aFs=y>MawlAtO%TEQ7Z`u9xQGR8B_!bk71~IKpO>2VR4NstPEbMJ5ig% zG=FK%(hyWgoQF|Xu6(4MwV`>y5c^z99uzz;bt&|KZCzL|b%WDAg=ikL=&fpl7 zmPbKFkGVVwZ4zMUC40F+)usjWU@0ifXPum!d>`TVT)|~Iipx-Hj79_VU@@?$cB3$e zU;zR^F%)$LXGexss-#Hy3T!QCc9JDlPhH$}YyRM5+X^dF8NcsA%R+7ul>r#fR%XDs zIoEu`g|=e^i&b`XbhP5Ct_)h1H)~Zk2{6oFa#QZX^M)c^+sIiSEC70aeO++|=Rqr} zY*t_%ECuF`-58iREU_cQvI|yN1}8Fr%b-QwnOXB#NnH#}AA2(d9I618!Lp-nHsSXa zS_`mQR0d#J+p}XWFr8vy)kW&^V0mRyXmhJ<6fmsy=^RuBjGr?whGmcK;xkwtv@t5% z7%=Z~1k8>K46p#9rZuv2JeB=gVEh`McVLacaO}Xk!o~w@$zgk!^w(`A_o7=-+Yi%D zY}6Oq$&PF7&`5_#(E{qu4vivc>x?D6$;P<`-`Py>*3VYx96M$#_G)^kG#{4DiRskK zk`st6d2KYX(iC+xU7gLZqkua#MGa`tB1p{&^Ik22)BuZ?;j{4Y3Om;_8~@JY%WS2! z$!HngOTbZ$Gq^bya%PF|T z2pZQ!3p9PLMr|H2hBkJ~rYC|)U;!A%f8P{5BeWWD{Q6F8JNJO~8ygmYR_b2t)U7k? zKwAeKo2RfWEVu6FtXgRO_PKWi@%als{z;ltjIA1r|=lyUjH4I8t;`*<+LiyOXNEP$}`<; vqF_pWFa7+cuV-;n043jadAoJ%wpI2QHV9BE9t?&*00000NkvXXu0mjf-JODz diff --git a/src/assets/images/room-widgets/playlist-editor/move.png b/src/assets/images/room-widgets/playlist-editor/move.png deleted file mode 100644 index 9d1635d83ea95063669963bb6724495bb57eaea5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^Vn8g!!3HGbRrPd%RJNy!V@SoEtyd26HYflT;xDC#cp>*f#7Xk*QIai{9S36%_P;fqX@FY<5)Y(CfjkKwAxtyhLmpLqhU OW$<+Mb6Mw<&;$U|mON+x diff --git a/src/assets/images/room-widgets/playlist-editor/pause-btn.png b/src/assets/images/room-widgets/playlist-editor/pause-btn.png deleted file mode 100644 index 900f99b4d7014aa4554a7e03a2ab7a580c550352..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`W}YsNAr*6y6A}`B^fNDJp7ZM8 zeO?}ygFAQ*EX}*p;Fx$IO;}i@=QKmiD>q&V5w-^hB-j!TGh}WIWH?#Wdm3m0gQu&X J%Q~loCIF@%BK`mX diff --git a/src/assets/images/room-widgets/playlist-editor/pause.png b/src/assets/images/room-widgets/playlist-editor/pause.png deleted file mode 100644 index ec5fef47dce0ad5cb6ebb5e32da844a8bb0bd313..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9S!3HE7rssMADN9cm$B>FS$rVxY|K-Kg9GEMv zHgV)IOn0=n+9zd_C1A?4tIhe7lvwkJRkEfTR}``&Tey>rImFo*LM>kH_*_t<1T=)f M)78&qol`;+04t#%-v9sr diff --git a/src/assets/images/room-widgets/playlist-editor/playing.png b/src/assets/images/room-widgets/playlist-editor/playing.png deleted file mode 100644 index 0e3449d161276ae0e82e7a956d76098c099fbde7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 309 zcmV-50m}Y~P)*{D6Ir^!I3%(k26bHQU=n1@vIP%QLU`~n zCFGafei%%GNc-V1>wXxl_5KMP2L?a+l`r0%aj`RuuAg*FN)P59uw*u%*G6$(EtfM}eu9k^c!(T>!@h1zp|N vcE-<~CMAsP@|P^+bUDPX@Q^jbBA-F-zh0bQ>+IP;TNpfD{an^LB{Ts5<%TfM diff --git a/src/assets/images/room-widgets/stickie-widget/stickie-blue.png b/src/assets/images/room-widgets/stickie-widget/stickie-blue.png deleted file mode 100644 index 9a14182e515e449d5e6fe27417fc085859e50395..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 401 zcmeAS@N?(olHy`uVBq!ia0vp^JArr;2Q!e=+%j)1kYX$ja(7}_cTVOdki(Mh=_Wunup>$LgbmML}{cq!Q_Wsr1*Wb>XWB+*a=lMS#{V}(* zs6YDsS^dYIKkI99|Mm5s?f-G@Pfz~Y^B~IpnRDFp<*$FSZ54k1?%*y93t$K^c)I$z JtaD0e0suDw%me@c diff --git a/src/assets/images/room-widgets/stickie-widget/stickie-christmas.png b/src/assets/images/room-widgets/stickie-widget/stickie-christmas.png deleted file mode 100644 index 82b4732fa8c57e023ac61336c798ba32bf622b7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1272 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�v~n=?I0_(WlwAn@duV^Jm-?w~x+k=33l#}t#C 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 diff --git a/src/assets/images/room-widgets/stickie-widget/stickie-green.png b/src/assets/images/room-widgets/stickie-widget/stickie-green.png deleted file mode 100644 index 5e73c74733bd4c64de6da0e677e7c54f4947a3b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 401 zcmeAS@N?(olHy`uVBq!ia0vp^JArr;2Q!e=+%j)1kYX$ja(7}_cTVOdki(Mh=lBSEK+1zj?YihE&A8J=f^#6v*Ie81Vm}Hh0%2HH(wJw>Yb$%kHP# zGk!nw`u+bxv41@I^ZXx={+QcY z)F1u+tp4N9pY=7l|N8pR_W!u{rzijHc@Sm)%sKA)^4GuEwhF(0cW{@51uz5{JYD@< J);T3K0RYHh%dY?c diff --git a/src/assets/images/room-widgets/stickie-widget/stickie-heart.png b/src/assets/images/room-widgets/stickie-widget/stickie-heart.png deleted file mode 100644 index 455238513ae84ee27c35e49718b3549aefe70781..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 945 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