🆙 Camera fix and some small updates

This commit is contained in:
duckietm 2024-09-13 08:06:26 +02:00
parent 34c52c69eb
commit 20cd6fc28f
14 changed files with 84 additions and 84 deletions

View File

@ -11,17 +11,17 @@
"${gamedata.url}//config/UITexts.json" "${gamedata.url}//config/UITexts.json"
], ],
"external.samples.url": "${hof.furni.url}/mp3/sound_machine_sample_%sample%.mp3", "external.samples.url": "${hof.furni.url}/mp3/sound_machine_sample_%sample%.mp3",
"furnidata.url": "${gamedata.url}/config/FurnitureData.json", "furnidata.url": "${gamedata.url}/config/FurnitureData.json?v=1",
"productdata.url": "${gamedata.url}/config/ProductData.json", "productdata.url": "${gamedata.url}/config/ProductData.json?v=1",
"avatar.actions.url": "${gamedata.url}/config/HabboAvatarActions.json", "avatar.actions.url": "${gamedata.url}/config/HabboAvatarActions.json?v=1",
"avatar.figuredata.url": "${gamedata.url}/config/FigureData.json", "avatar.figuredata.url": "${gamedata.url}/config/FigureData.json?v=1",
"avatar.figuremap.url": "${gamedata.url}/config/FigureMap.json", "avatar.figuremap.url": "${gamedata.url}/config/FigureMap.json?v=1",
"avatar.effectmap.url": "${gamedata.url}/config/EffectMap.json", "avatar.effectmap.url": "${gamedata.url}/config/EffectMap.json?v=1",
"avatar.asset.url": "${asset.url}/clothes/%libname%.nitro", "avatar.asset.url": "${asset.url}/clothes/%libname%.nitro",
"avatar.asset.effect.url": "${asset.url}/effect/%libname%.nitro", "avatar.asset.effect.url": "${asset.url}/effect/%libname%.nitro",
"furni.asset.url": "${asset.url}/furniture/%libname%.nitro", "furni.asset.url": "${asset.url}/furniture/%libname%.nitro",
"furni.asset.icon.url": "${gamedata.url}/icons/%libname%%param%_icon.png", "furni.asset.icon.url": "${gamedata.url}/icons/%libname%%param%_icon.png",
"pet.asset.url": "${asset.url}/pet/%libname%.nitro", "pet.asset.url": "${asset.url}/pets/%libname%.nitro",
"generic.asset.url": "${asset.url}/generic/%libname%.nitro", "generic.asset.url": "${asset.url}/generic/%libname%.nitro",
"badge.asset.url": "${image.library.url}album1584/%badgename%.gif", "badge.asset.url": "${image.library.url}album1584/%badgename%.gif",
"furni.rotation.bounce.steps": 20, "furni.rotation.bounce.steps": 20,
@ -38,6 +38,7 @@
"system.pong.interval.ms": 20000, "system.pong.interval.ms": 20000,
"room.color.skip.transition": true, "room.color.skip.transition": true,
"room.landscapes.enabled": true, "room.landscapes.enabled": true,
"room.zoom.enabled": true,
"avatar.mandatory.libraries": [ "avatar.mandatory.libraries": [
"bd:1", "bd:1",
"li:0" "li:0"

View File

@ -1,4 +1,4 @@
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 { GetAssetManager, GetAvatarRenderManager, GetCommunication, GetConfiguration, GetLocalizationManager, GetRoomEngine, GetRoomSessionManager, GetSessionDataManager, GetSoundManager, GetStage, GetTexturePool, GetTicker, HabboWebTools, LegacyExternalInterface, LoadGameUrlEvent, NitroLogger, NitroVersion, PrepareRenderer } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { GetUIVersion } from './api'; import { GetUIVersion } from './api';
import { Base } from './common'; import { Base } from './common';
@ -57,7 +57,6 @@ export const App: FC<{}> = props =>
GetSoundManager().init(), GetSoundManager().init(),
GetSessionDataManager().init(), GetSessionDataManager().init(),
GetRoomSessionManager().init(), GetRoomSessionManager().init(),
GetRoomCameraWidgetManager().init()
] ]
); );

