diff --git a/.gitattributes b/.gitattributes index 952d6cd0e9df1e13528d2ea34a59c92582ab37d3..a175917f31ca16f29edb1bd3fa5e26c0ed1b099b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,7 @@ *.svg -diff -text *.psd -diff -text *.ai -diff -text +*.mqo -diff -text +*.glb -diff -text +*.blend -diff -text +*.afdesign -diff -text diff --git a/.gitignore b/.gitignore index e438ad890cf08bfa71c25494e63eef15a41726d7..4baefc147fd6ed429e23be869d591d8a08c1f6aa 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,10 @@ api-docs.json .DS_Store /files ormconfig.json + +# blender backups +*.blend1 +*.blend2 +*.blend3 +*.blend4 +*.blend5 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba45f5d23c0b701ee568a6a9a28f9fdf4d0a03d7..0c3bfa42f75c63f3d78e6d784f8711fe3c9f80b0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,6 +38,16 @@ Documentation of Vue I18n is available at http://kazupon.github.io/vue-i18n/intr Misskey uses CircleCI for executing automated tests. Configuration files are located in [`/.circleci`](/.circleci). +## Adding MisskeyRoom items +Currently, we accept only 3D models created with [Blender](https://www.blender.org/). + +* Use English for material, object and texture names +* Use meter for unit of length +* Your PR must include all source files of your models (for later editing) +* Your PR must include the glTF binary files (.glb) of your models + +You can find information on glTF 2.0 at [glTF 2.0 — Blender Manual]( https://docs.blender.org/manual/en/dev/addons/io_scene_gltf2.html). + ## FAQ ### How to resolve conflictions occurred at yarn.lock? diff --git a/gulpfile.ts b/gulpfile.ts index 85305cd0e44d6c0ef215436c49001a99c5287e89..6ed597731f2db58c45702b86a0cd82d7b232244a 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -47,7 +47,11 @@ gulp.task('build:copy:views', () => gulp.src('./src/server/web/views/**/*').pipe(gulp.dest('./built/server/web/views')) ); -gulp.task('build:copy', gulp.parallel('build:copy:views', () => +gulp.task('build:copy:fonts', () => + gulp.src('./node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/client/assets/fonts/')) +); + +gulp.task('build:copy', gulp.parallel('build:copy:views', 'build:copy:fonts', () => gulp.src([ './src/const.json', './src/server/web/views/**/*', diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index dc9dd87a7f54c3caf279ac16fdf6d9084af5d566..8a34ea935b10cba3a02c7a9b4de2cf0901fd0697 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -308,6 +308,16 @@ common: saved: "ä¿å˜ã—ã¾ã—ãŸ" home-profile: "ホームã®ãƒ—ãƒãƒ•ã‚¡ã‚¤ãƒ«" deck-profile: "デッã‚ã®ãƒ—ãƒãƒ•ã‚¡ã‚¤ãƒ«" + room: "ルーム" + _room: + graphicsQuality: "グラフィックã®å“質" + _graphicsQuality: + ultra: "最高" + high: "高" + medium: "ä¸" + low: "低" + cheep: "最低" + useOrthographicCamera: "平行投影カメラを使用" search: "検索" delete: "削除" @@ -1250,6 +1260,7 @@ desktop/views/components/ui.header.account.vue: groups: "グループ" follow-requests: "フォãƒãƒ¼ç”³è«‹" admin: "管ç†" + room: "ルーム" desktop/views/components/ui.header.nav.vue: game: "ゲーム" @@ -2281,3 +2292,55 @@ pages: enviromentVariables: "環境変数" pageVariables: "ページè¦ç´ " argVariables: "入力スãƒãƒƒãƒˆ" + +room: + add-furniture: "家具を置ã" + translate: "移動" + rotate: "回転" + exit: "戻る" + remove: "ã—ã¾ã†" + save: "ä¿å˜" + chooseImage: "ç”»åƒã‚’é¸æŠž" + room-type: "部屋ã®ã‚¿ã‚¤ãƒ—" + carpet-color: "床ã®è‰²" + rooms: + default: "デフォルト" + washitsu: "和室" + furnitures: + milk: "牛乳パック" + bed: "ベッド" + low-table: "ãƒãƒ¼ãƒ†ãƒ¼ãƒ–ル" + desk: "デスク" + chair: "ãƒã‚§ã‚¢" + chair2: "ãƒã‚§ã‚¢2" + fan: "æ›æ°—扇" + pc: "パソコン" + plant: "観葉æ¤ç‰©" + plant2: "観葉æ¤ç‰©2" + eraser: "消ã—ゴム" + pencil: "鉛ç†" + pudding: "プリン" + cardboard-box: "段ボール箱" + cardboard-box2: "段ボール箱2" + cardboard-box3: "段ボール箱3" + book: "本" + book2: "本2" + piano: "ピアノ" + facial-tissue: "ティッシュボックス" + server: "サーãƒãƒ¼" + moon: "月" + corkboard: "コルクボード" + mousepad: "マウスパッド" + monitor: "モニター" + keyboard: "ã‚ーボード" + carpet-stripe: "カーペット(縞)" + mat: "マット" + color-box: "カラーボックス" + wall-clock: "å£æŽ›ã‘時計" + photoframe: "é¡ç¸" + cube: "ã‚ューブ" + tv: "テレビ" + pinguin: "ピンギン" + rubik-cube: "ルービックã‚ューブ" + poster-h: "ãƒã‚¹ã‚¿ãƒ¼(横長)" + poster-v: "ãƒã‚¹ã‚¿ãƒ¼(縦長)" diff --git a/migration/1565634203341-room.ts b/migration/1565634203341-room.ts new file mode 100644 index 0000000000000000000000000000000000000000..783b375ff9a93be56dc80be8787d7a876ee09ca1 --- /dev/null +++ b/migration/1565634203341-room.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class room1565634203341 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise<any> { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "room" jsonb NOT NULL DEFAULT '{}'`); + } + + public async down(queryRunner: QueryRunner): Promise<any> { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "room"`); + } + +} diff --git a/package.json b/package.json index 5cd0299c0eb860d7ed19715ee332f7b2eacba7d2..85beac348cb57e2e0648cf7cadeb452fb72bbc63 100644 --- a/package.json +++ b/package.json @@ -223,6 +223,7 @@ "syuilo-password-strength": "0.0.1", "terser-webpack-plugin": "1.3.0", "textarea-caret": "3.1.0", + "three": "0.107.0", "tinycolor2": "1.4.1", "tmp": "0.1.0", "ts-loader": "5.3.3", diff --git a/src/client/app/common/scripts/room/furniture.ts b/src/client/app/common/scripts/room/furniture.ts new file mode 100644 index 0000000000000000000000000000000000000000..7734e32668699547a00291fef0d828190f1ed209 --- /dev/null +++ b/src/client/app/common/scripts/room/furniture.ts @@ -0,0 +1,21 @@ +export type RoomInfo = { + roomType: string; + carpetColor: string; + furnitures: Furniture[]; +}; + +export type Furniture = { + id: string; // åŒã˜å®¶å…·ãŒè¤‡æ•°ã‚ã‚‹å ´åˆã«ãã‚Œãžã‚Œã‚’è˜åˆ¥ã™ã‚‹ãŸã‚ã®IDã§ã‚ã‚Šã€å®¶å…·IDã§ã¯ãªã„ + type: string; // ã“ã£ã¡ãŒå®¶å…·ID(chairã¨ã‹) + position: { + x: number; + y: number; + z: number; + }; + rotation: { + x: number; + y: number; + z: number; + }; + props?: Record<string, any>; +}; diff --git a/src/client/app/common/scripts/room/furnitures.json5 b/src/client/app/common/scripts/room/furnitures.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d88228ca36e190076a0bf596869d34ff94a6d8c7 --- /dev/null +++ b/src/client/app/common/scripts/room/furnitures.json5 @@ -0,0 +1,324 @@ +// 家具メタデータ + +// 家具ã«ã¯ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒè¨å®šã§ãるプãƒãƒ‘ティをè¨å®šå¯èƒ½ã§ã™: +// +// props: { +// <propname>: <proptype> +// } +// +// proptype一覧: +// * image ... ç”»åƒé¸æŠžãƒ€ã‚¤ã‚¢ãƒã‚°ã‚’出ã—ã€ãã®ç”»åƒã®URLãŒæ ¼ç´ã•ã‚Œã¾ã™ +// * color ... 色é¸æŠžã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ«ã‚’出ã—ã€é¸æŠžã•ã‚ŒãŸè‰²ãŒæ ¼ç´ã•ã‚Œã¾ã™ + +// 家具ã«ã‚«ã‚¹ã‚¿ãƒ テクスãƒãƒ£ã‚’é©ç”¨ã§ãるよã†ã«ã™ã‚‹ã«ã¯ã€textureプãƒãƒ‘ティã«ä»¥ä¸‹ã®è¿½åŠ ã®æƒ…å ±ã‚’å«ã‚ã¾ã™: +// 便宜上ãã®UVã®ã©ã®éƒ¨åˆ†ã«ã‚«ã‚¹ã‚¿ãƒ テクスãƒãƒ£ã‚’貼りåˆã‚ã›ã‚‹ã‹ã®ã‚¨ãƒªã‚¢ã‚’テクスãƒãƒ£ã‚¨ãƒªã‚¢ã¨å‘¼ã³ã¾ã™ã€‚ +// UVã¯1024*1024ã ã¨ä»®å®šã—ã¾ã™ã€‚ +// +// <key>: { +// prop: <プãƒãƒ‘ティå>, +// uv: { +// x: <テクスãƒãƒ£ã‚¨ãƒªã‚¢X座標>, +// y: <テクスãƒãƒ£ã‚¨ãƒªã‚¢Y座標>, +// width: <テクスãƒãƒ£ã‚¨ãƒªã‚¢ã®å¹…>, +// height: <テクスãƒãƒ£ã‚¨ãƒªã‚¢ã®é«˜ã•>, +// }, +// } +// +// <key>ã«ã¯ã€ã‚«ã‚¹ã‚¿ãƒ テクスãƒãƒ£ã‚’é©ç”¨ã—ãŸã„メッシュåを指定ã—ã¾ã™ +// <プãƒãƒ‘ティå>ã«ã¯ã€ã‚«ã‚¹ã‚¿ãƒ テクスãƒãƒ£ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ç”»åƒã‚’æ ¼ç´ã™ã‚‹ãƒ—ãƒãƒ‘ティ(å‰è¿°)åを指定ã—ã¾ã™ + +// 家具ã«ã‚«ã‚¹ã‚¿ãƒ カラーをé©ç”¨ã§ãるよã†ã«ã™ã‚‹ã«ã¯ã€colorプãƒãƒ‘ティã«ä»¥ä¸‹ã®è¿½åŠ ã®æƒ…å ±ã‚’å«ã‚ã¾ã™: +// +// <key>: <プãƒãƒ‘ティå> +// +// <key>ã«ã¯ã€ã‚«ã‚¹ã‚¿ãƒ カラーをé©ç”¨ã—ãŸã„マテリアルåを指定ã—ã¾ã™ +// <プãƒãƒ‘ティå>ã«ã¯ã€ã‚«ã‚¹ã‚¿ãƒ カラーã¨ã—ã¦ä½¿ç”¨ã™ã‚‹è‰²ã‚’æ ¼ç´ã™ã‚‹ãƒ—ãƒãƒ‘ティ(å‰è¿°)åを指定ã—ã¾ã™ + +[ + { + id: "milk", + place: "floor" + }, + { + id: "bed", + place: "floor" + }, + { + id: "low-table", + place: "floor", + props: { + color: 'color' + }, + color: { + Table: 'color' + } + }, + { + id: "desk", + place: "floor", + props: { + color: 'color' + }, + color: { + Board: 'color' + } + }, + { + id: "chair", + place: "floor", + props: { + color: 'color' + }, + color: { + Chair: 'color' + } + }, + { + id: "chair2", + place: "floor", + props: { + color1: 'color', + color2: 'color' + }, + color: { + Cushion: 'color1', + Leg: 'color2' + } + }, + { + id: "fan", + place: "wall" + }, + { + id: "pc", + place: "floor" + }, + { + id: "plant", + place: "floor" + }, + { + id: "plant2", + place: "floor" + }, + { + id: "eraser", + place: "floor" + }, + { + id: "pencil", + place: "floor" + }, + { + id: "pudding", + place: "floor" + }, + { + id: "cardboard-box", + place: "floor" + }, + { + id: "cardboard-box2", + place: "floor" + }, + { + id: "cardboard-box3", + place: "floor" + }, + { + id: "book", + place: "floor", + props: { + color: 'color' + }, + color: { + Cover: 'color' + } + }, + { + id: "book2", + place: "floor" + }, + { + id: "piano", + place: "floor" + }, + { + id: "facial-tissue", + place: "floor" + }, + { + id: "server", + place: "floor" + }, + { + id: "moon", + place: "floor" + }, + { + id: "corkboard", + place: "wall" + }, + { + id: "mousepad", + place: "floor", + props: { + color: 'color' + }, + color: { + Pad: 'color' + } + }, + { + id: "monitor", + place: "floor", + props: { + screen: 'image' + }, + texture: { + Screen: { + prop: 'screen', + uv: { + x: 0, + y: 434, + width: 1024, + height: 588, + }, + }, + }, + }, + { + id: "tv", + place: "floor", + props: { + screen: 'image' + }, + texture: { + Screen: { + prop: 'screen', + uv: { + x: 0, + y: 434, + width: 1024, + height: 588, + }, + }, + }, + }, + { + id: "keyboard", + place: "floor" + }, + { + id: "carpet-stripe", + place: "floor", + props: { + color1: 'color', + color2: 'color' + }, + color: { + CarpetAreaA: 'color1', + CarpetAreaB: 'color2' + }, + }, + { + id: "mat", + place: "floor", + props: { + color: 'color' + }, + color: { + Mat: 'color' + } + }, + { + id: "color-box", + place: "floor", + props: { + color: 'color' + }, + color: { + main: 'color' + } + }, + { + id: "wall-clock", + place: "wall" + }, + { + id: "cube", + place: "floor", + props: { + color: 'color' + }, + color: { + Cube: 'color' + } + }, + { + id: "photoframe", + place: "wall", + props: { + photo: 'image', + color: 'color' + }, + texture: { + Photo: { + prop: 'photo', + uv: { + x: 0, + y: 342, + width: 1024, + height: 683, + }, + }, + }, + color: { + Frame: 'color' + } + }, + { + id: "pinguin", + place: "floor" + }, + { + id: "rubik-cube", + place: "floor", + }, + { + id: "poster-h", + place: "wall", + props: { + picture: 'image' + }, + texture: { + Poster: { + prop: 'picture', + uv: { + x: 0, + y: 277, + width: 1024, + height: 745, + }, + }, + }, + }, + { + id: "poster-v", + place: "wall", + props: { + picture: 'image' + }, + texture: { + Poster: { + prop: 'picture', + uv: { + x: 0, + y: 0, + width: 745, + height: 1024, + }, + }, + }, + }, +] diff --git a/src/client/app/common/scripts/room/room.ts b/src/client/app/common/scripts/room/room.ts new file mode 100644 index 0000000000000000000000000000000000000000..2a06f5bc5b86169569cc314bac07bff5a1bedece --- /dev/null +++ b/src/client/app/common/scripts/room/room.ts @@ -0,0 +1,690 @@ +import autobind from 'autobind-decorator'; +import * as THREE from 'three'; +import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; +import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; +import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; +import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; +import { BloomPass } from 'three/examples/jsm/postprocessing/BloomPass.js'; +import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'; +import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'; +import { Furniture, RoomInfo } from './furniture'; +import { v4 as uuid } from 'uuid'; +const furnitureDefs = require('./furnitures.json5'); + +THREE.ImageUtils.crossOrigin = ''; + +type Options = { + graphicsQuality: Room['graphicsQuality']; + onChangeSelect: Room['onChangeSelect']; + useOrthographicCamera: boolean; +}; + +export class Room { + private clock: THREE.Clock; + private scene: THREE.Scene; + private renderer: THREE.WebGLRenderer; + private camera: THREE.PerspectiveCamera | THREE.OrthographicCamera; + private controls: OrbitControls; + private composer: EffectComposer; + private mixers: THREE.AnimationMixer[] = []; + private furnitureControl: TransformControls; + private roomInfo: RoomInfo; + private graphicsQuality: 'cheep' | 'low' | 'medium' | 'high' | 'ultra'; + private roomObj: THREE.Object3D; + private objects: THREE.Object3D[] = []; + private selectedObject: THREE.Object3D = null; + private onChangeSelect: Function; + private isTransformMode = false; + public canvas: HTMLCanvasElement; + + private get furnitures(): Furniture[] { + return this.roomInfo.furnitures; + } + + private set furnitures(furnitures: Furniture[]) { + this.roomInfo.furnitures = furnitures; + } + + private get enableShadow() { + return this.graphicsQuality != 'cheep'; + } + + private get usePostFXs() { + return this.graphicsQuality !== 'cheep' && this.graphicsQuality !== 'low'; + } + + private get shadowQuality() { + return ( + this.graphicsQuality === 'ultra' ? 16384 : + this.graphicsQuality === 'high' ? 8192 : + this.graphicsQuality === 'medium' ? 4096 : + this.graphicsQuality === 'low' ? 1024 : + 0); // cheep + } + + constructor(user, isMyRoom, roomInfo: RoomInfo, container, options: Options) { + this.roomInfo = roomInfo; + this.graphicsQuality = options.graphicsQuality; + this.onChangeSelect = options.onChangeSelect; + + this.clock = new THREE.Clock(true); + + //#region Init a scene + this.scene = new THREE.Scene(); + + const width = window.innerWidth; + const height = window.innerHeight; + + //#region Init a renderer + this.renderer = new THREE.WebGLRenderer({ + antialias: false, + stencil: false, + alpha: false, + powerPreference: + this.graphicsQuality === 'ultra' ? 'high-performance' : + this.graphicsQuality === 'high' ? 'high-performance' : + this.graphicsQuality === 'medium' ? 'default' : + this.graphicsQuality === 'low' ? 'low-power' : + 'low-power' // cheep + }); + + this.renderer.setPixelRatio(window.devicePixelRatio); + this.renderer.setSize(width, height); + this.renderer.autoClear = false; + this.renderer.setClearColor(new THREE.Color(0x051f2d)); + this.renderer.shadowMap.enabled = this.enableShadow; + this.renderer.gammaOutput = true; + this.renderer.shadowMap.type = + this.graphicsQuality === 'ultra' ? THREE.PCFSoftShadowMap : + this.graphicsQuality === 'high' ? THREE.PCFSoftShadowMap : + this.graphicsQuality === 'medium' ? THREE.PCFShadowMap : + this.graphicsQuality === 'low' ? THREE.BasicShadowMap : + THREE.BasicShadowMap; // cheep + + this.canvas = this.renderer.domElement; + container.appendChild(this.renderer.domElement); + //#endregion + + //#region Init a camera + this.camera = options.useOrthographicCamera + ? new THREE.OrthographicCamera( + width / - 2, width / 2, height / 2, height / - 2, -10, 10) + : new THREE.PerspectiveCamera(45, width / height); + + if (options.useOrthographicCamera) { + this.camera.position.x = 2; + this.camera.position.y = 2; + this.camera.position.z = 2; + this.camera.zoom = 100; + this.camera.updateProjectionMatrix(); + } else { + this.camera.position.x = 5; + this.camera.position.y = 2; + this.camera.position.z = 5; + } + + this.scene.add(this.camera); + //#endregion + + //#region AmbientLight + const ambientLight = new THREE.AmbientLight(0xffffff, 1); + this.scene.add(ambientLight); + //#endregion + + if (this.graphicsQuality !== 'cheep') { + //#region Room light + const roomLight = new THREE.SpotLight(0xffffff, 0.1); + + roomLight.position.set(0, 8, 0); + roomLight.castShadow = this.enableShadow; + roomLight.shadow.bias = -0.0001; + roomLight.shadow.mapSize.width = this.shadowQuality; + roomLight.shadow.mapSize.height = this.shadowQuality; + roomLight.shadow.camera.near = 0.1; + roomLight.shadow.camera.far = 9; + roomLight.shadow.camera.fov = 45; + + this.scene.add(roomLight); + //#endregion + } + + //#region Out light + const outLight = new THREE.SpotLight(0xffffff, 0.4); + + outLight.position.set(9, 3, -2); + outLight.castShadow = this.enableShadow; + outLight.shadow.bias = -0.001; // アクãƒã€ã‚¢ãƒ¼ãƒãƒ•ã‚¡ã‚¯ãƒˆå¯¾ç– ãã®ä»£ã‚りピーターパンãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ + outLight.shadow.mapSize.width = this.shadowQuality; + outLight.shadow.mapSize.height = this.shadowQuality; + outLight.shadow.camera.near = 6; + outLight.shadow.camera.far = 15; + outLight.shadow.camera.fov = 45; + + this.scene.add(outLight); + //#endregion + + //#region Init a controller + this.controls = new OrbitControls(this.camera, this.renderer.domElement); + + this.controls.target.set(0, 1, 0); + this.controls.enableZoom = true; + this.controls.enablePan = isMyRoom; + this.controls.minPolarAngle = 0; + this.controls.maxPolarAngle = Math.PI / 2; + this.controls.minAzimuthAngle = 0; + this.controls.maxAzimuthAngle = Math.PI / 2; + this.controls.enableDamping = true; + this.controls.dampingFactor = 0.2; + this.controls.mouseButtons.LEFT = 1; + this.controls.mouseButtons.MIDDLE = 2; + this.controls.mouseButtons.RIGHT = 0; + //#endregion + + //#region POST FXs + if (!this.usePostFXs) { + this.composer = null; + } else { + const renderTarget = new THREE.WebGLRenderTarget(width, height, { + minFilter: THREE.LinearFilter, + magFilter: THREE.LinearFilter, + format: THREE.RGBFormat, + stencilBuffer: false, + }); + + const fxaa = new ShaderPass(FXAAShader); + fxaa.uniforms['resolution'].value = new THREE.Vector2(1 / width, 1 / height); + fxaa.renderToScreen = true; + + this.composer = new EffectComposer(this.renderer, renderTarget); + this.composer.addPass(new RenderPass(this.scene, this.camera)); + if (this.graphicsQuality === 'ultra') { + this.composer.addPass(new BloomPass(0.25, 30, 128.0, 512)); + } + this.composer.addPass(fxaa); + } + //#endregion + //#endregion + + //#region Label + //#region Avatar + const avatarUrl = user.avatarUrl; + + const iconTexture = new THREE.TextureLoader().load(avatarUrl); + iconTexture.wrapS = THREE.RepeatWrapping; + iconTexture.wrapT = THREE.RepeatWrapping; + iconTexture.anisotropy = 16; + + const avatarMaterial = new THREE.MeshLambertMaterial({ + emissive: 0x111111, + map: iconTexture, + side: THREE.DoubleSide, + alphaTest: 0.5 + }); + + const iconGeometry = new THREE.PlaneGeometry(1, 1); + + const avatarObject = new THREE.Mesh(iconGeometry, avatarMaterial); + avatarObject.position.set(-3, 2.5, 2); + avatarObject.rotation.y = Math.PI / 2; + avatarObject.castShadow = false; + + this.scene.add(avatarObject); + //#endregion + + //#region Username + const name = user.username; + + new THREE.FontLoader().load('/assets/fonts/helvetiker_regular.typeface.json', font => { + const nameGeometry = new THREE.TextGeometry(name, { + size: 0.5, + height: 0, + curveSegments: 8, + font: font, + bevelThickness: 0, + bevelSize: 0, + bevelEnabled: false + }); + + const nameMaterial = new THREE.MeshLambertMaterial({ + color: 0xffffff + }); + + const nameObject = new THREE.Mesh(nameGeometry, nameMaterial); + nameObject.position.set(-3, 2.25, 1.25); + nameObject.rotation.y = Math.PI / 2; + nameObject.castShadow = false; + + this.scene.add(nameObject); + }); + //#endregion + //#endregion + + //#region Interaction + if (isMyRoom) { + this.furnitureControl = new TransformControls(this.camera, this.renderer.domElement); + this.scene.add(this.furnitureControl); + + // Hover highlight + this.renderer.domElement.onmousemove = this.onmousemove; + + // Click + this.renderer.domElement.onmousedown = this.onmousedown; + } + //#endregion + + //#region Init room + this.loadRoom(); + //#endregion + + //#region Load furnitures + for (const furniture of this.furnitures) { + this.loadFurniture(furniture).then(obj => { + this.scene.add(obj.scene); + this.objects.push(obj.scene); + }); + } + //#endregion + + // Start render + if (this.usePostFXs) { + this.renderWithPostFXs(); + } else { + this.renderWithoutPostFXs(); + } + } + + @autobind + private renderWithoutPostFXs() { + requestAnimationFrame(this.renderWithoutPostFXs); + + // Update animations + const clock = this.clock.getDelta(); + for (const mixer of this.mixers) { + mixer.update(clock); + } + + this.controls.update(); + this.renderer.render(this.scene, this.camera); + } + + @autobind + private renderWithPostFXs() { + requestAnimationFrame(this.renderWithPostFXs); + + // Update animations + const clock = this.clock.getDelta(); + for (const mixer of this.mixers) { + mixer.update(clock); + } + + this.controls.update(); + this.renderer.clear(); + this.composer.render(); + } + + @autobind + private loadRoom() { + new GLTFLoader().load(`/assets/room/rooms/${this.roomInfo.roomType}/${this.roomInfo.roomType}.glb`, gltf => { + gltf.scene.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + + child.receiveShadow = this.enableShadow; + + child.material = new THREE.MeshLambertMaterial({ + color: (child.material as THREE.MeshStandardMaterial).color, + map: (child.material as THREE.MeshStandardMaterial).map, + name: (child.material as THREE.MeshStandardMaterial).name, + }); + + // 異方性フィルタリング + if ((child.material as THREE.MeshLambertMaterial).map && this.graphicsQuality !== 'cheep') { + (child.material as THREE.MeshLambertMaterial).map.minFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshLambertMaterial).map.magFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshLambertMaterial).map.anisotropy = 8; + } + }); + + gltf.scene.position.set(0, 0, 0); + + this.scene.add(gltf.scene); + this.roomObj = gltf.scene; + if (this.roomInfo.roomType === 'default') { + this.applyCarpetColor(); + } + }); + } + + @autobind + private loadFurniture(furniture: Furniture) { + const def = furnitureDefs.find(d => d.id === furniture.type); + return new Promise<GLTF>((res, rej) => { + const loader = new GLTFLoader(); + loader.load(`/assets/room/furnitures/${furniture.type}/${furniture.type}.glb`, gltf => { + const model = gltf.scene; + + // Load animation + if (gltf.animations.length > 0) { + const mixer = new THREE.AnimationMixer(model); + this.mixers.push(mixer); + for (const clip of gltf.animations) { + mixer.clipAction(clip).play(); + } + } + + model.name = furniture.id; + model.position.x = furniture.position.x; + model.position.y = furniture.position.y; + model.position.z = furniture.position.z; + model.rotation.x = furniture.rotation.x; + model.rotation.y = furniture.rotation.y; + model.rotation.z = furniture.rotation.z; + + model.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + child.castShadow = this.enableShadow; + child.receiveShadow = this.enableShadow; + child.material = new THREE.MeshLambertMaterial({ + color: (child.material as THREE.MeshStandardMaterial).color, + map: (child.material as THREE.MeshStandardMaterial).map, + name: (child.material as THREE.MeshStandardMaterial).name, + }); + + // 異方性フィルタリング + if ((child.material as THREE.MeshLambertMaterial).map && this.graphicsQuality !== 'cheep') { + (child.material as THREE.MeshLambertMaterial).map.minFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshLambertMaterial).map.magFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshLambertMaterial).map.anisotropy = 8; + } + }); + + if (def.color) { // カスタムカラー + this.applyCustomColor(model); + } + + if (def.texture) { // カスタムテクスãƒãƒ£ + this.applyCustomTexture(model); + } + + res(gltf); + }, null, rej); + }); + } + + @autobind + private applyCarpetColor() { + this.roomObj.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + if (child.material && (child.material as THREE.MeshStandardMaterial).name && (child.material as THREE.MeshStandardMaterial).name === 'Carpet') { + (child.material as THREE.MeshStandardMaterial).color.setHex(parseInt(this.roomInfo.carpetColor.substr(1), 16)); + } + }); + } + + @autobind + public applyCustomColor(model: THREE.Object3D) { + const furniture = this.furnitures.find(furniture => furniture.id === model.name); + const def = furnitureDefs.find(d => d.id === furniture.type); + if (def.color == null) return; + model.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + for (const t of Object.keys(def.color)) { + if (!child.material || !(child.material as THREE.MeshStandardMaterial).name || (child.material as THREE.MeshStandardMaterial).name !== t) continue; + + const prop = def.color[t]; + const val = furniture.props ? furniture.props[prop] : undefined; + + if (val == null) continue; + + (child.material as THREE.MeshStandardMaterial).color.setHex(parseInt(val.substr(1), 16)); + } + }); + } + + @autobind + public applyCustomTexture(model: THREE.Object3D) { + const furniture = this.furnitures.find(furniture => furniture.id === model.name); + const def = furnitureDefs.find(d => d.id === furniture.type); + if (def.texture == null) return; + model.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + for (const t of Object.keys(def.texture)) { + if (child.name !== t) continue; + + const prop = def.texture[t].prop; + const val = furniture.props ? furniture.props[prop] : undefined; + + if (val == null) continue; + + const canvas = document.createElement('canvas'); + canvas.height = 1024; + canvas.width = 1024; + + child.material = new THREE.MeshLambertMaterial({ + emissive: 0x111111, + side: THREE.DoubleSide, + alphaTest: 0.5, + }); + + const img = new Image(); + img.onload = () => { + const uvInfo = def.texture[t].uv; + + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0, img.width, img.height, uvInfo.x, uvInfo.y, uvInfo.width, uvInfo.height); + + const texture = new THREE.Texture(canvas); + texture.wrapS = THREE.RepeatWrapping; + texture.wrapT = THREE.RepeatWrapping; + texture.anisotropy = 16; + texture.flipY = false; + + (child.material as THREE.MeshLambertMaterial).map = texture; + (child.material as THREE.MeshLambertMaterial).needsUpdate = true; + (child.material as THREE.MeshLambertMaterial).map.needsUpdate = true; + }; + img.src = val; + } + }); + } + + @autobind + private onmousemove(ev: MouseEvent) { + if (this.isTransformMode) return; + + const rect = (ev.target as HTMLElement).getBoundingClientRect(); + const x = (((ev.clientX * window.devicePixelRatio) - rect.left) / this.renderer.domElement.width) * 2 - 1; + const y = -(((ev.clientY * window.devicePixelRatio) - rect.top) / this.renderer.domElement.height) * 2 + 1; + const pos = new THREE.Vector2(x, y); + + this.camera.updateMatrixWorld(); + + const raycaster = new THREE.Raycaster(); + raycaster.setFromCamera(pos, this.camera); + + const intersects = raycaster.intersectObjects(this.objects, true); + + for (const object of this.objects) { + if (this.isSelectedObject(object)) continue; + object.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000); + } + }); + } + + if (intersects.length > 0) { + const intersected = this.getRoot(intersects[0].object); + if (!this.isSelectedObject(intersected)) { + intersected.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x191919); + } + }); + } + } + } + + @autobind + private onmousedown(ev: MouseEvent) { + if (this.isTransformMode) return; + if (ev.target !== this.renderer.domElement || ev.button !== 0) return; + + const rect = (ev.target as HTMLElement).getBoundingClientRect(); + const x = (((ev.clientX * window.devicePixelRatio) - rect.left) / this.renderer.domElement.width) * 2 - 1; + const y = -(((ev.clientY * window.devicePixelRatio) - rect.top) / this.renderer.domElement.height) * 2 + 1; + const pos = new THREE.Vector2(x, y); + + this.camera.updateMatrixWorld(); + + const raycaster = new THREE.Raycaster(); + raycaster.setFromCamera(pos, this.camera); + + const intersects = raycaster.intersectObjects(this.objects, true); + + for (const object of this.objects) { + object.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000); + } + }); + } + + if (intersects.length > 0) { + const selectedObj = this.getRoot(intersects[0].object); + this.selectFurniture(selectedObj); + } else { + this.selectedObject = null; + this.onChangeSelect(null); + } + } + + @autobind + private getRoot(obj: THREE.Object3D): THREE.Object3D { + let found = false; + let x = obj.parent; + while (!found) { + if (x.parent.parent == null) { + found = true; + } else { + x = x.parent; + } + } + return x; + } + + @autobind + private isSelectedObject(obj: THREE.Object3D): boolean { + if (this.selectedObject == null) { + return false; + } else { + return obj.name === this.selectedObject.name; + } + } + + @autobind + private selectFurniture(obj: THREE.Object3D) { + this.selectedObject = obj; + this.onChangeSelect(obj); + obj.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0xff0000); + } + }); + } + + @autobind + public enterTransformMode(type: 'translate' | 'rotate') { + this.isTransformMode = true; + this.furnitureControl.setMode(type); + this.furnitureControl.attach(this.selectedObject); + } + + @autobind + public exitTransformMode() { + this.isTransformMode = false; + this.furnitureControl.detach(); + } + + @autobind + public updateProp(key: string, value: any) { + const furniture = this.furnitures.find(furniture => furniture.id === this.selectedObject.name); + if (furniture.props == null) furniture.props = {}; + furniture.props[key] = value; + this.applyCustomColor(this.selectedObject); + this.applyCustomTexture(this.selectedObject); + } + + @autobind + public addFurniture(type: string) { + const furniture = { + id: uuid(), + type: type, + position: { + x: 0, + y: 0, + z: 0, + }, + rotation: { + x: 0, + y: 0, + z: 0, + }, + }; + + this.furnitures.push(furniture); + + this.loadFurniture(furniture).then(obj => { + this.scene.add(obj.scene); + this.objects.push(obj.scene); + }); + } + + @autobind + public removeFurniture() { + const obj = this.selectedObject; + this.scene.remove(obj); + this.objects = this.objects.filter(object => object.name !== obj.name); + this.furnitures = this.furnitures.filter(furniture => furniture.id !== obj.name); + this.selectedObject = null; + this.onChangeSelect(null); + } + + @autobind + public updateCarpetColor(color: string) { + this.roomInfo.carpetColor = color; + this.applyCarpetColor(); + } + + @autobind + public changeRoomType(type: string) { + this.roomInfo.roomType = type; + this.scene.remove(this.roomObj); + this.loadRoom(); + } + + @autobind + public getRoomInfo() { + for (const obj of this.objects) { + const furniture = this.furnitures.find(f => f.id === obj.name); + furniture.position.x = obj.position.x; + furniture.position.y = obj.position.y; + furniture.position.z = obj.position.z; + furniture.rotation.x = obj.rotation.x; + furniture.rotation.y = obj.rotation.y; + furniture.rotation.z = obj.rotation.z; + } + + return this.roomInfo; + } + + @autobind + public getSelectedObject() { + return this.selectedObject; + } + + @autobind + public findFurnitureById(id: string) { + return this.furnitures.find(furniture => furniture.id === id); + } +} diff --git a/src/client/app/common/views/components/settings/settings.vue b/src/client/app/common/views/components/settings/settings.vue index c609a9672288cf2a397ddd84a2817c42f7fc85eb..914d5bf84f178dda4a2740df48a8dd46a343cc2e 100644 --- a/src/client/app/common/views/components/settings/settings.vue +++ b/src/client/app/common/views/components/settings/settings.vue @@ -159,6 +159,19 @@ <template #desc>{{ $t('@._settings.paste-dialog-desc') }}</template> </ui-switch> </section> + + <section> + <header>{{ $t('@._settings.room') }}</header> + <ui-select v-model="roomGraphicsQuality"> + <template #label>{{ $t('@._settings._room.graphicsQuality') }}</template> + <option value="ultra">{{ $t('@._settings._room._graphicsQuality.ultra') }}</option> + <option value="high">{{ $t('@._settings._room._graphicsQuality.high') }}</option> + <option value="medium">{{ $t('@._settings._room._graphicsQuality.medium') }}</option> + <option value="low">{{ $t('@._settings._room._graphicsQuality.low') }}</option> + <option value="cheep">{{ $t('@._settings._room._graphicsQuality.cheep') }}</option> + </ui-select> + <ui-switch v-model="roomUseOrthographicCamera">{{ $t('@._settings._room.useOrthographicCamera') }}</ui-switch> + </section> </ui-card> <ui-card> @@ -503,6 +516,16 @@ export default Vue.extend({ set(value) { this.$store.dispatch('settings/set', { key: 'iLikeSushi', value }); } }, + roomUseOrthographicCamera: { + get() { return this.$store.state.device.roomUseOrthographicCamera; }, + set(value) { this.$store.commit('device/set', { key: 'roomUseOrthographicCamera', value }); } + }, + + roomGraphicsQuality: { + get() { return this.$store.state.device.roomGraphicsQuality; }, + set(value) { this.$store.commit('device/set', { key: 'roomGraphicsQuality', value }); } + }, + games_reversi_showBoardLabels: { get() { return this.$store.state.settings.gamesReversiShowBoardLabels; }, set(value) { this.$store.dispatch('settings/set', { key: 'gamesReversiShowBoardLabels', value }); } diff --git a/src/client/app/common/views/pages/room/preview.vue b/src/client/app/common/views/pages/room/preview.vue new file mode 100644 index 0000000000000000000000000000000000000000..3f849d8c0465ba492b0443f60c71c32df08e2e23 --- /dev/null +++ b/src/client/app/common/views/pages/room/preview.vue @@ -0,0 +1,98 @@ +<template> +<canvas width=224 height=128></canvas> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import * as THREE from 'three'; + +export default Vue.extend({ + data() { + return { + selected: null, + objectHeight: 0 + }; + }, + + mounted() { + const canvas = this.$el; + + const width = canvas.width; + const height = canvas.height; + + const scene = new THREE.Scene(); + + const renderer = new THREE.WebGLRenderer({ + canvas: canvas, + antialias: true, + alpha: false + }); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(width, height); + renderer.setClearColor(0x000000); + renderer.autoClear = false; + renderer.shadowMap.enabled = true; + renderer.shadowMap.cullFace = THREE.CullFaceBack; + + const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 100); + camera.zoom = 10; + camera.position.x = 0; + camera.position.y = 2; + camera.position.z = 0; + camera.updateProjectionMatrix(); + scene.add(camera); + + const ambientLight = new THREE.AmbientLight(0xffffff, 1); + ambientLight.castShadow = false; + scene.add(ambientLight); + + const light = new THREE.PointLight(0xffffff, 1, 100); + light.position.set(3, 3, 3); + scene.add(light); + + const grid = new THREE.GridHelper(5, 16, 0x444444, 0x222222); + scene.add(grid); + + const render = () => { + const timer = Date.now() * 0.0004; + requestAnimationFrame(render); + + camera.position.y = 2 + this.objectHeight / 2; + camera.position.z = Math.cos(timer) * 10; + camera.position.x = Math.sin(timer) * 10; + camera.lookAt(new THREE.Vector3(0, this.objectHeight / 2, 0)); + renderer.render(scene, camera); + }; + + this.selected = selected => { + const obj = selected.clone(); + + // Remove current object + const current = scene.getObjectByName('obj'); + if (current != null) { + scene.remove(current); + } + + // Add new object + obj.name = 'obj'; + obj.position.x = 0; + obj.position.y = 0; + obj.position.z = 0; + obj.rotation.x = 0; + obj.rotation.y = 0; + obj.rotation.z = 0; + obj.traverse(child => { + if (child instanceof THREE.Mesh) { + child.material = child.material.clone(); + return child.material.emissive.setHex(0x000000); + } + }); + const objectBoundingBox = new THREE.Box3().setFromObject(obj); + this.objectHeight = objectBoundingBox.max.y - objectBoundingBox.min.y; + scene.add(obj); + }; + + render(); + }, +}); +</script> diff --git a/src/client/app/common/views/pages/room/room.vue b/src/client/app/common/views/pages/room/room.vue new file mode 100644 index 0000000000000000000000000000000000000000..955e35701e527e031c1d63d648d7762ed6b381ed --- /dev/null +++ b/src/client/app/common/views/pages/room/room.vue @@ -0,0 +1,237 @@ +<template> +<div class="hveuntkp"> + <div class="controller" v-if="objectSelected"> + <section> + <p class="name">{{ selectedFurnitureName }}</p> + <x-preview ref="preview"/> + <template v-if="selectedFurnitureInfo.props"> + <div v-for="k in Object.keys(selectedFurnitureInfo.props)" :key="k"> + <p>{{ k }}</p> + <template v-if="selectedFurnitureInfo.props[k] === 'image'"> + <ui-button @click="chooseImage(k)">{{ $t('chooseImage') }}</ui-button> + </template> + <template v-else-if="selectedFurnitureInfo.props[k] === 'color'"> + <input type="color" :value="selectedFurnitureProps ? selectedFurnitureProps[k] : null" @change="updateColor(k, $event)"/> + </template> + </div> + </template> + </section> + <section> + <ui-button @click="translate()" :primary="isTranslateMode"><fa :icon="faArrowsAlt"/> {{ $t('translate') }}</ui-button> + <ui-button @click="rotate()" :primary="isRotateMode"><fa :icon="faUndo"/> {{ $t('rotate') }}</ui-button> + <ui-button v-if="isTranslateMode || isRotateMode" @click="exit()"><fa :icon="faBan"/> {{ $t('exit') }}</ui-button> + </section> + <section> + <ui-button @click="remove()"><fa :icon="faTrashAlt"/> {{ $t('remove') }}</ui-button> + </section> + </div> + <div class="menu"> + <section> + <ui-button @click="add()"><fa :icon="faBoxOpen"/> {{ $t('add-furniture') }}</ui-button> + </section> + <section> + <ui-select :value="roomType" @input="updateRoomType($event)"> + <template #label>{{ $t('room-type') }}</template> + <option value="default">{{ $t('rooms.default') }}</option> + <option value="washitsu">{{ $t('rooms.washitsu') }}</option> + </ui-select> + <label v-if="roomType === 'default'"> + <span>{{ $t('carpet-color') }}</span> + <input type="color" :value="carpetColor" @change="updateCarpetColor($event)"/> + </label> + </section> + <section> + <ui-button primary @click="save()"><fa :icon="faSave"/> {{ $t('save') }}</ui-button> + </section> + </div> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import i18n from '../../../../i18n'; +import { Room } from '../../../scripts/room/room'; +import parseAcct from '../../../../../../misc/acct/parse'; +import XPreview from './preview.vue'; +const storeItems = require('../../../scripts/room/furnitures.json5'); +import { faBoxOpen, faUndo, faArrowsAlt, faBan } from '@fortawesome/free-solid-svg-icons'; +import { faSave, faTrashAlt } from '@fortawesome/free-regular-svg-icons'; + +let room: Room; + +export default Vue.extend({ + i18n: i18n('room'), + + components: { + XPreview + }, + + props: { + acct: { + type: String, + required: true + }, + }, + + data() { + return { + objectSelected: false, + selectedFurnitureName: null, + selectedFurnitureInfo: null, + selectedFurnitureProps: null, + roomType: null, + carpetColor: null, + isTranslateMode: false, + isRotateMode: false, + faBoxOpen, faSave, faTrashAlt, faUndo, faArrowsAlt, faBan, + }; + }, + + async mounted() { + const user = await this.$root.api('users/show', { + ...parseAcct(this.acct) + }); + + const roomInfo = await this.$root.api('room/show', { + userId: user.id + }); + + this.roomType = roomInfo.roomType; + this.carpetColor = roomInfo.carpetColor; + + room = new Room(user, this.$store.getters.isSignedIn && this.$store.state.i.id === user.id, roomInfo, this.$el, { + graphicsQuality: this.$store.state.device.roomGraphicsQuality, + onChangeSelect: obj => { + this.objectSelected = obj != null; + if (obj) { + const f = room.findFurnitureById(obj.name); + this.selectedFurnitureName = this.$t('furnitures.' + f.type); + this.selectedFurnitureInfo = storeItems.find(x => x.id === f.type); + this.selectedFurnitureProps = f.props + ? JSON.parse(JSON.stringify(f.props)) // Disable reactivity + : null; + this.$nextTick(() => { + this.$refs.preview.selected(obj); + }); + } + }, + useOrthographicCamera: this.$store.state.device.roomUseOrthographicCamera + }); + }, + + methods: { + async add() { + const { canceled, result: id } = await this.$root.dialog({ + type: null, + title: this.$t('add-furniture'), + select: { + items: storeItems.map(item => ({ + value: item.id, text: this.$t('furnitures.' + item.id) + })) + }, + showCancelButton: true + }); + if (canceled) return; + room.addFurniture(id); + }, + + remove() { + room.removeFurniture(); + }, + + save() { + this.$root.api('room/update', { + room: room.getRoomInfo() + }); + }, + + chooseImage(key) { + this.$chooseDriveFile({ + multiple: false + }).then(file => { + room.updateProp(key, file.thumbnailUrl); + this.$refs.preview.selected(room.getSelectedObject()); + }); + }, + + updateColor(key, ev) { + room.updateProp(key, ev.target.value); + this.$refs.preview.selected(room.getSelectedObject()); + }, + + updateCarpetColor(ev) { + room.updateCarpetColor(ev.target.value); + this.carpetColor = ev.target.value; + }, + + updateRoomType(type) { + room.changeRoomType(type); + this.roomType = type; + }, + + translate() { + if (this.isTranslateMode) { + this.exit(); + } else { + this.isRotateMode = false; + this.isTranslateMode = true; + room.enterTransformMode('translate'); + } + }, + + rotate() { + if (this.isRotateMode) { + this.exit(); + } else { + this.isTranslateMode = false; + this.isRotateMode = true; + room.enterTransformMode('rotate'); + } + }, + + exit() { + this.isTranslateMode = false; + this.isRotateMode = false; + room.exitTransformMode(); + } + } +}); +</script> + +<style lang="stylus" scoped> +.hveuntkp + > .controller + > .menu + position fixed + z-index 1 + padding 16px + background var(--face) + color var(--text) + + > section + padding 16px 0 + + &:first-child + padding-top 0 + + &:last-child + padding-bottom 0 + + &:not(:last-child) + border-bottom solid 1px var(--faceDivider) + + > .controller + top 16px + left 16px + width 256px + + > section + > .name + margin 0 + + > .menu + top 16px + right 16px + width 256px + +</style> diff --git a/src/client/app/desktop/script.ts b/src/client/app/desktop/script.ts index 32e4886de313612257fd3cb5e7f5f5e1faad441e..f77a00ae6b00b5ef32d2709c37f1e4cc94129fd4 100644 --- a/src/client/app/desktop/script.ts +++ b/src/client/app/desktop/script.ts @@ -187,6 +187,7 @@ init(async (launch, os) => { { path: '/i/drive/folder/:folder', component: MkDrive }, { path: '/i/settings', component: MkSettings }, { path: '/selectdrive', component: MkSelectDrive }, + { path: '/@:acct/room', props: true, component: () => import('../common/views/pages/room/room.vue').then(m => m.default) }, { path: '/share', component: MkShare }, { path: '/games/reversi/:game?', component: MkReversi }, { path: '/authorize-follow', component: MkFollow }, diff --git a/src/client/app/desktop/views/components/ui.header.account.vue b/src/client/app/desktop/views/components/ui.header.account.vue index 5d7ed8c302ffb4e4a91d48ba514a583773cf7c37..690f3a5587df14f6497adef2da11ee3f3ee9fb5f 100644 --- a/src/client/app/desktop/views/components/ui.header.account.vue +++ b/src/client/app/desktop/views/components/ui.header.account.vue @@ -56,6 +56,13 @@ <i><fa icon="angle-right"/></i> </router-link> </li> + <li> + <router-link :to="`/@${ $store.state.i.username }/room`"> + <i><fa :icon="faDoorOpen" fixed-width/></i> + <span>{{ $t('room') }}</span> + <i><fa icon="angle-right"/></i> + </router-link> + </li> </ul> <ul> <li> @@ -106,7 +113,7 @@ import i18n from '../../../i18n'; // import MkSettingsWindow from './settings-window.vue'; import MkDriveWindow from './drive-window.vue'; import contains from '../../../common/scripts/contains'; -import { faHome, faColumns, faUsers } from '@fortawesome/free-solid-svg-icons'; +import { faHome, faColumns, faUsers, faDoorOpen } from '@fortawesome/free-solid-svg-icons'; import { faMoon, faSun, faStickyNote } from '@fortawesome/free-regular-svg-icons'; export default Vue.extend({ @@ -114,7 +121,7 @@ export default Vue.extend({ data() { return { isOpen: false, - faHome, faColumns, faMoon, faSun, faStickyNote, faUsers + faHome, faColumns, faMoon, faSun, faStickyNote, faUsers, faDoorOpen }; }, computed: { diff --git a/src/client/app/store.ts b/src/client/app/store.ts index d9f1631a828c1ef483c66ee2410e7096710241a5..92fb1568b035f8b627c7d1994014be02270bb86e 100644 --- a/src/client/app/store.ts +++ b/src/client/app/store.ts @@ -76,6 +76,8 @@ const defaultDeviceSettings = { expandUsersPhotos: true, expandUsersActivity: true, enableMobileQuickNotificationView: false, + roomGraphicsQuality: 'medium', + roomUseOrthographicCamera: true, }; export default (os: MiOS) => new Vuex.Store({ diff --git a/src/client/app/tsconfig.json b/src/client/app/tsconfig.json index 8605da75ab769d2d0de87c5b10488cf5966c7ea4..3ec0271f63af9da39401a1910484dff4bbfeba7e 100644 --- a/src/client/app/tsconfig.json +++ b/src/client/app/tsconfig.json @@ -11,11 +11,17 @@ "sourceMap": false, "target": "es2017", "module": "esnext", + "moduleResolution": "node", "removeComments": false, "noLib": false, "strict": true, "strictNullChecks": false, - "experimentalDecorators": true + "experimentalDecorators": true, + "resolveJsonModule": true, + "typeRoots": [ + "node_modules/@types", + "src/@types" + ] }, "compileOnSave": false, "include": [ diff --git a/src/client/assets/room/furnitures/bed/bed.blend b/src/client/assets/room/furnitures/bed/bed.blend new file mode 100644 index 0000000000000000000000000000000000000000..731df76d0cd735d34f95bfaf05331ca2a6aa6909 Binary files /dev/null and b/src/client/assets/room/furnitures/bed/bed.blend differ diff --git a/src/client/assets/room/furnitures/bed/bed.glb b/src/client/assets/room/furnitures/bed/bed.glb new file mode 100644 index 0000000000000000000000000000000000000000..f35ecb9ef4125801c5f2ff036bc7463abfdabe70 Binary files /dev/null and b/src/client/assets/room/furnitures/bed/bed.glb differ diff --git a/src/client/assets/room/furnitures/book/book.blend b/src/client/assets/room/furnitures/book/book.blend new file mode 100644 index 0000000000000000000000000000000000000000..0d4899d4aec991e1f53e6f77d8c89d58159bf948 Binary files /dev/null and b/src/client/assets/room/furnitures/book/book.blend differ diff --git a/src/client/assets/room/furnitures/book/book.glb b/src/client/assets/room/furnitures/book/book.glb new file mode 100644 index 0000000000000000000000000000000000000000..546893da06b256e8a5e9710525961a01dc9439bb Binary files /dev/null and b/src/client/assets/room/furnitures/book/book.glb differ diff --git a/src/client/assets/room/furnitures/book2/barcode.png b/src/client/assets/room/furnitures/book2/barcode.png new file mode 100644 index 0000000000000000000000000000000000000000..269485422744a5f2e8e248be9fd19a00d31a9fbd Binary files /dev/null and b/src/client/assets/room/furnitures/book2/barcode.png differ diff --git a/src/client/assets/room/furnitures/book2/book2.blend b/src/client/assets/room/furnitures/book2/book2.blend new file mode 100644 index 0000000000000000000000000000000000000000..e0fdb4810197caad280ed2d1e715d9e254827a04 Binary files /dev/null and b/src/client/assets/room/furnitures/book2/book2.blend differ diff --git a/src/client/assets/room/furnitures/book2/book2.glb b/src/client/assets/room/furnitures/book2/book2.glb new file mode 100644 index 0000000000000000000000000000000000000000..2b26402f8ca80bf96517241bf1d0ba1c359605e2 Binary files /dev/null and b/src/client/assets/room/furnitures/book2/book2.glb differ diff --git a/src/client/assets/room/furnitures/book2/texture.afdesign b/src/client/assets/room/furnitures/book2/texture.afdesign new file mode 100644 index 0000000000000000000000000000000000000000..b63771607a035da290e5e27f7d9b5824857440c2 Binary files /dev/null and b/src/client/assets/room/furnitures/book2/texture.afdesign differ diff --git a/src/client/assets/room/furnitures/book2/texture.png b/src/client/assets/room/furnitures/book2/texture.png new file mode 100644 index 0000000000000000000000000000000000000000..f34328cb4a6563fc097b35a0c791814116cc3da6 Binary files /dev/null and b/src/client/assets/room/furnitures/book2/texture.png differ diff --git a/src/client/assets/room/furnitures/book2/uv.png b/src/client/assets/room/furnitures/book2/uv.png new file mode 100644 index 0000000000000000000000000000000000000000..9d282d0b6943cb348131ad9cdf031deaae605f78 Binary files /dev/null and b/src/client/assets/room/furnitures/book2/uv.png differ diff --git a/src/client/assets/room/furnitures/cardboard-box/cardboard-box.blend b/src/client/assets/room/furnitures/cardboard-box/cardboard-box.blend new file mode 100644 index 0000000000000000000000000000000000000000..3a528de32a376053a00fc5c9564ed9ebca1a011f Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box/cardboard-box.blend differ diff --git a/src/client/assets/room/furnitures/cardboard-box/cardboard-box.glb b/src/client/assets/room/furnitures/cardboard-box/cardboard-box.glb new file mode 100644 index 0000000000000000000000000000000000000000..bed372e94f8b7bd18a272e8a38f5835cbc3a20ca Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box/cardboard-box.glb differ diff --git a/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend b/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend new file mode 100644 index 0000000000000000000000000000000000000000..5f146267acf22370b4b7a6d60ace5217b3db91f7 Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend differ diff --git a/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb b/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb new file mode 100644 index 0000000000000000000000000000000000000000..85fcb5c0b60ebf15658dc49b687c7bda51843a5d Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb differ diff --git a/src/client/assets/room/furnitures/cardboard-box2/texture.png b/src/client/assets/room/furnitures/cardboard-box2/texture.png new file mode 100644 index 0000000000000000000000000000000000000000..abc1b3de64825ba198993cfa8971e060d035b90c Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box2/texture.png differ diff --git a/src/client/assets/room/furnitures/cardboard-box2/uv.png b/src/client/assets/room/furnitures/cardboard-box2/uv.png new file mode 100644 index 0000000000000000000000000000000000000000..104c141b2cd10e9ebb463f71b672306f63d074b4 Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box2/uv.png differ diff --git a/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend b/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend new file mode 100644 index 0000000000000000000000000000000000000000..00681a3cfd5060e42378fd2e2fe6646074a6f862 Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend differ diff --git a/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb b/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb new file mode 100644 index 0000000000000000000000000000000000000000..1ef04276894f0c0f7b29533074d5716fb18d66a9 Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb differ diff --git a/src/client/assets/room/furnitures/cardboard-box3/texture.png b/src/client/assets/room/furnitures/cardboard-box3/texture.png new file mode 100644 index 0000000000000000000000000000000000000000..e68292dce003c6a5e3b98e7fcde9029f07dc58aa Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box3/texture.png differ diff --git a/src/client/assets/room/furnitures/cardboard-box3/texture.xcf b/src/client/assets/room/furnitures/cardboard-box3/texture.xcf new file mode 100644 index 0000000000000000000000000000000000000000..7ffb3e3439d30c22841d77510c8d85815ced9475 Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box3/texture.xcf differ diff --git a/src/client/assets/room/furnitures/cardboard-box3/uv.png b/src/client/assets/room/furnitures/cardboard-box3/uv.png new file mode 100644 index 0000000000000000000000000000000000000000..3ac23ef5844e6d2b324598ea4a309921e995a2b4 Binary files /dev/null and b/src/client/assets/room/furnitures/cardboard-box3/uv.png differ diff --git a/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend b/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend new file mode 100644 index 0000000000000000000000000000000000000000..750343d4f00fc9af30c5158cfc0c517d73e2e02a Binary files /dev/null and b/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend differ diff --git a/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb b/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb new file mode 100644 index 0000000000000000000000000000000000000000..3066a69e353c4ab6668f6c010a804ac258e6f26a Binary files /dev/null and b/src/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb differ diff --git a/src/client/assets/room/furnitures/chair/chair.blend b/src/client/assets/room/furnitures/chair/chair.blend new file mode 100644 index 0000000000000000000000000000000000000000..79c29a840145a21373a2bb7a635b57745a57007f Binary files /dev/null and b/src/client/assets/room/furnitures/chair/chair.blend differ diff --git a/src/client/assets/room/furnitures/chair/chair.glb b/src/client/assets/room/furnitures/chair/chair.glb new file mode 100644 index 0000000000000000000000000000000000000000..08ee1a0bb0fc569dad8b900fb8c0d5ab2cef4716 Binary files /dev/null and b/src/client/assets/room/furnitures/chair/chair.glb differ diff --git a/src/client/assets/room/furnitures/chair2/chair2.blend b/src/client/assets/room/furnitures/chair2/chair2.blend new file mode 100644 index 0000000000000000000000000000000000000000..c6a1acd96f5f5347536e31d99ee36d25e8e775d6 Binary files /dev/null and b/src/client/assets/room/furnitures/chair2/chair2.blend differ diff --git a/src/client/assets/room/furnitures/chair2/chair2.glb b/src/client/assets/room/furnitures/chair2/chair2.glb new file mode 100644 index 0000000000000000000000000000000000000000..5ea2f3518b692efe6e5237aae464ba594c3f755c Binary files /dev/null and b/src/client/assets/room/furnitures/chair2/chair2.glb differ diff --git a/src/client/assets/room/furnitures/color-box/color-box.blend b/src/client/assets/room/furnitures/color-box/color-box.blend new file mode 100644 index 0000000000000000000000000000000000000000..f96a4ff76633b20fb292504702c0816e06859ce7 Binary files /dev/null and b/src/client/assets/room/furnitures/color-box/color-box.blend differ diff --git a/src/client/assets/room/furnitures/color-box/color-box.glb b/src/client/assets/room/furnitures/color-box/color-box.glb new file mode 100644 index 0000000000000000000000000000000000000000..43f2abcae8ff2471236a5936844179edb4f154ec Binary files /dev/null and b/src/client/assets/room/furnitures/color-box/color-box.glb differ diff --git a/src/client/assets/room/furnitures/corkboard/corkboard.blend b/src/client/assets/room/furnitures/corkboard/corkboard.blend new file mode 100644 index 0000000000000000000000000000000000000000..9a7e1878cda339fc9f22151d9904bdddde7f892f Binary files /dev/null and b/src/client/assets/room/furnitures/corkboard/corkboard.blend differ diff --git a/src/client/assets/room/furnitures/corkboard/corkboard.glb b/src/client/assets/room/furnitures/corkboard/corkboard.glb new file mode 100644 index 0000000000000000000000000000000000000000..fee108fb91519ca8ec3f7dc9637db5dde02c6a6d Binary files /dev/null and b/src/client/assets/room/furnitures/corkboard/corkboard.glb differ diff --git a/src/client/assets/room/furnitures/cube/cube.blend b/src/client/assets/room/furnitures/cube/cube.blend new file mode 100644 index 0000000000000000000000000000000000000000..1af5bf40a9d3c63d4a8345bc34b36f4e36f8fdfe Binary files /dev/null and b/src/client/assets/room/furnitures/cube/cube.blend differ diff --git a/src/client/assets/room/furnitures/cube/cube.glb b/src/client/assets/room/furnitures/cube/cube.glb new file mode 100644 index 0000000000000000000000000000000000000000..4ac8b6036d22ea22981582ee87e529277acab4c5 Binary files /dev/null and b/src/client/assets/room/furnitures/cube/cube.glb differ diff --git a/src/client/assets/room/furnitures/desk/desk.blend b/src/client/assets/room/furnitures/desk/desk.blend new file mode 100644 index 0000000000000000000000000000000000000000..c88d01f0b233ec40c4475b2555d21386d9037691 Binary files /dev/null and b/src/client/assets/room/furnitures/desk/desk.blend differ diff --git a/src/client/assets/room/furnitures/desk/desk.glb b/src/client/assets/room/furnitures/desk/desk.glb new file mode 100644 index 0000000000000000000000000000000000000000..4a58513095884e46661b178bc50b41140eeb3a47 Binary files /dev/null and b/src/client/assets/room/furnitures/desk/desk.glb differ diff --git a/src/client/assets/room/furnitures/eraser/cover.png b/src/client/assets/room/furnitures/eraser/cover.png new file mode 100644 index 0000000000000000000000000000000000000000..e64bfde11a56ef8d59c4649e9c9296eefc39cbf3 Binary files /dev/null and b/src/client/assets/room/furnitures/eraser/cover.png differ diff --git a/src/client/assets/room/furnitures/eraser/cover.psd b/src/client/assets/room/furnitures/eraser/cover.psd new file mode 100644 index 0000000000000000000000000000000000000000..c393337833d4d76f28a4f2de33ace2ce863f3b1c Binary files /dev/null and b/src/client/assets/room/furnitures/eraser/cover.psd differ diff --git a/src/client/assets/room/furnitures/eraser/eraser-uv.png b/src/client/assets/room/furnitures/eraser/eraser-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..2124114e70b890fb13e78afb1cc25c54df960b06 Binary files /dev/null and b/src/client/assets/room/furnitures/eraser/eraser-uv.png differ diff --git a/src/client/assets/room/furnitures/eraser/eraser.blend b/src/client/assets/room/furnitures/eraser/eraser.blend new file mode 100644 index 0000000000000000000000000000000000000000..103c54fbae3f04db34ad3ad7cd36102890a393fb Binary files /dev/null and b/src/client/assets/room/furnitures/eraser/eraser.blend differ diff --git a/src/client/assets/room/furnitures/eraser/eraser.glb b/src/client/assets/room/furnitures/eraser/eraser.glb new file mode 100644 index 0000000000000000000000000000000000000000..016b60df202459182cb66c6f12b13222f8a88ae8 Binary files /dev/null and b/src/client/assets/room/furnitures/eraser/eraser.glb differ diff --git a/src/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png b/src/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..b6dfa8f30851575cc183890251a076e9d761f3b0 Binary files /dev/null and b/src/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png differ diff --git a/src/client/assets/room/furnitures/facial-tissue/facial-tissue.blend b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.blend new file mode 100644 index 0000000000000000000000000000000000000000..d59f87c1ee5482a6f375585fba575a60a4d454a8 Binary files /dev/null and b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.blend differ diff --git a/src/client/assets/room/furnitures/facial-tissue/facial-tissue.glb b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.glb new file mode 100644 index 0000000000000000000000000000000000000000..48b36ef34729727ff186714aaf6f08f473115eaa Binary files /dev/null and b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.glb differ diff --git a/src/client/assets/room/furnitures/facial-tissue/facial-tissue.png b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.png new file mode 100644 index 0000000000000000000000000000000000000000..f25c882027e0f9b11647291df5cca9b8459a20d1 Binary files /dev/null and b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.png differ diff --git a/src/client/assets/room/furnitures/facial-tissue/facial-tissue.psd b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.psd new file mode 100644 index 0000000000000000000000000000000000000000..cd59fc007bb0d4c2472a99ec2326b8f8284cae87 Binary files /dev/null and b/src/client/assets/room/furnitures/facial-tissue/facial-tissue.psd differ diff --git a/src/client/assets/room/furnitures/fan/fan.blend b/src/client/assets/room/furnitures/fan/fan.blend new file mode 100644 index 0000000000000000000000000000000000000000..8c8106e5fe61f92fce0e3e3f359bba90474a5576 Binary files /dev/null and b/src/client/assets/room/furnitures/fan/fan.blend differ diff --git a/src/client/assets/room/furnitures/fan/fan.glb b/src/client/assets/room/furnitures/fan/fan.glb new file mode 100644 index 0000000000000000000000000000000000000000..d9367f353407b2a9f66841ef2ac373e322ca64b5 Binary files /dev/null and b/src/client/assets/room/furnitures/fan/fan.glb differ diff --git a/src/client/assets/room/furnitures/keyboard/keyboard.blend b/src/client/assets/room/furnitures/keyboard/keyboard.blend new file mode 100644 index 0000000000000000000000000000000000000000..ab33d134b3d99491c34b8557628c944948d01ce9 Binary files /dev/null and b/src/client/assets/room/furnitures/keyboard/keyboard.blend differ diff --git a/src/client/assets/room/furnitures/keyboard/keyboard.glb b/src/client/assets/room/furnitures/keyboard/keyboard.glb new file mode 100644 index 0000000000000000000000000000000000000000..15dc69f47a4d5390dd2f5e83045cf1577ae98a75 Binary files /dev/null and b/src/client/assets/room/furnitures/keyboard/keyboard.glb differ diff --git a/src/client/assets/room/furnitures/low-table/low-table.blend b/src/client/assets/room/furnitures/low-table/low-table.blend new file mode 100644 index 0000000000000000000000000000000000000000..e1592174d9963b9996cdf1969ecc96885c31d2a5 Binary files /dev/null and b/src/client/assets/room/furnitures/low-table/low-table.blend differ diff --git a/src/client/assets/room/furnitures/low-table/low-table.glb b/src/client/assets/room/furnitures/low-table/low-table.glb new file mode 100644 index 0000000000000000000000000000000000000000..c69bf35d7b52eda2434c4a3db91a3c5f695e4adf Binary files /dev/null and b/src/client/assets/room/furnitures/low-table/low-table.glb differ diff --git a/src/client/assets/room/furnitures/mat/mat.blend b/src/client/assets/room/furnitures/mat/mat.blend new file mode 100644 index 0000000000000000000000000000000000000000..a1e1a68c554e93b9b63f54801310d6f34a83d161 Binary files /dev/null and b/src/client/assets/room/furnitures/mat/mat.blend differ diff --git a/src/client/assets/room/furnitures/mat/mat.glb b/src/client/assets/room/furnitures/mat/mat.glb new file mode 100644 index 0000000000000000000000000000000000000000..87ccd44e1a2fcb07c7ea55c7561bff356c5f6d70 Binary files /dev/null and b/src/client/assets/room/furnitures/mat/mat.glb differ diff --git a/src/client/assets/room/furnitures/milk/milk-uv.png b/src/client/assets/room/furnitures/milk/milk-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..70060c91909bab23f3cc677d4878e487170cd023 Binary files /dev/null and b/src/client/assets/room/furnitures/milk/milk-uv.png differ diff --git a/src/client/assets/room/furnitures/milk/milk.blend b/src/client/assets/room/furnitures/milk/milk.blend new file mode 100644 index 0000000000000000000000000000000000000000..2df508d5b905dbc1ee0df0f5b755c5949dc66681 Binary files /dev/null and b/src/client/assets/room/furnitures/milk/milk.blend differ diff --git a/src/client/assets/room/furnitures/milk/milk.glb b/src/client/assets/room/furnitures/milk/milk.glb new file mode 100644 index 0000000000000000000000000000000000000000..b335fe3d021b227bcec7f82d13133442f1fe84cf Binary files /dev/null and b/src/client/assets/room/furnitures/milk/milk.glb differ diff --git a/src/client/assets/room/furnitures/milk/milk.png b/src/client/assets/room/furnitures/milk/milk.png new file mode 100644 index 0000000000000000000000000000000000000000..2ce010ce785e3029283135be67aa96a45403d967 Binary files /dev/null and b/src/client/assets/room/furnitures/milk/milk.png differ diff --git a/src/client/assets/room/furnitures/milk/milk.psd b/src/client/assets/room/furnitures/milk/milk.psd new file mode 100644 index 0000000000000000000000000000000000000000..f31e439277821d8ad26e4a6f68c00d80cac2f8ba Binary files /dev/null and b/src/client/assets/room/furnitures/milk/milk.psd differ diff --git a/src/client/assets/room/furnitures/monitor/monitor.blend b/src/client/assets/room/furnitures/monitor/monitor.blend new file mode 100644 index 0000000000000000000000000000000000000000..bf37cd5da2cc1623d313ef07ffd0025802dadd51 Binary files /dev/null and b/src/client/assets/room/furnitures/monitor/monitor.blend differ diff --git a/src/client/assets/room/furnitures/monitor/monitor.glb b/src/client/assets/room/furnitures/monitor/monitor.glb new file mode 100644 index 0000000000000000000000000000000000000000..efe42bd71ceb6fbfa3dff0970c73093e88ca75ee Binary files /dev/null and b/src/client/assets/room/furnitures/monitor/monitor.glb differ diff --git a/src/client/assets/room/furnitures/monitor/monitor.psd b/src/client/assets/room/furnitures/monitor/monitor.psd new file mode 100644 index 0000000000000000000000000000000000000000..57afff9cd9ef9717b57fee8df33bc5bd4814da1e Binary files /dev/null and b/src/client/assets/room/furnitures/monitor/monitor.psd differ diff --git a/src/client/assets/room/furnitures/monitor/screen-uv.png b/src/client/assets/room/furnitures/monitor/screen-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..55990873643265fc53b45e432a485af145f5c0e6 Binary files /dev/null and b/src/client/assets/room/furnitures/monitor/screen-uv.png differ diff --git a/src/client/assets/room/furnitures/monitor/screen.jpg b/src/client/assets/room/furnitures/monitor/screen.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6f03a9ee90c5b94108703c5017ce0399472717fe Binary files /dev/null and b/src/client/assets/room/furnitures/monitor/screen.jpg differ diff --git a/src/client/assets/room/furnitures/moon/moon.blend b/src/client/assets/room/furnitures/moon/moon.blend new file mode 100644 index 0000000000000000000000000000000000000000..4ff3deab8ec8c6cdc7ade407b72a8fe5ba28c782 Binary files /dev/null and b/src/client/assets/room/furnitures/moon/moon.blend differ diff --git a/src/client/assets/room/furnitures/moon/moon.glb b/src/client/assets/room/furnitures/moon/moon.glb new file mode 100644 index 0000000000000000000000000000000000000000..07fa7e4c02a9b1902ca137b08e10266c040bfa48 Binary files /dev/null and b/src/client/assets/room/furnitures/moon/moon.glb differ diff --git a/src/client/assets/room/furnitures/moon/moon.jpg b/src/client/assets/room/furnitures/moon/moon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b0798755ce745cd6888215ac59d65b5b6e19190 Binary files /dev/null and b/src/client/assets/room/furnitures/moon/moon.jpg differ diff --git a/src/client/assets/room/furnitures/mousepad/mousepad.blend b/src/client/assets/room/furnitures/mousepad/mousepad.blend new file mode 100644 index 0000000000000000000000000000000000000000..14bd139c94a03e0b26685de5431e6fe9893d87ed Binary files /dev/null and b/src/client/assets/room/furnitures/mousepad/mousepad.blend differ diff --git a/src/client/assets/room/furnitures/mousepad/mousepad.glb b/src/client/assets/room/furnitures/mousepad/mousepad.glb new file mode 100644 index 0000000000000000000000000000000000000000..681ada49cd93e18d9b01f111c1de8a0fd6e7b460 Binary files /dev/null and b/src/client/assets/room/furnitures/mousepad/mousepad.glb differ diff --git a/src/client/assets/room/furnitures/pc/motherboard-uv.png b/src/client/assets/room/furnitures/pc/motherboard-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..490ae868106d28e00d9af6c84bd7e8f026602be8 Binary files /dev/null and b/src/client/assets/room/furnitures/pc/motherboard-uv.png differ diff --git a/src/client/assets/room/furnitures/pc/motherboard-uv.psd b/src/client/assets/room/furnitures/pc/motherboard-uv.psd new file mode 100644 index 0000000000000000000000000000000000000000..971f33f79eadfdda3e206d09a23aa17d04ac16fa Binary files /dev/null and b/src/client/assets/room/furnitures/pc/motherboard-uv.psd differ diff --git a/src/client/assets/room/furnitures/pc/motherboard.jpg b/src/client/assets/room/furnitures/pc/motherboard.jpg new file mode 100644 index 0000000000000000000000000000000000000000..415f8d0b1d1ac3edd7c6ffeb7ab1ae0256a3ec13 Binary files /dev/null and b/src/client/assets/room/furnitures/pc/motherboard.jpg differ diff --git a/src/client/assets/room/furnitures/pc/pc.blend b/src/client/assets/room/furnitures/pc/pc.blend new file mode 100644 index 0000000000000000000000000000000000000000..13dfec6ccc27bdd13bfdcb5d9eec42fcaf75b7b0 Binary files /dev/null and b/src/client/assets/room/furnitures/pc/pc.blend differ diff --git a/src/client/assets/room/furnitures/pc/pc.glb b/src/client/assets/room/furnitures/pc/pc.glb new file mode 100644 index 0000000000000000000000000000000000000000..44a48b18ae6031bf312552636e50c9014391e667 Binary files /dev/null and b/src/client/assets/room/furnitures/pc/pc.glb differ diff --git a/src/client/assets/room/furnitures/pencil/pencil.blend b/src/client/assets/room/furnitures/pencil/pencil.blend new file mode 100644 index 0000000000000000000000000000000000000000..0fc6bdd77699df7874b90b5694ff6e17c0d71a3c Binary files /dev/null and b/src/client/assets/room/furnitures/pencil/pencil.blend differ diff --git a/src/client/assets/room/furnitures/pencil/pencil.glb b/src/client/assets/room/furnitures/pencil/pencil.glb new file mode 100644 index 0000000000000000000000000000000000000000..a938b5cdcc759f46990adfa9e2656587e7070400 Binary files /dev/null and b/src/client/assets/room/furnitures/pencil/pencil.glb differ diff --git a/src/client/assets/room/furnitures/photoframe/photo-uv.png b/src/client/assets/room/furnitures/photoframe/photo-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..befa32c3678847f76f2f8ad83afbec879b819c71 Binary files /dev/null and b/src/client/assets/room/furnitures/photoframe/photo-uv.png differ diff --git a/src/client/assets/room/furnitures/photoframe/photo.jpg b/src/client/assets/room/furnitures/photoframe/photo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9597571fef05f4f16330458bc0c936e8750415f3 Binary files /dev/null and b/src/client/assets/room/furnitures/photoframe/photo.jpg differ diff --git a/src/client/assets/room/furnitures/photoframe/photoframe.blend b/src/client/assets/room/furnitures/photoframe/photoframe.blend new file mode 100644 index 0000000000000000000000000000000000000000..4224cde45b42b17acd08e3a98eb4d990d543e27f Binary files /dev/null and b/src/client/assets/room/furnitures/photoframe/photoframe.blend differ diff --git a/src/client/assets/room/furnitures/photoframe/photoframe.glb b/src/client/assets/room/furnitures/photoframe/photoframe.glb new file mode 100644 index 0000000000000000000000000000000000000000..4255a77de6ccaacec292f79c0dec650bb22137c7 Binary files /dev/null and b/src/client/assets/room/furnitures/photoframe/photoframe.glb differ diff --git a/src/client/assets/room/furnitures/piano/piano.blend b/src/client/assets/room/furnitures/piano/piano.blend new file mode 100644 index 0000000000000000000000000000000000000000..7653cdf672f6599d66e43aa71a1cf657c54e7f6f Binary files /dev/null and b/src/client/assets/room/furnitures/piano/piano.blend differ diff --git a/src/client/assets/room/furnitures/piano/piano.glb b/src/client/assets/room/furnitures/piano/piano.glb new file mode 100644 index 0000000000000000000000000000000000000000..7242e78ceb4a382243d37cc5c326a26684033461 Binary files /dev/null and b/src/client/assets/room/furnitures/piano/piano.glb differ diff --git a/src/client/assets/room/furnitures/pinguin/pinguin.glb b/src/client/assets/room/furnitures/pinguin/pinguin.glb new file mode 100644 index 0000000000000000000000000000000000000000..0ddf611ad94ba4530a01301ab467556ad36fc725 Binary files /dev/null and b/src/client/assets/room/furnitures/pinguin/pinguin.glb differ diff --git a/src/client/assets/room/furnitures/plant/plant-soil-uv.png b/src/client/assets/room/furnitures/plant/plant-soil-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..ca690fdeb8354088ef0086308df6947133158720 Binary files /dev/null and b/src/client/assets/room/furnitures/plant/plant-soil-uv.png differ diff --git a/src/client/assets/room/furnitures/plant/plant-soil.png b/src/client/assets/room/furnitures/plant/plant-soil.png new file mode 100644 index 0000000000000000000000000000000000000000..dc26ba062e4bb923c484a3641bb5e0333a4586a4 Binary files /dev/null and b/src/client/assets/room/furnitures/plant/plant-soil.png differ diff --git a/src/client/assets/room/furnitures/plant/plant-soil.psd b/src/client/assets/room/furnitures/plant/plant-soil.psd new file mode 100644 index 0000000000000000000000000000000000000000..1457b7ea5b3086877beb83ab3bb822648c8a8d4f Binary files /dev/null and b/src/client/assets/room/furnitures/plant/plant-soil.psd differ diff --git a/src/client/assets/room/furnitures/plant/plant.blend b/src/client/assets/room/furnitures/plant/plant.blend new file mode 100644 index 0000000000000000000000000000000000000000..aa38c7b54e4e6656a713b97964a1de0b8ea36b48 Binary files /dev/null and b/src/client/assets/room/furnitures/plant/plant.blend differ diff --git a/src/client/assets/room/furnitures/plant/plant.glb b/src/client/assets/room/furnitures/plant/plant.glb new file mode 100644 index 0000000000000000000000000000000000000000..38422b4a9b2940de45816684ae45c77599382995 Binary files /dev/null and b/src/client/assets/room/furnitures/plant/plant.glb differ diff --git a/src/client/assets/room/furnitures/plant2/plant2.blend b/src/client/assets/room/furnitures/plant2/plant2.blend new file mode 100644 index 0000000000000000000000000000000000000000..6592c5d98d91007550d41cdfd27e3da08f17bb3e Binary files /dev/null and b/src/client/assets/room/furnitures/plant2/plant2.blend differ diff --git a/src/client/assets/room/furnitures/plant2/plant2.glb b/src/client/assets/room/furnitures/plant2/plant2.glb new file mode 100644 index 0000000000000000000000000000000000000000..223e6f58340f9a9ba76c8aac4777ca3ccfb51a0c Binary files /dev/null and b/src/client/assets/room/furnitures/plant2/plant2.glb differ diff --git a/src/client/assets/room/furnitures/plant2/soil.png b/src/client/assets/room/furnitures/plant2/soil.png new file mode 100644 index 0000000000000000000000000000000000000000..dc26ba062e4bb923c484a3641bb5e0333a4586a4 Binary files /dev/null and b/src/client/assets/room/furnitures/plant2/soil.png differ diff --git a/src/client/assets/room/furnitures/poster-h/poster-h.blend b/src/client/assets/room/furnitures/poster-h/poster-h.blend new file mode 100644 index 0000000000000000000000000000000000000000..40f944f3c115f9d3aaf966f6b7f06e436c85d9e4 Binary files /dev/null and b/src/client/assets/room/furnitures/poster-h/poster-h.blend differ diff --git a/src/client/assets/room/furnitures/poster-h/poster-h.glb b/src/client/assets/room/furnitures/poster-h/poster-h.glb new file mode 100644 index 0000000000000000000000000000000000000000..c6032c100979c713e6d6a4a15f30f7dcec160e6d Binary files /dev/null and b/src/client/assets/room/furnitures/poster-h/poster-h.glb differ diff --git a/src/client/assets/room/furnitures/poster-h/uv.png b/src/client/assets/room/furnitures/poster-h/uv.png new file mode 100644 index 0000000000000000000000000000000000000000..700e6b1cf0b39885d6525705a76822f7da814653 Binary files /dev/null and b/src/client/assets/room/furnitures/poster-h/uv.png differ diff --git a/src/client/assets/room/furnitures/poster-v/poster-v.blend b/src/client/assets/room/furnitures/poster-v/poster-v.blend new file mode 100644 index 0000000000000000000000000000000000000000..07fe971634f2f9df6ab8802f670ebd09c41adf65 Binary files /dev/null and b/src/client/assets/room/furnitures/poster-v/poster-v.blend differ diff --git a/src/client/assets/room/furnitures/poster-v/poster-v.glb b/src/client/assets/room/furnitures/poster-v/poster-v.glb new file mode 100644 index 0000000000000000000000000000000000000000..6e3782f19364233453bfee6d4af8451614af6de5 Binary files /dev/null and b/src/client/assets/room/furnitures/poster-v/poster-v.glb differ diff --git a/src/client/assets/room/furnitures/poster-v/uv.png b/src/client/assets/room/furnitures/poster-v/uv.png new file mode 100644 index 0000000000000000000000000000000000000000..225b0061a2c91eccb48e44abe3f09b3875c26442 Binary files /dev/null and b/src/client/assets/room/furnitures/poster-v/uv.png differ diff --git a/src/client/assets/room/furnitures/pudding/pudding.blend b/src/client/assets/room/furnitures/pudding/pudding.blend new file mode 100644 index 0000000000000000000000000000000000000000..bba40ce161d37b08e974cbc875ee5193ffbfe862 Binary files /dev/null and b/src/client/assets/room/furnitures/pudding/pudding.blend differ diff --git a/src/client/assets/room/furnitures/pudding/pudding.glb b/src/client/assets/room/furnitures/pudding/pudding.glb new file mode 100644 index 0000000000000000000000000000000000000000..06c9ed80cc1507fc8562d12b7b3cf849897580fa Binary files /dev/null and b/src/client/assets/room/furnitures/pudding/pudding.glb differ diff --git a/src/client/assets/room/furnitures/rubik-cube/rubik-cube.blend b/src/client/assets/room/furnitures/rubik-cube/rubik-cube.blend new file mode 100644 index 0000000000000000000000000000000000000000..6c09067e78bfce812853e715ed6b467fd87ab2d4 Binary files /dev/null and b/src/client/assets/room/furnitures/rubik-cube/rubik-cube.blend differ diff --git a/src/client/assets/room/furnitures/rubik-cube/rubik-cube.glb b/src/client/assets/room/furnitures/rubik-cube/rubik-cube.glb new file mode 100644 index 0000000000000000000000000000000000000000..d640df9b06e50757d021866fb6eeda54ad272296 Binary files /dev/null and b/src/client/assets/room/furnitures/rubik-cube/rubik-cube.glb differ diff --git a/src/client/assets/room/furnitures/server/rack-uv.png b/src/client/assets/room/furnitures/server/rack-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..c317bd0b1a08a3b7d5470b0fd52e1345d977365c Binary files /dev/null and b/src/client/assets/room/furnitures/server/rack-uv.png differ diff --git a/src/client/assets/room/furnitures/server/rack.png b/src/client/assets/room/furnitures/server/rack.png new file mode 100644 index 0000000000000000000000000000000000000000..2c8231f878990916fbba92549d4ab730c48e62d7 Binary files /dev/null and b/src/client/assets/room/furnitures/server/rack.png differ diff --git a/src/client/assets/room/furnitures/server/server.blend b/src/client/assets/room/furnitures/server/server.blend new file mode 100644 index 0000000000000000000000000000000000000000..6675dfbdc2f020c98cb755bd1989de2a753b107a Binary files /dev/null and b/src/client/assets/room/furnitures/server/server.blend differ diff --git a/src/client/assets/room/furnitures/server/server.glb b/src/client/assets/room/furnitures/server/server.glb new file mode 100644 index 0000000000000000000000000000000000000000..a8b530a2d22ee5cce3e76ac644c55f64e7e2f041 Binary files /dev/null and b/src/client/assets/room/furnitures/server/server.glb differ diff --git a/src/client/assets/room/furnitures/server/server.png b/src/client/assets/room/furnitures/server/server.png new file mode 100644 index 0000000000000000000000000000000000000000..ac62a8b1655681eede0b8d4a904dd598d6bb7d9e Binary files /dev/null and b/src/client/assets/room/furnitures/server/server.png differ diff --git a/src/client/assets/room/furnitures/server/uv.png b/src/client/assets/room/furnitures/server/uv.png new file mode 100644 index 0000000000000000000000000000000000000000..6c7e4950146a0b60f218e33f1bbc1faae1fd29d1 Binary files /dev/null and b/src/client/assets/room/furnitures/server/uv.png differ diff --git a/src/client/assets/room/furnitures/tv/screen-uv.png b/src/client/assets/room/furnitures/tv/screen-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..c02e01c2e5bb1dbc804f93ffbdc04e1532e3bd32 Binary files /dev/null and b/src/client/assets/room/furnitures/tv/screen-uv.png differ diff --git a/src/client/assets/room/furnitures/tv/tv.blend b/src/client/assets/room/furnitures/tv/tv.blend new file mode 100644 index 0000000000000000000000000000000000000000..490e298e7b24dd1928fd4d39d7f54b7fdea63250 Binary files /dev/null and b/src/client/assets/room/furnitures/tv/tv.blend differ diff --git a/src/client/assets/room/furnitures/tv/tv.glb b/src/client/assets/room/furnitures/tv/tv.glb new file mode 100644 index 0000000000000000000000000000000000000000..b9bd23896b394fd59991885296acea68b6b37dcd Binary files /dev/null and b/src/client/assets/room/furnitures/tv/tv.glb differ diff --git a/src/client/assets/room/furnitures/wall-clock/wall-clock.blend b/src/client/assets/room/furnitures/wall-clock/wall-clock.blend new file mode 100644 index 0000000000000000000000000000000000000000..0a61c8f01e3eab209e3a2ed73fbfc13feaaa84b7 Binary files /dev/null and b/src/client/assets/room/furnitures/wall-clock/wall-clock.blend differ diff --git a/src/client/assets/room/furnitures/wall-clock/wall-clock.glb b/src/client/assets/room/furnitures/wall-clock/wall-clock.glb new file mode 100644 index 0000000000000000000000000000000000000000..b9f0093a8dc470e2783a9a53b97a021e330ee037 Binary files /dev/null and b/src/client/assets/room/furnitures/wall-clock/wall-clock.glb differ diff --git a/src/client/assets/room/rooms/default/default.blend b/src/client/assets/room/rooms/default/default.blend new file mode 100644 index 0000000000000000000000000000000000000000..661154724aafc4b46db0d6100e0be6a9458335a7 Binary files /dev/null and b/src/client/assets/room/rooms/default/default.blend differ diff --git a/src/client/assets/room/rooms/default/default.glb b/src/client/assets/room/rooms/default/default.glb new file mode 100644 index 0000000000000000000000000000000000000000..3d378deee2a9c63add57a19753481a18e409c81a Binary files /dev/null and b/src/client/assets/room/rooms/default/default.glb differ diff --git a/src/client/assets/room/rooms/washitsu/husuma-uv.png b/src/client/assets/room/rooms/washitsu/husuma-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..3d0b08f488132b19c306ab54b2435c873fbe9197 Binary files /dev/null and b/src/client/assets/room/rooms/washitsu/husuma-uv.png differ diff --git a/src/client/assets/room/rooms/washitsu/husuma.png b/src/client/assets/room/rooms/washitsu/husuma.png new file mode 100644 index 0000000000000000000000000000000000000000..fd1f5ef23185d0a6b84cf3be8889cafd3f07d91f Binary files /dev/null and b/src/client/assets/room/rooms/washitsu/husuma.png differ diff --git a/src/client/assets/room/rooms/washitsu/tatami-single1600.png b/src/client/assets/room/rooms/washitsu/tatami-single1600.png new file mode 100644 index 0000000000000000000000000000000000000000..49fd2d64763ec46768fa80e8ea77d05fe8d675f8 Binary files /dev/null and b/src/client/assets/room/rooms/washitsu/tatami-single1600.png differ diff --git a/src/client/assets/room/rooms/washitsu/tatami-uv.png b/src/client/assets/room/rooms/washitsu/tatami-uv.png new file mode 100644 index 0000000000000000000000000000000000000000..b4bba33850d8a4c698da3fa4d744841fd05a36ec Binary files /dev/null and b/src/client/assets/room/rooms/washitsu/tatami-uv.png differ diff --git a/src/client/assets/room/rooms/washitsu/tatami.afdesign b/src/client/assets/room/rooms/washitsu/tatami.afdesign new file mode 100644 index 0000000000000000000000000000000000000000..9300a26950a1ab857fe71d41893c8eb2b5429ba1 Binary files /dev/null and b/src/client/assets/room/rooms/washitsu/tatami.afdesign differ diff --git a/src/client/assets/room/rooms/washitsu/tatami.png b/src/client/assets/room/rooms/washitsu/tatami.png new file mode 100644 index 0000000000000000000000000000000000000000..2137d4eca737c9aa22dc09c65192ca3f9cc39b91 Binary files /dev/null and b/src/client/assets/room/rooms/washitsu/tatami.png differ diff --git a/src/client/assets/room/rooms/washitsu/washitsu.blend b/src/client/assets/room/rooms/washitsu/washitsu.blend new file mode 100644 index 0000000000000000000000000000000000000000..84dc11374d63314bc95b4556ad0c588dc420cb98 Binary files /dev/null and b/src/client/assets/room/rooms/washitsu/washitsu.blend differ diff --git a/src/client/assets/room/rooms/washitsu/washitsu.glb b/src/client/assets/room/rooms/washitsu/washitsu.glb new file mode 100644 index 0000000000000000000000000000000000000000..5b4767bc73d5c27e677c6b3832e7900ecbeb7604 Binary files /dev/null and b/src/client/assets/room/rooms/washitsu/washitsu.glb differ diff --git a/src/models/entities/user-profile.ts b/src/models/entities/user-profile.ts index 61e80049c3fa46f2d7118182bbd413ad58979850..1244fa43902cbfb58700a0631d3d905352e56475 100644 --- a/src/models/entities/user-profile.ts +++ b/src/models/entities/user-profile.ts @@ -99,6 +99,12 @@ export class UserProfile { }) public clientData: Record<string, any>; + @Column('jsonb', { + default: {}, + comment: 'The room data of the User.' + }) + public room: Record<string, any>; + @Column('boolean', { default: false, }) diff --git a/src/server/api/endpoints/room/show.ts b/src/server/api/endpoints/room/show.ts new file mode 100644 index 0000000000000000000000000000000000000000..17634834acc008df0d921ae8ec9735a22d1226aa --- /dev/null +++ b/src/server/api/endpoints/room/show.ts @@ -0,0 +1,92 @@ +import $ from 'cafy'; +import define from '../../define'; +import { ApiError } from '../../error'; +import { Users, UserProfiles } from '../../../../models'; +import { ID } from '../../../../misc/cafy-id'; +import { ensure } from '../../../../prelude/ensure'; +import { toPunyNullable } from '../../../../misc/convert-host'; + +export const meta = { + desc: { + 'ja-JP': '指定ã—ãŸéƒ¨å±‹ã®æƒ…å ±ã‚’å–å¾—ã—ã¾ã™ã€‚', + }, + + tags: ['room'], + + requireCredential: false, + + params: { + userId: { + validator: $.optional.type(ID), + desc: { + 'ja-JP': '対象ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ID', + 'en-US': 'Target user ID' + } + }, + + username: { + validator: $.optional.str + }, + + host: { + validator: $.optional.nullable.str + }, + }, + + errors: { + noSuchUser: { + message: 'No such user.', + code: 'NO_SUCH_USER', + id: '7ad3fa3e-5e12-42f0-b23a-f3d13f10ee4b' + } + } +}; + +export default define(meta, async (ps, me) => { + const user = await Users.findOne(ps.userId != null + ? { id: ps.userId } + : { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) }); + + if (user == null) { + throw new ApiError(meta.errors.noSuchUser); + } + + const profile = await UserProfiles.findOne(user.id).then(ensure); + + if (profile.room.furnitures == null) { + await UserProfiles.update({ userId: user.id }, { + room: { + furnitures: [], + ...profile.room + } + }); + + profile.room.furnitures = []; + } + + if (profile.room.roomType == null) { + const initialType = 'default'; + await UserProfiles.update({ userId: user.id }, { + room: { + roomType: initialType as any, + ...profile.room + } + }); + + profile.room.roomType = initialType; + } + + if (profile.room.carpetColor == null) { + const initialColor = '#85CAF0'; + await UserProfiles.update({ userId: user.id }, { + room: { + carpetColor: initialColor as any, + ...profile.room + } + }); + + profile.room.carpetColor = initialColor; + } + + return profile.room; +}); diff --git a/src/server/api/endpoints/room/update.ts b/src/server/api/endpoints/room/update.ts new file mode 100644 index 0000000000000000000000000000000000000000..897f65f2d25158cae4f54111aaa8b3f6b5d80077 --- /dev/null +++ b/src/server/api/endpoints/room/update.ts @@ -0,0 +1,48 @@ +import $ from 'cafy'; +import { publishMainStream } from '../../../../services/stream'; +import define from '../../define'; +import { Users, UserProfiles } from '../../../../models'; + +export const meta = { + requireCredential: true, + + params: { + room: { + validator: $.obj({ + furnitures: $.arr($.obj({ + id: $.str, + type: $.str, + position: $.obj({ + x: $.num, + y: $.num, + z: $.num, + }), + rotation: $.obj({ + x: $.num, + y: $.num, + z: $.num, + }), + props: $.optional.nullable.obj(), + })), + roomType: $.str, + carpetColor: $.str + }) + }, + }, +}; + +export default define(meta, async (ps, user) => { + await UserProfiles.update({ userId: user.id }, { + room: ps.room as any + }); + + const iObj = await Users.pack(user.id, user, { + detail: true, + includeSecrets: true + }); + + // Publish meUpdated event + publishMainStream(user.id, 'meUpdated', iObj); + + return iObj; +}); diff --git a/tsconfig.json b/tsconfig.json index 4f1d1b9cd560ccf4b5429aa4d190050637d387dc..62107507acdb3814f57b6c7f42a23fe3e1f5ab80 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "sourceMap": true, "target": "es2017", "module": "commonjs", + "moduleResolution": "node", "removeComments": false, "noLib": false, "strict": true, diff --git a/yarn.lock b/yarn.lock index 1ac9e145f23a27840031d43c736a37018a55f786..1d5bf3226c9ac1a1672c9ca2e43b644052fae4af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10994,6 +10994,11 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +three@0.107.0: + version "0.107.0" + resolved "https://registry.yarnpkg.com/three/-/three-0.107.0.tgz#0c862c348d61bd3f22058e01f5e771c1294315a1" + integrity sha512-vqbKJRLBEviPVa7poEzXocobicwxzsctr5mnymA7n8fEzcVS49rYP0RrwqZ98JqujRoruK+/YzcchNpRP+kXsQ== + through2-concurrent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/through2-concurrent/-/through2-concurrent-2.0.0.tgz#c9dd2c146504ec9962dbc86a5168b63d662669fa"