🆙 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

@ -20,7 +20,14 @@ 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

View File

@ -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));
@ -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

@ -30,7 +30,7 @@ export const CameraWidgetCaptureView: FC<CameraWidgetCaptureViewProps> = props =
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">
@ -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(() =>
{ {
@ -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) setEffectsThumbnails(renderedEffects.map((image, index) => new CameraPictureThumbnail(availableEffects[index].name, image.src)));
{ };
const image = await GetRoomCameraWidgetManager().applyEffects(picture.texture, [ new RoomCameraWidgetSelectedEffect(effect, 1) ], false);
thumbnails.push(new CameraPictureThumbnail(effect.name, image.src)); processThumbnails();
}
setEffectsThumbnails(thumbnails);
})();
}, [ picture, availableEffects ]); }, [ picture, availableEffects ]);
useEffect(() => useEffect(() =>
{ {
(async () => GetRoomCameraWidgetManager()
.applyEffects(picture.texture, selectedEffects, isZoomed)
.then(imageElement =>
{ {
const imageUrl = await GetRoomCameraWidgetManager().applyEffects(picture.texture, selectedEffects, isZoomed); setCurrentPictureUrl(imageElement.src);
})
setCurrentPictureUrl(imageUrl.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,7 +24,7 @@ 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

@ -26,17 +26,14 @@ const useCameraState = () =>
useEffect(() => useEffect(() =>
{ {
if(!GetRoomCameraWidgetManager().isLoaded) if(GetRoomCameraWidgetManager().isLoaded) return;
{
GetRoomCameraWidgetManager().init(); GetRoomCameraWidgetManager().init();
SendMessageComposer(new RequestCameraConfigurationComposer()); SendMessageComposer(new RequestCameraConfigurationComposer());
return;
}
}, []); }, []);
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);