View File

@ -19,10 +19,17 @@ export class FurnitureDimmerUtilities
} }
public static previewDimmer(color: number, brightness: number, bgOnly: boolean): void public static previewDimmer(color: number, brightness: number, bgOnly: boolean): void
{ {
GetRoomEngine().updateObjectRoomColor(GetRoomSession().roomId, color, brightness, bgOnly); const roomSession = GetRoomSession();
if (!roomSession || !roomSession.roomId) {
console.error('Room session or roomId is not available.');
return;
} }
GetRoomEngine().updateObjectRoomColor(roomSession.roomId, color, brightness, bgOnly);
}
public static scaleBrightness(value: number): number public static scaleBrightness(value: number): number
{ {
return ~~((((value - this.MIN_BRIGHTNESS) * (100 - 0)) / (this.MAX_BRIGHTNESS - this.MIN_BRIGHTNESS)) + 0); return ~~((((value - this.MIN_BRIGHTNESS) * (100 - 0)) / (this.MAX_BRIGHTNESS - this.MIN_BRIGHTNESS)) + 0);

View File

@ -14,7 +14,7 @@ export const CameraWidgetView: FC<{}> = props =>
{ {
const [ mode, setMode ] = useState<number>(MODE_NONE); const [ mode, setMode ] = useState<number>(MODE_NONE);
const [ base64Url, setSavedPictureUrl ] = useState<string>(null); const [ base64Url, setSavedPictureUrl ] = useState<string>(null);
const { availableEffects = [], selectedPictureIndex = -1, cameraRoll = [], setCameraRoll = null, myLevel = 0, price = { credits: 0, duckets: 0, publishDucketPrice: 0 }} = useCamera(); const { availableEffects = [], selectedPictureIndex = -1, cameraRoll = [], setCameraRoll = null, myLevel = 0, price = { credits: 0, duckets: 0, publishDucketPrice: 0 } } = useCamera();
const processAction = (type: string) => const processAction = (type: string) =>
{ {
@ -40,13 +40,13 @@ export const CameraWidgetView: FC<{}> = props =>
setMode(MODE_CAPTURE); setMode(MODE_CAPTURE);
return; return;
} }
} };
const checkoutPictureUrl = (pictureUrl: string) => const checkoutPictureUrl = (pictureUrl: string) =>
{ {
setSavedPictureUrl(pictureUrl); setSavedPictureUrl(pictureUrl);
setMode(MODE_CHECKOUT); setMode(MODE_CHECKOUT);
} };
useNitroEvent<RoomSessionEvent>(RoomSessionEvent.ENDED, event => setMode(MODE_NONE)); useNitroEvent<RoomSessionEvent>(RoomSessionEvent.ENDED, event => setMode(MODE_NONE));
@ -56,9 +56,9 @@ export const CameraWidgetView: FC<{}> = props =>
linkReceived: (url: string) => linkReceived: (url: string) =>
{ {
const parts = url.split('/'); const parts = url.split('/');
if(parts.length < 2) return; if(parts.length < 2) return;
switch(parts[1]) switch(parts[1])
{ {
case 'show': case 'show':
@ -93,4 +93,4 @@ export const CameraWidgetView: FC<{}> = props =>
{ (mode === MODE_CHECKOUT) && <CameraWidgetCheckoutView base64Url={ base64Url } onCloseClick={ () => processAction('close') } onCancelClick={ () => processAction('editor_cancel') } price={ price }></CameraWidgetCheckoutView> } { (mode === MODE_CHECKOUT) && <CameraWidgetCheckoutView base64Url={ base64Url } onCloseClick={ () => processAction('close') } onCancelClick={ () => processAction('editor_cancel') } price={ price }></CameraWidgetCheckoutView> }
</> </>
); );
} };

View File

@ -28,9 +28,9 @@ export const CameraWidgetCaptureView: FC<CameraWidgetCaptureViewProps> = props =
if(!elementRef || !elementRef.current) return null; if(!elementRef || !elementRef.current) return null;
const frameBounds = elementRef.current.getBoundingClientRect(); const frameBounds = elementRef.current.getBoundingClientRect();
return new NitroRectangle(Math.floor(frameBounds.x), Math.floor(frameBounds.y), Math.floor(frameBounds.width), Math.floor(frameBounds.height)); return new NitroRectangle(Math.floor(frameBounds.x), Math.floor(frameBounds.y), Math.floor(frameBounds.width), Math.floor(frameBounds.height));
} };
const takePicture = async () => const takePicture = async () =>
{ {
@ -55,7 +55,7 @@ export const CameraWidgetCaptureView: FC<CameraWidgetCaptureViewProps> = props =
clone.push(new CameraPicture(texture, await TextureUtils.generateImageUrl(texture))); clone.push(new CameraPicture(texture, await TextureUtils.generateImageUrl(texture)));
setCameraRoll(clone); setCameraRoll(clone);
} };
return ( return (
<DraggableWindow uniqueKey="nitro-camera-capture"> <DraggableWindow uniqueKey="nitro-camera-capture">
@ -66,7 +66,7 @@ export const CameraWidgetCaptureView: FC<CameraWidgetCaptureViewProps> = props =
<FaTimes className="fa-icon" /> <FaTimes className="fa-icon" />
</div> </div>
{ !selectedPicture && <div ref={ elementRef } className="camera-area camera-view-finder" /> } { !selectedPicture && <div ref={ elementRef } className="camera-area camera-view-finder" /> }
{ selectedPicture && { selectedPicture &&
<div className="camera-area camera-frame"> <div className="camera-area camera-frame">
<div className="camera-frame-preview-actions w-100 position-absolute bottom-0 py-2 text-center"> <div className="camera-frame-preview-actions w-100 position-absolute bottom-0 py-2 text-center">
<button className="btn btn-success me-3" title={ LocalizeText('camera.editor.button.tooltip') } onClick={ onEdit }>{ LocalizeText('camera.editor.button.text') }</button> <button className="btn btn-success me-3" title={ LocalizeText('camera.editor.button.tooltip') } onClick={ onEdit }>{ LocalizeText('camera.editor.button.text') }</button>
@ -87,4 +87,4 @@ export const CameraWidgetCaptureView: FC<CameraWidgetCaptureViewProps> = props =
</Column> </Column>
</DraggableWindow> </DraggableWindow>
); );
} };

