From b241aac640e8d984b9cbd0449b4859c7e1e25ea0 Mon Sep 17 00:00:00 2001 From: duckietm Date: Fri, 23 May 2025 07:56:11 +0200 Subject: [PATCH] :up: beta fix pets --- src/hooks/rooms/widgets/useChatWidget.ts | 135 +++++++++++++++++++---- 1 file changed, 114 insertions(+), 21 deletions(-) diff --git a/src/hooks/rooms/widgets/useChatWidget.ts b/src/hooks/rooms/widgets/useChatWidget.ts index 61a5348..f81708f 100644 --- a/src/hooks/rooms/widgets/useChatWidget.ts +++ b/src/hooks/rooms/widgets/useChatWidget.ts @@ -19,9 +19,14 @@ const useChatWidgetState = () => distance: 50, protection: RoomChatSettings.FLOOD_FILTER_NORMAL }); + const [ hasRoomLoaded, setHasRoomLoaded ] = useState(false); + const [ isInitialLoadDelayActive, setIsInitialLoadDelayActive ] = useState(false); const { roomSession = null } = useRoom(); const { addChatEntry } = useChatHistory(); const isDisposed = useRef(false); + const isDelayingPetChats = useRef(false); // Synchronous flag to track delay period + const isFirstRoomLoad = useRef(true); // Track if this is the first room load in the session + const isWaitingForRoomEntry = useRef(true); // Track if we're waiting for GetGuestRoomResultEvent const getScrollSpeed = useMemo(() => { @@ -80,6 +85,7 @@ const useChatWidgetState = () => avatarImage.dispose(); resolve(image.src); }).catch(error => { + console.log(`Error generating avatar image for figure ${figure}:`, error); avatarImage.dispose(); resolve(null); }); @@ -120,19 +126,21 @@ const useChatWidgetState = () => const imageUrl = await TextureUtils.generateImageUrl(image.data); if (imageUrl) { petImageCache.set(cacheKey, imageUrl); + console.log(`Pet image generated successfully: ${imageUrl}`); return imageUrl; } else { + console.log(`Failed to generate image URL for pet: typeId=${typeId}`); petImageCache.delete(cacheKey); } } else { + console.log(`Pet image generation failed for typeId ${typeId}`); petImageCache.delete(cacheKey); } return null; }; - useRoomSessionManagerEvent(RoomSessionChatEvent.CHAT_EVENT, async event => - { + const processChatEvent = async (event: RoomSessionChatEvent) => { const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, event.objectId, RoomObjectCategory.UNIT); const bubbleLocation = roomObject ? GetRoomObjectScreenLocation(roomSession.roomId, roomObject?.id, RoomObjectCategory.UNIT) : new NitroPoint(); const userData = roomObject ? roomSession.userDataManager.getUserDataByIndex(event.objectId) : new RoomUserData(-1); @@ -155,7 +163,7 @@ const useChatWidgetState = () => switch(userType) { case RoomObjectType.PET: - imageUrl = await getPetImage(figure, 2, true, 64, roomObject.model.getValue(RoomObjectVariable.FIGURE_POSTURE)); + imageUrl = await getPetImage(figure, 2, true, 64, roomObject?.model.getValue(RoomObjectVariable.FIGURE_POSTURE)); petType = new PetFigureData(figure).typeId; chatColours = "black"; break; @@ -176,6 +184,7 @@ const useChatWidgetState = () => switch(chatType) { case RoomSessionChatEvent.CHAT_TYPE_RESPECT: + styleId = 38; text = LocalizeText('widgets.chatbubble.respect', [ 'username' ], [ username ]); if(GetConfiguration('respect.options')['enabled']) PlaySound(GetConfiguration('respect.options')['sound']); break; @@ -183,6 +192,7 @@ const useChatWidgetState = () => case RoomSessionChatEvent.CHAT_TYPE_PET_REBREED_FERTILIZE: case RoomSessionChatEvent.CHAT_TYPE_PET_SPEED_FERTILIZE: { let textKey = 'widget.chatbubble.petrevived'; + styleId = 38; if(chatType === RoomSessionChatEvent.CHAT_TYPE_PET_REBREED_FERTILIZE) { textKey = 'widget.chatbubble.petrefertilized;'; @@ -202,15 +212,19 @@ const useChatWidgetState = () => break; } case RoomSessionChatEvent.CHAT_TYPE_PETRESPECT: + styleId = 38; text = LocalizeText('widget.chatbubble.petrespect', [ 'petname' ], [ username ]); break; case RoomSessionChatEvent.CHAT_TYPE_PETTREAT: + styleId = 38; text = LocalizeText('widget.chatbubble.pettreat', [ 'petname' ], [ username ]); break; case RoomSessionChatEvent.CHAT_TYPE_HAND_ITEM_RECEIVED: + styleId = 38; text = LocalizeText('widget.chatbubble.handitem', [ 'username', 'handitem' ], [ username, LocalizeText(('handitem' + event.extraParam)) ]); break; case RoomSessionChatEvent.CHAT_TYPE_MUTE_REMAINING: { + styleId = 38; 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(); @@ -237,11 +251,102 @@ const useChatWidgetState = () => chatColours ); - // Add userType to ChatBubbleMessage as a dynamic property (chatMessage as any).userType = userType; 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, chatColours }); + }; + + useRoomSessionManagerEvent(RoomSessionChatEvent.CHAT_EVENT, async event => + { + if (!roomSession) return; + + const userData = GetRoomEngine().getRoomObject(roomSession.roomId, event.objectId, RoomObjectCategory.UNIT) + ? roomSession.userDataManager.getUserDataByIndex(event.objectId) + : new RoomUserData(-1); + const userType = userData?.type; + + // Discard pet chats until room entry is confirmed and delay is processed + if (userType === RoomObjectType.PET) { + if (isWaitingForRoomEntry.current || (isFirstRoomLoad.current && isDelayingPetChats.current)) { + console.log(`Discarding pet chat event for objectId ${event.objectId} until room entry is confirmed or delay ends`); + return; + } + } + + // Process all chats immediately after room entry and initial delay (if applicable) + await processChatEvent(event); + }); + + useMessageEvent(GetGuestRoomResultEvent, event => + { + const parser = event.getParser(); + + console.log(`GetGuestRoomResultEvent received, roomEnter: ${parser.roomEnter}`); + + if(!parser.roomEnter) return; + + setChatSettings(parser.chat); + + // Room entry confirmed, stop waiting + isWaitingForRoomEntry.current = false; + console.log('Room entry confirmed via GetGuestRoomResultEvent'); + + if (!hasRoomLoaded) { + setHasRoomLoaded(true); + + // Apply delay only for the first room load + if (isFirstRoomLoad.current) { + isDelayingPetChats.current = true; + setIsInitialLoadDelayActive(true); + console.log('First room loaded in useRoom.ts, starting 5-second delay for pet chat events'); + + // After 5 seconds, stop delaying pet chats + setTimeout(() => { + console.log('Initial 5-second delay ended'); + isDelayingPetChats.current = false; + setIsInitialLoadDelayActive(false); + isFirstRoomLoad.current = false; // Mark that the first room has been loaded + }, 5000); + } else { + // For subsequent rooms, no delay is applied + console.log('Subsequent room loaded, no delay for pet chat events'); + } + } + }); + + // Fallback timeout to stop waiting if GetGuestRoomResultEvent doesn't fire + useEffect(() => { + if (isWaitingForRoomEntry.current) { + const timeout = setTimeout(() => { + console.log('Fallback timeout: GetGuestRoomResultEvent not received within 10 seconds, assuming room entry'); + isWaitingForRoomEntry.current = false; + if (!hasRoomLoaded) { + setHasRoomLoaded(true); + if (isFirstRoomLoad.current) { + isDelayingPetChats.current = true; + setIsInitialLoadDelayActive(true); + console.log('First room assumed loaded (fallback), starting 5-second delay for pet chat events'); + setTimeout(() => { + console.log('Initial 5-second delay ended (fallback)'); + isDelayingPetChats.current = false; + setIsInitialLoadDelayActive(false); + isFirstRoomLoad.current = false; + }, 5000); + } else { + console.log('Subsequent room assumed loaded (fallback), no delay for pet chat events'); + } + } + }, 10000); // Wait 10 seconds for GetGuestRoomResultEvent + return () => clearTimeout(timeout); + } + }, []); + + useMessageEvent(RoomChatSettingsEvent, event => + { + const parser = event.getParser(); + + setChatSettings(parser.chat); }); useRoomEngineEvent(RoomDragEvent.ROOM_DRAG, event => @@ -253,22 +358,6 @@ const useChatWidgetState = () => 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; @@ -276,7 +365,11 @@ const useChatWidgetState = () => return () => { isDisposed.current = true; - } + isDelayingPetChats.current = false; + isWaitingForRoomEntry.current = true; // Reset for next room load + setHasRoomLoaded(false); + setIsInitialLoadDelayActive(false); + }; }, []); return { chatMessages, setChatMessages, chatSettings, getScrollSpeed };