From 816779a6140d4f8bd1d6588ad38bcf92547a3ee9 Mon Sep 17 00:00:00 2001 From: DuckieTM Date: Sat, 6 Jun 2026 08:42:18 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=86=99=20Fixed=20the=20colorid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widgets/CatalogViewProductWidgetView.tsx | 35 +---------------- .../inventory/views/bot/InventoryBotView.tsx | 14 +------ .../furniture/InventoryFurnitureView.tsx | 38 ++++--------------- .../inventory/views/pet/InventoryPetView.tsx | 13 +------ src/pixiPatch.ts | 33 ---------------- 5 files changed, 13 insertions(+), 120 deletions(-) diff --git a/src/components/catalog/views/page/widgets/CatalogViewProductWidgetView.tsx b/src/components/catalog/views/page/widgets/CatalogViewProductWidgetView.tsx index e79c7d9..46c0184 100644 --- a/src/components/catalog/views/page/widgets/CatalogViewProductWidgetView.tsx +++ b/src/components/catalog/views/page/widgets/CatalogViewProductWidgetView.tsx @@ -1,4 +1,4 @@ -import { GetAvatarRenderManager, GetRoomEngine, GetSessionDataManager, RoomObjectVariable, Vector3d } from '@nitrots/nitro-renderer'; +import { GetAvatarRenderManager, GetSessionDataManager, Vector3d } from '@nitrots/nitro-renderer'; import { FC, useEffect } from 'react'; import { BuildPurchasableClothingFigure, FurniCategory, Offer, ProductTypeEnum } from '../../../../../api'; import { AutoGrid, Column, LayoutGridItem, LayoutRoomPreviewerView } from '../../../../../common'; @@ -19,25 +19,7 @@ export const CatalogViewProductWidgetView: FC<{}> = props => if(!product) return; roomPreviewer.reset(false); - - // Mirror the user's current room so the catalog preview shows - // the item against the wallpaper / floor / landscape they - // actually have decorated. Same approach as - // InventoryFurnitureView - read the active room's pattern ids - // off the room engine, fall back to '101' / '101' / '1.1' if - // the user isn't in a room yet (those are real Habbo pattern - // ids, the literal 'default' we used before is not and made - // the previewer fall back to blank white surfaces). - const roomEngine = GetRoomEngine(); - let floorType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE); - let wallType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE); - let landscapeType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE); - - floorType = (floorType && floorType.length) ? floorType : '3002'; - wallType = (wallType && wallType.length) ? wallType : '3001'; - landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1'; - - roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType); + roomPreviewer.updateObjectRoom('111', '217', '1.1'); roomPreviewer.updateRoomWallsAndFloorVisibility(true, true); const populate = () => @@ -124,13 +106,6 @@ export const CatalogViewProductWidgetView: FC<{}> = props => }; populate(); - - // RoomPreviewer.addFurnitureIntoRoom / addAvatarIntoRoom flip - // _automaticStateChange to true, which makes the ticker advance - // the room object's state every AUTOMATIC_STATE_CHANGE_INTERVAL. - // In the catalog we want the preview to sit still until the - // user clicks the state button explicitly - turn it back off - // after populate() runs. roomPreviewer.setAutomaticStateChange(false); }, [ currentOffer, previewStuffData, roomPreviewer ]); @@ -150,11 +125,5 @@ export const CatalogViewProductWidgetView: FC<{}> = props => ); } - // Re-mount the previewer whenever the offer changes so the render - // latch / texture handle in LayoutRoomPreviewerView resets cleanly. - // Without this a single broken offer (e.g. blackhole's Pixi filter - // crash) latches the previewer permanently and every following - // offer paints nothing - the singleton roomPreviewer + 240px height - // keep the same component mounted otherwise. return ; }; diff --git a/src/components/inventory/views/bot/InventoryBotView.tsx b/src/components/inventory/views/bot/InventoryBotView.tsx index 7f3dd04..6963f2e 100644 --- a/src/components/inventory/views/bot/InventoryBotView.tsx +++ b/src/components/inventory/views/bot/InventoryBotView.tsx @@ -1,4 +1,4 @@ -import { GetRoomEngine, IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer'; +import { IRoomSession, RoomPreviewer } from '@nitrots/nitro-renderer'; import { FC, useEffect, useState } from 'react'; import { IBotItem, LocalizeText, UnseenItemCategory, attemptBotPlacement } from '../../../../api'; import { LayoutRoomPreviewerView } from '../../../../common'; @@ -23,19 +23,9 @@ export const InventoryBotView: FC<{ const botData = selectedBot.botData; - 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 : '3001'; - floorType = (floorType && floorType.length) ? floorType : '3002'; - landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1'; - roomPreviewer.reset(false); roomPreviewer.updateRoomWallsAndFloorVisibility(true, true); - roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType); + roomPreviewer.updateObjectRoom('111', '217', '1.1'); roomPreviewer.addAvatarIntoRoom(botData.figure, 0); }, [ roomPreviewer, selectedBot ]); diff --git a/src/components/inventory/views/furniture/InventoryFurnitureView.tsx b/src/components/inventory/views/furniture/InventoryFurnitureView.tsx index c9666c6..fd0f38e 100644 --- a/src/components/inventory/views/furniture/InventoryFurnitureView.tsx +++ b/src/components/inventory/views/furniture/InventoryFurnitureView.tsx @@ -1,5 +1,5 @@ import { InfiniteGrid } from '@layout/InfiniteGrid'; -import { GetRoomEngine, GetSessionDataManager, IRoomSession, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer'; +import { GetSessionDataManager, IRoomSession, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer'; import { FC, useEffect, useState } from 'react'; import { FaPowerOff, FaSyncAlt, FaTrashAlt } from 'react-icons/fa'; import { DispatchUiEvent, FurniCategory, GroupItem, LocalizeText, UnseenItemCategory, attemptItemPlacement } from '../../../../api'; @@ -53,24 +53,17 @@ export const InventoryFurnitureView: FC<{ const isRoomDecoration = (furnitureItem.category === FurniCategory.WALL_PAPER) || (furnitureItem.category === FurniCategory.FLOOR) || (furnitureItem.category === FurniCategory.LANDSCAPE); + let floorType = '111'; + let wallType = '217'; + let landscapeType = '1.1'; + if(isRoomDecoration) { - 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 : '3001'; - floorType = (floorType && floorType.length) ? floorType : '3002'; - landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1'; - - roomPreviewer.updateRoomWallsAndFloorVisibility(true, true); - floorType = ((furnitureItem.category === FurniCategory.FLOOR) ? selectedItem.stuffData.getLegacyString() : floorType); wallType = ((furnitureItem.category === FurniCategory.WALL_PAPER) ? selectedItem.stuffData.getLegacyString() : wallType); landscapeType = ((furnitureItem.category === FurniCategory.LANDSCAPE) ? selectedItem.stuffData.getLegacyString() : landscapeType); + roomPreviewer.updateRoomWallsAndFloorVisibility(true, true); roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType); if(furnitureItem.category === FurniCategory.LANDSCAPE) @@ -83,24 +76,7 @@ export const InventoryFurnitureView: FC<{ return; } - // Mirror the active room's pattern ids so the furniture - // preview lands on the same wallpaper / floor / landscape the - // user is decorated with. Same fallback as the - // isRoomDecoration branch above; 'default' isn't a real - // pattern id, so passing it made the previewer fall back to - // blank white surfaces. - { - 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 : '3001'; - floorType = (floorType && floorType.length) ? floorType : '3002'; - landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1'; - - roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType); - } + roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType); roomPreviewer.updateRoomWallsAndFloorVisibility(true, true); if(selectedItem.isWallItem) diff --git a/src/components/inventory/views/pet/InventoryPetView.tsx b/src/components/inventory/views/pet/InventoryPetView.tsx index aee990a..a684cc2 100644 --- a/src/components/inventory/views/pet/InventoryPetView.tsx +++ b/src/components/inventory/views/pet/InventoryPetView.tsx @@ -1,4 +1,4 @@ -import { DeletePetMessageComposer, GetRoomEngine, IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer'; +import { DeletePetMessageComposer, IRoomSession, RoomPreviewer } from '@nitrots/nitro-renderer'; import { FC, useEffect, useState } from 'react'; import { FaTrashAlt } from 'react-icons/fa'; import { IPetItem, LocalizeText, SendMessageComposer, UnseenItemCategory, attemptPetPlacement } from '../../../../api'; @@ -38,19 +38,10 @@ export const InventoryPetView: FC<{ if(!selectedPet || !roomPreviewer) return; const petData = selectedPet.petData; - 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 : '3001'; - floorType = (floorType && floorType.length) ? floorType : '3002'; - landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1'; roomPreviewer.reset(false); roomPreviewer.updateRoomWallsAndFloorVisibility(true, true); - roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType); + roomPreviewer.updateObjectRoom('111', '217', '1.1'); roomPreviewer.addPetIntoRoom(petData.figureString); }, [ roomPreviewer, selectedPet ]); diff --git a/src/pixiPatch.ts b/src/pixiPatch.ts index 401ae8d..8074720 100644 --- a/src/pixiPatch.ts +++ b/src/pixiPatch.ts @@ -1,34 +1,3 @@ -/** - * Runtime patches for pixi.js v8 batcher edge cases. - * - * Pixi v8 (through 8.19 at least) has a long-running family of crashes - * where `getAdjustedBlendModeBlend(blendMode, textureSource)` is invoked - * with a `null` textureSource and throws on `null.alphaMode` or - * `null.uid`. We've seen it from at least four call sites: - * - Batcher.break() (FilterPipe, StencilMaskPipe, AlphaMaskPipe) - * - Batcher.checkAndUpdateTexture() (SpritePipe.validateRenderable) - * - * The trigger varies, but the symptom is always the same: a single bad - * frame inside the catalog room previewer (or anywhere RoomSpriteCanvas - * drives Pixi) tanks the whole render loop with an endless cascade of - * requestAnimationFrame errors. - * - * We removed the two custom filters we owned (BlackToAlphaFilter, - * PlaneMaskFilter) earlier, but several call sites are inside Pixi - * itself or inside renderer-side mask setup that we can't sensibly - * delete (RoomSpriteCanvas pins a Sprite mask on the master display to - * clip the room to the canvas). - * - * Patch every known throwing entry point so that when it throws because - * of a null textureSource we treat the frame as a no-op instead of - * propagating the exception. The visible cost is a missed batch this - * tick - the next tick re-renders cleanly. Without this patch the - * LayoutRoomPreviewerView safety latch fires permanently on the first - * affected offer. - * - * Importing this module has the side effect of installing the patch - * exactly once, idempotent across HMR reloads. - */ import * as PIXI from 'pixi.js'; type AnyFn = (...args: unknown[]) => unknown; @@ -95,9 +64,7 @@ const installPatch = (): void => const proto = (ctor as { prototype?: MethodHost } | undefined)?.prototype; if(!proto) continue; - // break() is called during FilterPipe / StencilMaskPipe / AlphaMaskPipe.pop if(guardMethod(proto, 'break', name)) patched = true; - // checkAndUpdateTexture() is called during SpritePipe.validateRenderable if(guardMethod(proto, 'checkAndUpdateTexture', name)) patched = true; }