View File

@ -70,7 +70,7 @@ export const CameraWidgetCheckoutView: FC<CameraWidgetCheckoutViewProps> = props
onCancelClick(); onCancelClick();
return; return;
} }
} };
useEffect(() => useEffect(() =>
{ {
@ -156,4 +156,4 @@ export const CameraWidgetCheckoutView: FC<CameraWidgetCheckoutViewProps> = props
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>
); );
} };

View File

@ -26,7 +26,7 @@ export const CameraWidgetShowPhotoView: FC<CameraWidgetShowPhotoViewProps> = pro
return newIndex; return newIndex;
}); });
} };
const previous = () => const previous = () =>
{ {
@ -38,7 +38,7 @@ export const CameraWidgetShowPhotoView: FC<CameraWidgetShowPhotoViewProps> = pro
return newIndex; return newIndex;
}); });
} };
useEffect(() => useEffect(() =>
{ {
@ -68,4 +68,4 @@ export const CameraWidgetShowPhotoView: FC<CameraWidgetShowPhotoViewProps> = pro
} }
</Grid> </Grid>
); );
} };

View File

@ -1,5 +1,5 @@
import { GetRoomCameraWidgetManager, IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect, RoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer'; import { GetRoomCameraWidgetManager, IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect, NitroLogger, RoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { FaSave, FaSearchMinus, FaSearchPlus, FaTrash } from 'react-icons/fa'; import { FaSave, FaSearchMinus, FaSearchPlus, FaTrash } from 'react-icons/fa';
import ReactSlider from 'react-slider'; import ReactSlider from 'react-slider';
import { CameraEditorTabs, CameraPicture, CameraPictureThumbnail, LocalizeText } from '../../../../api'; import { CameraEditorTabs, CameraPicture, CameraPictureThumbnail, LocalizeText } from '../../../../api';
@ -27,6 +27,7 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
const [ effectsThumbnails, setEffectsThumbnails ] = useState<CameraPictureThumbnail[]>([]); const [ effectsThumbnails, setEffectsThumbnails ] = useState<CameraPictureThumbnail[]>([]);
const [ isZoomed, setIsZoomed ] = useState(false); const [ isZoomed, setIsZoomed ] = useState(false);
const [ currentPictureUrl, setCurrentPictureUrl ] = useState<string>(''); const [ currentPictureUrl, setCurrentPictureUrl ] = useState<string>('');
const isBusy = useRef<boolean>(false);
const getColorMatrixEffects = useMemo(() => const getColorMatrixEffects = useMemo(() =>
{ {
@ -104,7 +105,7 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
let existingIndex = getSelectedEffectIndex(effectName); let existingIndex = getSelectedEffectIndex(effectName);
if(existingIndex >= 0) return; if(existingIndex >= 0) return;
const effect = availableEffects.find(effect => (effect.name === effectName)); const effect = availableEffects.find(effect => (effect.name === effectName));
if(!effect) return; if(!effect) return;
@ -142,9 +143,9 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
(async () => (async () =>
{ {
const image = new Image(); const image = new Image();
image.src = currentPictureUrl; image.src = currentPictureUrl;
const newWindow = window.open(''); const newWindow = window.open('');
newWindow.document.write(image.outerHTML); newWindow.document.write(image.outerHTML);
})(); })();
@ -158,29 +159,28 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
useEffect(() => useEffect(() =>
{ {
(async () => const processThumbnails = async () =>
{ {
const thumbnails: CameraPictureThumbnail[] = []; const renderedEffects = await Promise.all(availableEffects.map(effect => GetRoomCameraWidgetManager().applyEffects(picture.texture, [ new RoomCameraWidgetSelectedEffect(effect, 1) ], false)));
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(renderedEffects.map((image, index) => new CameraPictureThumbnail(availableEffects[index].name, image.src)));
} };
setEffectsThumbnails(thumbnails); processThumbnails();
})();
}, [ picture, availableEffects ]); }, [ picture, availableEffects ]);
useEffect(() => useEffect(() =>
{ {
(async () => GetRoomCameraWidgetManager()
{ .applyEffects(picture.texture, selectedEffects, isZoomed)
const imageUrl = await GetRoomCameraWidgetManager().applyEffects(picture.texture, selectedEffects, isZoomed); .then(imageElement =>
{
setCurrentPictureUrl(imageUrl.src); setCurrentPictureUrl(imageElement.src);
})(); })
.catch(error =>
{
NitroLogger.error('Failed to apply effects to picture', error);
});
}, [ picture, selectedEffects, isZoomed ]); }, [ picture, selectedEffects, isZoomed ]);
return ( return (
@ -189,7 +189,7 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
<NitroCardTabsView> <NitroCardTabsView>
{ TABS.map(tab => { TABS.map(tab =>
{ {
return <NitroCardTabsItemView key={ tab } isActive={ currentTab === tab } onClick={ event => processAction('change_tab', tab) }><i className={ 'icon icon-camera-' + tab }></i></NitroCardTabsItemView> return <NitroCardTabsItemView key={ tab } isActive={ currentTab === tab } onClick={ event => processAction('change_tab', tab) }><i className={ 'icon icon-camera-' + tab }></i></NitroCardTabsItemView>;
}) } }) }
</NitroCardTabsView> </NitroCardTabsView>
<NitroCardContentView> <NitroCardContentView>
@ -205,12 +205,12 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
<Text>{ LocalizeText('camera.effect.name.' + selectedEffectName) }</Text> <Text>{ LocalizeText('camera.effect.name.' + selectedEffectName) }</Text>
<ReactSlider <ReactSlider
className={ 'nitro-slider' } className={ 'nitro-slider' }
max={ 1 }
min={ 0 } min={ 0 }
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } max={ 1 }
step={ 0.01 } step={ 0.01 }
value={ getCurrentEffect.alpha } value={ getCurrentEffect.strength }
onChange={ event => setSelectedEffectAlpha(event) } /> onChange={ event => setSelectedEffectAlpha(event) }
renderThumb={ ({ key, ...props }, state) => <div key={ key } { ...props }>{ state.valueNow }</div> } />
</Column> } </Column> }
</Column> </Column>
<Flex justifyContent="between"> <Flex justifyContent="between">
@ -240,4 +240,4 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>
); );
} };

View File

@ -37,4 +37,4 @@ export const CameraWidgetEffectListItemView: FC<CameraWidgetEffectListItemViewPr
</Text> } </Text> }
</LayoutGridItem> </LayoutGridItem>
); );
} };

View File

@ -24,8 +24,8 @@ export const CameraWidgetEffectListView: FC<CameraWidgetEffectListViewProps> = p
const thumbnailUrl = (thumbnails.find(thumbnail => (thumbnail.effectName === effect.name))); const thumbnailUrl = (thumbnails.find(thumbnail => (thumbnail.effectName === effect.name)));
const isActive = (selectedEffects.findIndex(selectedEffect => (selectedEffect.effect.name === effect.name)) > -1); const isActive = (selectedEffects.findIndex(selectedEffect => (selectedEffect.effect.name === effect.name)) > -1);
return <CameraWidgetEffectListItemView key={ index } effect={ effect } isActive={ isActive } isLocked={ (effect.minLevel > myLevel) } removeEffect={ () => processAction('remove_effect', effect.name) } selectEffect={ () => processAction('select_effect', effect.name) } thumbnailUrl={ ((thumbnailUrl && thumbnailUrl.thumbnailUrl) || null) } />; return <CameraWidgetEffectListItemView key={ index } effect={ effect } thumbnailUrl={ ((thumbnailUrl && thumbnailUrl.thumbnailUrl) || null) } isActive={ isActive } isLocked={ (effect.minLevel > myLevel) } selectEffect={ () => processAction('select_effect', effect.name) } removeEffect={ () => processAction('remove_effect', effect.name) } />;
}) } }) }
</Grid> </Grid>
); );
}; };

View File

@ -21,7 +21,7 @@ export const RoomWidgetsView: FC<{}> = props =>
const { roomSession = null } = useRoom(); const { roomSession = null } = useRoom();
const { simpleAlert = null } = useNotification(); const { simpleAlert = null } = useNotification();
useNitroEvent<RoomZoomEvent>(RoomZoomEvent.ROOM_ZOOM, event => GetRoomEngine().setRoomInstanceRenderingCanvasScale(event.roomId, 1, event.level, null, null, false, event.asDelta)); useNitroEvent<RoomZoomEvent>(RoomZoomEvent.ROOM_ZOOM, event => GetRoomEngine().setRoomInstanceRenderingCanvasScale(event.roomId, 1, (((event.level)<1) ? 0.5 : (1 << (Math.floor(event.level) - 1))), null, null, event.isFlipForced));
useNitroEvent<RoomEngineObjectEvent>( useNitroEvent<RoomEngineObjectEvent>(
[ [

View File

@ -1,7 +1,7 @@
import { CreateLinkEvent, GetGuestRoomResultEvent, GetRoomEngine, NavigatorSearchComposer, RateFlatMessageComposer, RoomDataParser } from '@nitrots/nitro-renderer'; import { CreateLinkEvent, GetGuestRoomResultEvent, GetRoomEngine, NavigatorSearchComposer, RateFlatMessageComposer, RoomDataParser } from '@nitrots/nitro-renderer';
import { AnimatePresence, motion } from 'framer-motion'; import { AnimatePresence, motion } from 'framer-motion';
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { LocalizeText, SendMessageComposer, SetLocalStorage, TryVisitRoom } from '../../../../api'; import { GetConfigurationValue, LocalizeText, SendMessageComposer, SetLocalStorage, TryVisitRoom } from '../../../../api';
import { Base, Column, Flex, Text, classNames } from '../../../../common'; import { Base, Column, Flex, Text, classNames } from '../../../../common';
import { useMessageEvent, useNavigator, useRoom } from '../../../../hooks'; import { useMessageEvent, useNavigator, useRoom } from '../../../../hooks';
@ -31,12 +31,17 @@ export const RoomToolsWidgetView: FC<{}> = props =>
case 'zoom': case 'zoom':
setIsZoomedIn(prevValue => setIsZoomedIn(prevValue =>
{ {
let scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomSession.roomId, 1); if(GetConfigurationValue('room.zoom.enabled', true))
{
const scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomSession.roomId, 1);
GetRoomEngine().setRoomInstanceRenderingCanvasScale(roomSession.roomId, 1, scale === 1 ? 0.5 : 1);
}
else
{
const geometry = GetRoomEngine().getRoomInstanceGeometry(roomSession.roomId, 1);
if(!prevValue) scale /= 2; if(geometry) geometry.performZoom();
else scale *= 2; }
GetRoomEngine().setRoomInstanceRenderingCanvasScale(roomSession.roomId, 1, scale);
return !prevValue; return !prevValue;
}); });

View File

@ -20,23 +20,20 @@ const useCameraState = () =>
useMessageEvent<InitCameraMessageEvent>(InitCameraMessageEvent, event => useMessageEvent<InitCameraMessageEvent>(InitCameraMessageEvent, event =>
{ {
const parser = event.getParser(); const parser = event.getParser();
setPrice({ credits: parser.creditPrice, duckets: parser.ducketPrice, publishDucketPrice: parser.publishDucketPrice }); setPrice({ credits: parser.creditPrice, duckets: parser.ducketPrice, publishDucketPrice: parser.publishDucketPrice });
}); });
useEffect(() => useEffect(() =>
{ {
if(!GetRoomCameraWidgetManager().isLoaded) if(GetRoomCameraWidgetManager().isLoaded) return;
{
GetRoomCameraWidgetManager().init();
SendMessageComposer(new RequestCameraConfigurationComposer()); GetRoomCameraWidgetManager().init();
return; SendMessageComposer(new RequestCameraConfigurationComposer());
}
}, []); }, []);
return { availableEffects, cameraRoll, setCameraRoll, selectedPictureIndex, setSelectedPictureIndex, myLevel, price }; return { availableEffects, cameraRoll, setCameraRoll, selectedPictureIndex, setSelectedPictureIndex, myLevel, price };
} };
export const useCamera = () => useBetween(useCameraState); export const useCamera = () => useBetween(useCameraState);

View File

@ -108,17 +108,8 @@ const useChatInputWidgetState = () =>
return null; return null;
case ':zoom': case ':zoom':
let requestedZoomLevel = parseFloat(secondPart); GetEventDispatcher().dispatchEvent(new RoomZoomEvent(roomSession.roomId, parseInt(secondPart)));
if (isNaN(requestedZoomLevel)) {
requestedZoomLevel = 1;
}
if (requestedZoomLevel >= 1 && requestedZoomLevel <= 5) {
GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(roomSession.roomId, requestedZoomLevel, false));
} else if (requestedZoomLevel === 0) {
GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(roomSession.roomId, 1, false));
} else {
GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(roomSession.roomId, 1, false));
};
return null; return null;
case ':screenshot': case ':screenshot':
const texture = GetRoomEngine().createTextureFromRoom(roomSession.roomId, 1); const texture = GetRoomEngine().createTextureFromRoom(roomSession.roomId, 1);