Merge remote-tracking branch 'origin/next' into webgpu-true
This commit is contained in:
commit
92afdf54fb
243 changed files with 11112 additions and 1090 deletions
|
|
@ -1,5 +1,3 @@
|
|||
# we dont want default config to be loaded in the dockerfile, but rather using a volume
|
||||
config.json
|
||||
# build stuff
|
||||
node_modules
|
||||
public
|
||||
|
|
@ -96,5 +96,22 @@
|
|||
"unicorn/filename-case": "off",
|
||||
"max-depth": "off"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.js"
|
||||
],
|
||||
"rules": {
|
||||
"space-before-function-paren": [
|
||||
"error",
|
||||
{
|
||||
"anonymous": "always",
|
||||
"named": "never",
|
||||
"asyncArrow": "always"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"root": true
|
||||
}
|
||||
|
|
|
|||
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
|
|
@ -8,6 +8,11 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@master
|
||||
- name: Setup Java JDK
|
||||
uses: actions/setup-java@v1.4.3
|
||||
with:
|
||||
java-version: 17
|
||||
java-package: jre
|
||||
- name: Install pnpm
|
||||
run: npm i -g pnpm@9.0.4
|
||||
- uses: actions/setup-node@v4
|
||||
|
|
|
|||
3
.github/workflows/publish.yml
vendored
3
.github/workflows/publish.yml
vendored
|
|
@ -1,4 +1,4 @@
|
|||
name: Deploy to GitHub pages
|
||||
name: Release
|
||||
env:
|
||||
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
|
||||
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
|
||||
|
|
@ -17,6 +17,7 @@ jobs:
|
|||
# - run: pnpm install
|
||||
# - run: pnpm build
|
||||
- run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
|
||||
- run: node scripts/replaceFavicon.mjs ${{ secrets.FAVICON_MAIN }}
|
||||
# will install + build to .vercel/output/static
|
||||
- run: vercel build --token=${{ secrets.VERCEL_TOKEN }} --prod
|
||||
- run: pnpm build-storybook
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -17,5 +17,6 @@ out
|
|||
.vercel
|
||||
generated
|
||||
storybook-static
|
||||
server-jar
|
||||
|
||||
src/react/npmReactComponents.ts
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import React from 'react'
|
||||
|
||||
import type { Preview } from "@storybook/react";
|
||||
import type { Preview } from "@storybook/react"
|
||||
|
||||
import '../src/styles.css'
|
||||
import './storybook.css'
|
||||
import '../src/styles.css'
|
||||
import '../src/scaleInterface'
|
||||
|
||||
const preview: Preview = {
|
||||
decorators: [
|
||||
|
|
@ -11,7 +12,7 @@ const preview: Preview = {
|
|||
const noScaling = c.parameters.noScaling
|
||||
return <div id={noScaling ? '' : 'ui-root'}>
|
||||
<Story />
|
||||
</div>;
|
||||
</div>
|
||||
},
|
||||
],
|
||||
parameters: {
|
||||
|
|
@ -23,6 +24,6 @@ const preview: Preview = {
|
|||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default preview;
|
||||
export default preview
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ How different modules are used:
|
|||
|
||||
- `mineflayer` - provider `bot` variable and as mineflayer states it is a wrapper for the `node-minecraft-protocol` module and is used to connect and interact with real Java Minecraft servers. However not all events & properties are exposed and sometimes you have to use `bot._client.on('packet_name', data => ...)` to handle packets that are not handled via mineflayer API. Also you can use almost any mineflayer plugin.
|
||||
|
||||
## Making protocol changes
|
||||
## Making protocol-related changes
|
||||
|
||||
You can get a description of packets for the latest protocol version from <https://wiki.vg/Protocol> and for previous protocol versions from <https://wiki.vg/Protocol_version_numbers> (look for *Page* links that have *Protocol* in URL).
|
||||
|
||||
|
|
@ -37,6 +37,7 @@ Also there are [src/generatedClientPackets.ts](src/generatedClientPackets.ts) an
|
|||
- Some data are cached between restarts. If you see something doesn't work after upgrading dependencies, try to clear the by simply removing the `dist` folder.
|
||||
- The same folder `dist` is used for both development and production builds, so be careful when deploying the project.
|
||||
- Use `start-prod` script to start the project in production mode after running the `build` script to build the project.
|
||||
- If CI is failing on the next branch for some reason, feel free to use the latest commit for release branch. We will update the base branch asap. Please, always make sure to allow maintainers do changes when opening PRs.
|
||||
|
||||
### Would be useful to have
|
||||
|
||||
|
|
|
|||
19
Dockerfile
19
Dockerfile
|
|
@ -1,9 +1,22 @@
|
|||
FROM node:14-alpine
|
||||
FROM node:18-alpine
|
||||
# Without git installing the npm packages fails
|
||||
RUN apk add git
|
||||
RUN mkdir /app
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
# install python and other dependencies
|
||||
RUN apk add python3 make g++ cairo-dev pango-dev jpeg-dev giflib-dev librsvg-dev
|
||||
# install pnpm
|
||||
RUN npm i -g pnpm@9.0.4
|
||||
RUN pnpm install
|
||||
# only for prod
|
||||
RUN pnpm run build
|
||||
# ---
|
||||
EXPOSE 8080
|
||||
# uncomment for development
|
||||
# EXPOSE 9090
|
||||
# VOLUME /app/src
|
||||
# VOLUME /app/prismarine-viewer
|
||||
# ENTRYPOINT ["pnpm", "run", "run-all"]
|
||||
# only for prod
|
||||
ENTRYPOINT ["npm", "run", "prod-start"]
|
||||
|
|
|
|||
28
README.MD
28
README.MD
|
|
@ -4,19 +4,20 @@
|
|||
|
||||
A true Minecraft client running in your browser! A port of the original game to the web, written in JavaScript using modern web technologies.
|
||||
|
||||
If you encounter any bugs or usability issues, please report them!
|
||||
If you encounter any bugs or usability issues, please report them! For development, see [development](#development--debugging).
|
||||
|
||||
You can try this out at [mcraft.fun](https://mcraft.fun/), [pcm.gg](https://pcm.gg) (short link) [mcon.vercel.app](https://mcon.vercel.app/) or the GitHub pages deploy. Every commit from the `develop` (default) branch is deployed to [s.mcraft.fun](https://s.mcraft.fun/) - so it's usually newer, but might be less stable.
|
||||
|
||||
### Big Features
|
||||
|
||||
- Open any zip world file or even folder in read-write mode!
|
||||
- Connect to cracked servers* (it's possible because of proxy servers, see below)
|
||||
- Connect to Java servers running in both offline (cracked) and online mode* (it's possible because of proxy servers, see below)
|
||||
- Singleplayer mode with simple world generations!
|
||||
- Works offline
|
||||
- Play with friends over internet! (P2P is powered by Peer.js discovery servers)
|
||||
- First-class touch (mobile) & controller support
|
||||
- Resource pack support
|
||||
- Builtin JEI with recipes & guides for every item (also replaces creative inventory)
|
||||
- even even more!
|
||||
|
||||
All components that are in [Storybook](https://mcraft.fun/storybook) are published as npm module and can be used in other projects: [`minecraft-react`](https://npmjs.com/minecraft-react)
|
||||
|
|
@ -34,11 +35,13 @@ Zip files and folders are supported. Just drag and drop them into the browser wi
|
|||
In case of opening zip files they are stored in your ram entirely, so there is a ~300mb file limit on IOS.
|
||||
Whatever offline mode you used (zip, folder, just single player), you can always export world with the `/export` command typed in the game chat.
|
||||
|
||||

|
||||
|
||||
### Servers
|
||||
|
||||
You can play almost on any server, supporting offline connections.
|
||||
You can play almost on any Java server, vanilla servers are fully supported.
|
||||
See the [Mineflayer](https://github.com/PrismarineJS/mineflayer) repo for the list of supported versions (should support majority of versions).
|
||||
There is a builtin proxy, but you can also host a your one! Just clone the repo, run `pnpm i` (following CONTRIBUTING.MD) and run `pnpm prod-start`, then you can specify `http://localhost:8080` in the proxy field.
|
||||
There is a builtin proxy, but you can also host your one! Just clone the repo, run `pnpm i` (following CONTRIBUTING.MD) and run `pnpm prod-start`, then you can specify `http://localhost:8080` in the proxy field.
|
||||
MS account authentication will be supported soon.
|
||||
|
||||
### Rendering
|
||||
|
|
@ -46,8 +49,9 @@ MS account authentication will be supported soon.
|
|||
#### Three.js Renderer
|
||||
|
||||
- Uses WebGL2. Chunks are rendered using Geometry Buffers prepared by 4 mesher workers.
|
||||
- Supports FXAA
|
||||
- Doesn't support culling
|
||||
- Entities & text rendering
|
||||
- Supports resource packs
|
||||
- Doesn't support occlusion culling
|
||||
|
||||
<!-- TODO proxy server communication graph -->
|
||||
|
||||
|
|
@ -63,9 +67,9 @@ There are many many settings, that are not exposed in the UI yet. You can find o
|
|||
|
||||
To open the console, press `F12`, or if you are on mobile, you can type `#debug` in the URL (browser address bar), it wont't reload the page, but you will see a button to open the console. This way you can change advanced settings and see all errors or warnings. Also this way you can access global variables (described below).
|
||||
|
||||
### Debugging
|
||||
### Development & Debugging
|
||||
|
||||
It should be easy to build/start the project locally. See [CONTRIBUTING.MD](./CONTRIBUTING.md) for more info.
|
||||
It should be easy to build/start the project locally. See [CONTRIBUTING.MD](./CONTRIBUTING.md) for more info. Also you can look at Dockerfile for reference.
|
||||
|
||||
There is world renderer playground ([link](https://mcon.vercel.app/playground.html)).
|
||||
|
||||
|
|
@ -109,10 +113,10 @@ Press `Y` to set query parameters to url of your current game state.
|
|||
- `?version=<version>` - Set the version for server
|
||||
- `?lockConnect=true` - Disable cancel / save buttons, useful for integrates iframes
|
||||
- `?reconnect=true` - Reconnect to the server on page reloads. Available in **dev mode only** and very useful on server testing.
|
||||
<!-- - `?password=<password>` - Set the password on load -->
|
||||
- `?loadSave=<save_name>` - Load the save on load with the specified folder name (not title)
|
||||
- `?singleplayer=1` - Create empty world on load. Nothing will be saved
|
||||
- `?noSave=true` - Disable auto save on unload / disconnect / export. Only manual save with `/save` command will work
|
||||
<!-- - `?requiresAuth=true` - Show the Microsoft login screen on server connect. Useful for servers that require authentication (running in online mode) -->
|
||||
|
||||
- `?map=<map_url>` - Load the map from ZIP. You can use any url, but it must be CORS enabled.
|
||||
- `?setting=<setting_name>:<setting_value>` - Set the and lock the setting on load. You can set multiple settings by separating them with `&` e.g. `?setting=autoParkour:true&setting=renderDistance:4`
|
||||
|
|
@ -120,9 +124,13 @@ Press `Y` to set query parameters to url of your current game state.
|
|||
### Notable Things that Power this Project
|
||||
|
||||
- [Mineflayer](https://github.com/PrismarineJS/mineflayer) - Handles all client-side communications with the server (including the builtin one) - forked
|
||||
- [Flying Squid](https://github.com/prismarineJS/flying-squid) - The builtin server that makes single player possible! Here forked version is used.
|
||||
- [Forked Flying Squid (Space Squid)](https://github.com/zardoy/space-squid) - The builtin offline server that makes single player & P2P possible!
|
||||
- [Prismarine Provider Anvil](https://github.com/PrismarineJS/prismarine-provider-anvil) - Handles world loading (region format)
|
||||
- [Prismarine Physics](https://github.com/PrismarineJS/prismarine-physics) - Does all the physics calculations
|
||||
- [Minecraft Protocol](https://github.com/PrismarineJS/node-minecraft-protocol) - Makes connections to servers possible
|
||||
- [Peer.js](https://peerjs.com/) - P2P networking (when you open to wan)
|
||||
- [Three.js](https://threejs.org/) - Helping in 3D rendering
|
||||
|
||||
### Alternatives
|
||||
|
||||
- [https://github.com/ClassiCube/ClassiCube](ClassiCube - Better C# Rewrite) [DEMO](https://www.classicube.net/server/play/?warned=true)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
# Minecraft React
|
||||
|
||||
Minecraft UI components for React.
|
||||
|
||||
```bash
|
||||
yarn add minecraft-react
|
||||
pnpm i minecraft-react
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
|
|
@ -24,7 +28,7 @@ const App = () => {
|
|||
}
|
||||
```
|
||||
|
||||
See [Storybook](https://mcraft.fun/storybook/) or [Storybook (Mirror link)](https://mcon.vercel.app/storybook/) for more examples and full components list. Also take a look at the full [standalone example](https://github.com/zardoy/prismarine-web-client/tree/experiments/UiStandaloneExample.tsx).
|
||||
See [Storybook](https://mcraft.fun/storybook/) or [Storybook (Mirror link)](https://mcon.vercel.app/storybook/) for more examples and full components list. Also take a look at the full [standalone example](https://github.com/zardoy/minecraft-web-client/tree/experiments/UiStandaloneExample.tsx).
|
||||
|
||||
There are two types of components:
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 589 KiB After Width: | Height: | Size: 513 KiB |
|
|
@ -15,9 +15,9 @@
|
|||
"description": "One of the best servers here. Join now!"
|
||||
},
|
||||
{
|
||||
"ip": "play.minemalia.com",
|
||||
"ip": "sus.shhnowisnottheti.me",
|
||||
"version": "1.18.2",
|
||||
"description": "Only login with existing accounts."
|
||||
"description": "Creative, your own 'boxes' (islands)"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
/* eslint-disable max-nested-callbacks */
|
||||
/// <reference types="cypress" />
|
||||
import supportedVersions from '../../src/supportedVersions.mjs'
|
||||
import { setOptions, cleanVisit, visit } from './shared'
|
||||
|
||||
// todo use ssl
|
||||
|
|
@ -12,7 +14,7 @@ const compareRenderedFlatWorld = () => {
|
|||
}
|
||||
|
||||
const testWorldLoad = () => {
|
||||
cy.document().then({ timeout: 20_000 }, doc => {
|
||||
return cy.document().then({ timeout: 25_000 }, doc => {
|
||||
return new Cypress.Promise(resolve => {
|
||||
doc.addEventListener('cypress-world-ready', resolve)
|
||||
})
|
||||
|
|
@ -22,7 +24,7 @@ const testWorldLoad = () => {
|
|||
}
|
||||
|
||||
it('Loads & renders singleplayer', () => {
|
||||
visit('/?singleplayer=1')
|
||||
cleanVisit('/?singleplayer=1')
|
||||
setOptions({
|
||||
localServerOptions: {
|
||||
generation: {
|
||||
|
|
@ -36,7 +38,7 @@ it('Loads & renders singleplayer', () => {
|
|||
testWorldLoad()
|
||||
})
|
||||
|
||||
it('Joins to server', () => {
|
||||
it('Joins to local flying-squid server', () => {
|
||||
visit('/?ip=localhost&version=1.16.1')
|
||||
window.localStorage.version = ''
|
||||
// todo replace with data-test
|
||||
|
|
@ -47,6 +49,45 @@ it('Joins to server', () => {
|
|||
testWorldLoad()
|
||||
})
|
||||
|
||||
it('Joins to local latest Java vanilla server', () => {
|
||||
const version = supportedVersions.at(-1)!
|
||||
cy.task('startServer', [version, 25_590]).then(() => {
|
||||
visit('/?ip=localhost:25590&username=bot')
|
||||
cy.get('[data-test-id="connect-qs"]').click()
|
||||
testWorldLoad().then(() => {
|
||||
let x = 0
|
||||
let z = 0
|
||||
cy.window().then((win) => {
|
||||
x = win.bot.entity.position.x
|
||||
z = win.bot.entity.position.z
|
||||
})
|
||||
cy.document().trigger('keydown', { code: 'KeyW' })
|
||||
cy.wait(1500).then(() => {
|
||||
cy.document().trigger('keyup', { code: 'KeyW' })
|
||||
cy.window().then(async (win) => {
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
const bot: typeof __type_bot = win.bot
|
||||
// todo use f3 stats instead
|
||||
if (bot.entity.position.x === x && bot.entity.position.z === z) {
|
||||
throw new Error('Player not moved')
|
||||
}
|
||||
|
||||
bot.chat('Hello') // todo assert
|
||||
bot.chat('/gamemode creative')
|
||||
// bot.on('message', () => {
|
||||
void bot.creative.setInventorySlot(bot.inventory.hotbarStart, new win.PrismarineItem(1, 1, 0))
|
||||
// })
|
||||
await bot.lookAt(bot.entity.position.offset(1, 0, 1))
|
||||
}).then(() => {
|
||||
cy.document().trigger('mousedown', { button: 2, isTrusted: true, force: true }) // right click
|
||||
cy.document().trigger('mouseup', { button: 2, isTrusted: true, force: true })
|
||||
cy.wait(1000)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('Loads & renders zip world', () => {
|
||||
cleanVisit()
|
||||
cy.get('[data-test-id="select-file-folder"]').click({ shiftKey: true })
|
||||
|
|
@ -54,9 +95,14 @@ it('Loads & renders zip world', () => {
|
|||
testWorldLoad()
|
||||
})
|
||||
|
||||
it.skip('Performance test', () => {
|
||||
// select that world
|
||||
// from -2 85 24
|
||||
// await bot.loadPlugin(pathfinder.pathfinder)
|
||||
// bot.pathfinder.goto(new pathfinder.goals.GoalXZ(28, -28))
|
||||
|
||||
it.skip('Loads & renders world from folder', () => {
|
||||
cleanVisit()
|
||||
// dragndrop folder
|
||||
cy.get('[data-test-id="select-file-folder"]').click()
|
||||
cy.get('input[type="file"]').selectFile('server-jar/world', {
|
||||
force: true,
|
||||
// action: 'drag-drop',
|
||||
})
|
||||
testWorldLoad()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ import { AppOptions } from '../../src/optionsStorage'
|
|||
export const cleanVisit = (url?) => {
|
||||
cy.clearLocalStorage()
|
||||
visit(url)
|
||||
window.localStorage.options = {
|
||||
chatOpacity: 0
|
||||
}
|
||||
}
|
||||
export const visit = (url = '/') => {
|
||||
window.localStorage.cypress = 'true'
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import mcServer from 'flying-squid'
|
||||
import defaultOptions from 'flying-squid/config/default-settings.json' assert { type: 'json' }
|
||||
|
||||
/** @type {Options} */
|
||||
const serverOptions = {
|
||||
...defaultOptions,
|
||||
'online-mode': false,
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@
|
|||
const { cypressEsbuildPreprocessor } = require('cypress-esbuild-preprocessor')
|
||||
const { initPlugin } = require('cypress-plugin-snapshots/plugin')
|
||||
const polyfill = require('esbuild-plugin-polyfill-node')
|
||||
const { startMinecraftServer } = require('./startServer')
|
||||
|
||||
module.exports = (on, config) => {
|
||||
initPlugin(on, config)
|
||||
on('file:preprocessor', cypressEsbuildPreprocessor({
|
||||
esbuildOptions: {
|
||||
sourcemap: true,
|
||||
plugins: [
|
||||
polyfill.polyfillNode({
|
||||
polyfills: {
|
||||
|
|
@ -17,10 +19,15 @@ module.exports = (on, config) => {
|
|||
},
|
||||
}))
|
||||
on('task', {
|
||||
log (message) {
|
||||
log(message) {
|
||||
console.log(message)
|
||||
return null
|
||||
},
|
||||
})
|
||||
on('task', {
|
||||
async startServer([version, port]) {
|
||||
return startMinecraftServer(version, port)
|
||||
}
|
||||
})
|
||||
return config
|
||||
}
|
||||
|
|
|
|||
8
cypress/plugins/ops.json
Normal file
8
cypress/plugins/ops.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
{
|
||||
"uuid": "67128b5b-2e6b-3ad1-baa0-1b937b03e5c5",
|
||||
"name": "bot",
|
||||
"level": 4,
|
||||
"bypassesPlayerLimit": false
|
||||
}
|
||||
]
|
||||
61
cypress/plugins/server.properties
Normal file
61
cypress/plugins/server.properties
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#Minecraft server properties
|
||||
allow-flight=false
|
||||
allow-nether=true
|
||||
broadcast-console-to-ops=true
|
||||
broadcast-rcon-to-ops=true
|
||||
difficulty=peaceful
|
||||
enable-command-block=false
|
||||
enable-jmx-monitoring=false
|
||||
enable-query=false
|
||||
enable-rcon=false
|
||||
enable-status=true
|
||||
enforce-secure-profile=true
|
||||
enforce-whitelist=false
|
||||
entity-broadcast-range-percentage=100
|
||||
force-gamemode=false
|
||||
function-permission-level=2
|
||||
gamemode=survival
|
||||
generate-structures=true
|
||||
generator-settings={}
|
||||
hardcore=false
|
||||
hide-online-players=false
|
||||
initial-disabled-packs=
|
||||
initial-enabled-packs=vanilla
|
||||
level-name=world
|
||||
level-seed=
|
||||
level-type=flat
|
||||
log-ips=true
|
||||
max-build-height=256
|
||||
max-chained-neighbor-updates=1000000
|
||||
max-players=20
|
||||
max-tick-time=60000
|
||||
max-world-size=29999984
|
||||
motd=A Minecraft Server
|
||||
network-compression-threshold=256
|
||||
online-mode=false
|
||||
op-permission-level=4
|
||||
player-idle-timeout=0
|
||||
prevent-proxy-connections=false
|
||||
pvp=true
|
||||
query.port=25565
|
||||
rate-limit=0
|
||||
rcon.password=
|
||||
rcon.port=25575
|
||||
require-resource-pack=false
|
||||
resource-pack=
|
||||
resource-pack-id=
|
||||
resource-pack-prompt=
|
||||
resource-pack-sha1=
|
||||
server-ip=
|
||||
server-port=25565
|
||||
simulation-distance=10
|
||||
snooper-enabled=true
|
||||
spawn-animals=true
|
||||
spawn-monsters=true
|
||||
spawn-npcs=true
|
||||
spawn-protection=16
|
||||
sync-chunk-writes=true
|
||||
text-filtering-config=
|
||||
use-native-transport=true
|
||||
view-distance=10
|
||||
white-list=false
|
||||
45
cypress/plugins/startServer.ts
Normal file
45
cypress/plugins/startServer.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { ChildProcess, spawn } from 'child_process'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import { promisify } from 'util'
|
||||
import { downloadServer } from 'minecraft-wrap'
|
||||
import * as waitOn from 'wait-on'
|
||||
|
||||
let prevProcess: ChildProcess | null = null
|
||||
export const startMinecraftServer = async (version: string, port: number) => {
|
||||
if (prevProcess) return null
|
||||
const jar = `./server-jar/${version}.jar`
|
||||
|
||||
const start = () => {
|
||||
// if (prevProcess) {
|
||||
// prevProcess.kill()
|
||||
// }
|
||||
|
||||
prevProcess = spawn('java', ['-jar', path.basename(jar), 'nogui', '--port', `${port}`], {
|
||||
stdio: 'inherit',
|
||||
cwd: path.dirname(jar),
|
||||
})
|
||||
}
|
||||
|
||||
let coldStart = false
|
||||
if (fs.existsSync(jar)) {
|
||||
start()
|
||||
} else {
|
||||
coldStart = true
|
||||
promisify(downloadServer)(version, jar).then(() => {
|
||||
// add eula.txt
|
||||
fs.writeFileSync(path.join(path.dirname(jar), 'eula.txt'), 'eula=true')
|
||||
// copy cypress/plugins/server.properties
|
||||
fs.copyFileSync(path.join(__dirname, 'server.properties'), path.join(path.dirname(jar), 'server.properties'))
|
||||
// copy ops.json
|
||||
fs.copyFileSync(path.join(__dirname, 'ops.json'), path.join(path.dirname(jar), 'ops.json'))
|
||||
start()
|
||||
})
|
||||
}
|
||||
|
||||
return new Promise<null>((res) => {
|
||||
waitOn({ resources: [`tcp:localhost:${port}`] }, () => {
|
||||
setTimeout(() => res(null), coldStart ? 6500 : 2000) // todo retry instead of timeout
|
||||
})
|
||||
})
|
||||
}
|
||||
BIN
docs-assets/singleplayer-future-city-1-10-2.jpg
Normal file
BIN
docs-assets/singleplayer-future-city-1-10-2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
|
|
@ -60,6 +60,7 @@ const buildOptions = {
|
|||
net: 'net-browserify',
|
||||
assert: 'assert',
|
||||
dns: './src/dns.js',
|
||||
'yggdrasil': './src/yggdrasilReplacement.ts',
|
||||
// todo write advancedAliases plugin
|
||||
},
|
||||
inject: [
|
||||
|
|
@ -79,11 +80,15 @@ const buildOptions = {
|
|||
loader: {
|
||||
// todo use external or resolve issues with duplicating
|
||||
'.png': 'dataurl',
|
||||
'.svg': 'dataurl',
|
||||
'.map': 'empty',
|
||||
'.vert': 'text',
|
||||
'.frag': 'text',
|
||||
'.wgsl': 'text',
|
||||
'.obj': 'text',
|
||||
'.woff': 'dataurl',
|
||||
'.woff2': 'dataurl',
|
||||
'.ttf': 'dataurl',
|
||||
},
|
||||
write: false,
|
||||
// todo would be better to enable?
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
</div>
|
||||
<div>
|
||||
<div style="font-size: calc(var(--font-size) * 1.8);color: lightgray;" class="title">Loading...</div>
|
||||
<div style="font-size: var(--font-size);color: rgb(176, 176, 176);" class="subtitle">A true Minecraft client in your browser!</div>
|
||||
<div style="font-size: var(--font-size);color: rgb(176, 176, 176);margin-top: 3px;text-align: center" class="subtitle">A true Minecraft client in your browser!</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
|
@ -94,9 +94,7 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="react-root"></div>
|
||||
<div id="ui-root">
|
||||
<pmui-playscreen id="play-screen" style="display: none;"></pmui-playscreen>
|
||||
</div>
|
||||
<div id="ui-root"></div>
|
||||
<!-- inject script -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
22
package.json
22
package.json
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "prismarine-web-client",
|
||||
"name": "minecraft-web-client",
|
||||
"version": "0.0.0-dev",
|
||||
"description": "A minecraft client running in a browser",
|
||||
"scripts": {
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
"@types/wicg-file-system-access": "^2023.10.2",
|
||||
"@webgpu/types": "^0.1.40",
|
||||
"@xmcl/text-component": "^2.1.3",
|
||||
"@zardoy/react-util": "^0.2.0",
|
||||
"@zardoy/react-util": "^0.2.4",
|
||||
"@zardoy/utils": "^0.0.11",
|
||||
"adm-zip": "^0.5.12",
|
||||
"browserfs": "github:zardoy/browserfs#build",
|
||||
|
|
@ -65,21 +65,21 @@
|
|||
"esbuild-plugin-polyfill-node": "^0.3.0",
|
||||
"express": "^4.18.2",
|
||||
"filesize": "^10.0.12",
|
||||
"flying-squid": "npm:@zardoy/flying-squid@^0.0.20",
|
||||
"flying-squid": "npm:@zardoy/flying-squid@^0.0.33",
|
||||
"fs-extra": "^11.1.1",
|
||||
"google-drive-browserfs": "github:zardoy/browserfs#google-drive",
|
||||
"iconify-icon": "^1.0.8",
|
||||
"jszip": "^3.10.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"math.gl": "^4.0.0",
|
||||
"minecraft-assets": "^1.12.2",
|
||||
"minecraft-data": "3.65.0",
|
||||
"minecraft-protocol": "github:PrismarineJS/node-minecraft-protocol",
|
||||
"minecraft-protocol": "github:PrismarineJS/node-minecraft-protocol#master",
|
||||
"mineflayer-item-map-downloader": "github:zardoy/mineflayer-item-map-downloader",
|
||||
"mojangson": "^2.0.4",
|
||||
"net-browserify": "github:zardoy/prismarinejs-net-browserify",
|
||||
"node-gzip": "^1.1.2",
|
||||
"peerjs": "^1.5.0",
|
||||
"pixelarticons": "^1.8.1",
|
||||
"pretty-bytes": "^6.1.1",
|
||||
"prismarine-provider-anvil": "github:zardoy/prismarine-provider-anvil#everything",
|
||||
"prosemirror-example-setup": "^1.2.2",
|
||||
|
|
@ -104,6 +104,7 @@
|
|||
"use-typed-event-listener": "^4.0.2",
|
||||
"valtio": "^1.11.1",
|
||||
"vec3": "^0.1.7",
|
||||
"wait-on": "^7.2.0",
|
||||
"workbox-build": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -117,12 +118,13 @@
|
|||
"@types/stats.js": "^0.17.1",
|
||||
"@types/three": "0.154.0",
|
||||
"@types/ua-parser-js": "^0.7.39",
|
||||
"@types/wait-on": "^5.3.4",
|
||||
"@xmcl/installer": "^5.1.0",
|
||||
"assert": "^2.0.0",
|
||||
"browserify-zlib": "^0.2.0",
|
||||
"buffer": "^6.0.3",
|
||||
"constants-browserify": "^1.0.0",
|
||||
"contro-max": "^0.1.6",
|
||||
"contro-max": "^0.1.8",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"cypress": "^10.11.0",
|
||||
"cypress-esbuild-preprocessor": "^1.0.2",
|
||||
|
|
@ -133,7 +135,7 @@
|
|||
"http-server": "^14.1.1",
|
||||
"https-browserify": "^1.0.0",
|
||||
"minecraft-inventory-gui": "github:zardoy/minecraft-inventory-gui#next",
|
||||
"mineflayer": "github:PrismarineJS/mineflayer",
|
||||
"mineflayer": "github:zardoy/mineflayer",
|
||||
"mineflayer-pathfinder": "^2.4.4",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"os-browserify": "^0.3.0",
|
||||
|
|
@ -162,7 +164,7 @@
|
|||
"prismarine-world": "github:zardoy/prismarine-world#next-era",
|
||||
"minecraft-data": "3.65.0",
|
||||
"prismarine-provider-anvil": "github:zardoy/prismarine-provider-anvil#everything",
|
||||
"minecraft-protocol": "github:PrismarineJS/node-minecraft-protocol",
|
||||
"minecraft-protocol": "github:PrismarineJS/node-minecraft-protocol#master",
|
||||
"react": "^18.2.0",
|
||||
"prismarine-chunk": "github:zardoy/prismarine-chunk"
|
||||
},
|
||||
|
|
@ -170,7 +172,9 @@
|
|||
"ignoreDependencies": []
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"minecraft-protocol@1.47.0": "patches/minecraft-protocol@1.47.0.patch"
|
||||
"minecraft-protocol@1.47.0": "patches/minecraft-protocol@1.47.0.patch",
|
||||
"three@0.154.0": "patches/three@0.154.0.patch",
|
||||
"pixelarticons@1.8.1": "patches/pixelarticons@1.8.1.patch"
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@9.0.4"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
},
|
||||
"module": "./dist/react/npmReactComponents.js",
|
||||
"types": "./dist/react/npmReactComponents.d.ts",
|
||||
"repository": "zardoy/prismarine-web-client",
|
||||
"repository": "zardoy/minecraft-web-client",
|
||||
"version": "0.0.0-dev",
|
||||
"dependencies": {},
|
||||
"peerDependencies": {
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ index c437ecf3a0e4ab5758a48538c714b7e9651bb5da..d9c9895ae8614550aa09ad60a396ac32
|
|||
debug('ping response', response)
|
||||
// TODO: could also use ping pre-connect to save description, type, max players, etc.
|
||||
@@ -40,6 +40,7 @@ module.exports = function (client, options) {
|
||||
|
||||
|
||||
// Reinitialize client object with new version TODO: move out of its constructor?
|
||||
client.version = minecraftVersion
|
||||
+ await options.versionSelectedHook?.(client)
|
||||
client.state = states.HANDSHAKING
|
||||
|
||||
|
||||
// Let other plugins such as Forge/FML (modinfo) respond to the ping response
|
||||
diff --git a/src/client/encrypt.js b/src/client/encrypt.js
|
||||
index b9d21bab9faccd5dbf1975fc423fc55c73e906c5..99ffd76527b410e3a393181beb260108f4c63536 100644
|
||||
|
|
@ -34,7 +34,7 @@ index b9d21bab9faccd5dbf1975fc423fc55c73e906c5..99ffd76527b410e3a393181beb260108
|
|||
+ // clearTimeout(loginTimeout)
|
||||
+ // })
|
||||
}
|
||||
|
||||
|
||||
function onJoinServerResponse (err) {
|
||||
diff --git a/src/client.js b/src/client.js
|
||||
index c89375e32babbf3559655b1e95f6441b9a30796f..f24cd5dc8fa9a0a4000b184fb3c79590a3ad8b8a 100644
|
||||
|
|
@ -74,7 +74,7 @@ index c89375e32babbf3559655b1e95f6441b9a30796f..f24cd5dc8fa9a0a4000b184fb3c79590
|
|||
}
|
||||
@@ -166,7 +174,10 @@ class Client extends EventEmitter {
|
||||
}
|
||||
|
||||
|
||||
const onFatalError = (err) => {
|
||||
- this.emit('error', err)
|
||||
+ // todo find out what is trying to write after client disconnect
|
||||
|
|
@ -83,7 +83,7 @@ index c89375e32babbf3559655b1e95f6441b9a30796f..f24cd5dc8fa9a0a4000b184fb3c79590
|
|||
+ }
|
||||
endSocket()
|
||||
}
|
||||
|
||||
|
||||
@@ -195,6 +206,8 @@ class Client extends EventEmitter {
|
||||
serializer -> framer -> socket -> splitter -> deserializer */
|
||||
if (this.serializer) {
|
||||
|
|
@ -94,7 +94,7 @@ index c89375e32babbf3559655b1e95f6441b9a30796f..f24cd5dc8fa9a0a4000b184fb3c79590
|
|||
if (this.socket) this.socket.end()
|
||||
}
|
||||
@@ -236,8 +249,11 @@ class Client extends EventEmitter {
|
||||
|
||||
|
||||
write (name, params) {
|
||||
if (!this.serializer.writable) { return }
|
||||
- debug('writing packet ' + this.state + '.' + name)
|
||||
|
|
@ -106,7 +106,7 @@ index c89375e32babbf3559655b1e95f6441b9a30796f..f24cd5dc8fa9a0a4000b184fb3c79590
|
|||
+ this.emit('writePacket', name, params)
|
||||
this.serializer.write({ name, params })
|
||||
}
|
||||
|
||||
|
||||
diff --git a/src/index.d.ts b/src/index.d.ts
|
||||
index 0a5821c32d735e11205a280aa5a503c13533dc14..94a49f661d922478b940d853169b6087e6ec3df5 100644
|
||||
--- a/src/index.d.ts
|
||||
|
|
@ -126,5 +126,63 @@ index 0a5821c32d735e11205a280aa5a503c13533dc14..94a49f661d922478b940d853169b6087
|
|||
+ /** Can be used to prepare mc data on autoVersion (client.version has selected version) */
|
||||
+ versionSelectedHook?: (client: Client) => Promise<void> | void
|
||||
}
|
||||
|
||||
|
||||
export class Server extends EventEmitter {
|
||||
diff --git a/src/client/chat.js b/src/client/chat.js
|
||||
index 5cad9954db13d7121ed0a03792c2304156cdf436..ffd7c7d6299ef54854e0923f8d5296bf2a58956b 100644
|
||||
--- a/src/client/chat.js
|
||||
+++ b/src/client/chat.js
|
||||
@@ -111,7 +111,7 @@ module.exports = function (client, options) {
|
||||
for (const player of packet.data) {
|
||||
if (!player.chatSession) continue
|
||||
client._players[player.UUID] = {
|
||||
- publicKey: crypto.createPublicKey({ key: player.chatSession.publicKey.keyBytes, format: 'der', type: 'spki' }),
|
||||
+ // publicKey: crypto.createPublicKey({ key: player.chatSession.publicKey.keyBytes, format: 'der', type: 'spki' }),
|
||||
publicKeyDER: player.chatSession.publicKey.keyBytes,
|
||||
sessionUuid: player.chatSession.uuid
|
||||
}
|
||||
@@ -127,7 +127,7 @@ module.exports = function (client, options) {
|
||||
for (const player of packet.data) {
|
||||
if (player.crypto) {
|
||||
client._players[player.UUID] = {
|
||||
- publicKey: crypto.createPublicKey({ key: player.crypto.publicKey, format: 'der', type: 'spki' }),
|
||||
+ // publicKey: crypto.createPublicKey({ key: player.crypto.publicKey, format: 'der', type: 'spki' }),
|
||||
publicKeyDER: player.crypto.publicKey,
|
||||
signature: player.crypto.signature,
|
||||
displayName: player.displayName || player.name
|
||||
@@ -198,7 +198,7 @@ module.exports = function (client, options) {
|
||||
if (mcData.supportFeature('useChatSessions')) {
|
||||
const tsDelta = BigInt(Date.now()) - packet.timestamp
|
||||
const expired = !packet.timestamp || tsDelta > messageExpireTime || tsDelta < 0
|
||||
- const verified = !packet.unsignedChatContent && updateAndValidateSession(packet.senderUuid, packet.plainMessage, packet.signature, packet.index, packet.previousMessages, packet.salt, packet.timestamp) && !expired
|
||||
+ const verified = false && !packet.unsignedChatContent && updateAndValidateSession(packet.senderUuid, packet.plainMessage, packet.signature, packet.index, packet.previousMessages, packet.salt, packet.timestamp) && !expired
|
||||
if (verified) client._signatureCache.push(packet.signature)
|
||||
client.emit('playerChat', {
|
||||
plainMessage: packet.plainMessage,
|
||||
@@ -363,7 +363,7 @@ module.exports = function (client, options) {
|
||||
}
|
||||
}
|
||||
|
||||
- client._signedChat = (message, options = {}) => {
|
||||
+ client._signedChat = async (message, options = {}) => {
|
||||
options.timestamp = options.timestamp || BigInt(Date.now())
|
||||
options.salt = options.salt || 1n
|
||||
|
||||
@@ -404,7 +404,7 @@ module.exports = function (client, options) {
|
||||
message,
|
||||
timestamp: options.timestamp,
|
||||
salt: options.salt,
|
||||
- signature: (client.profileKeys && client._session) ? client.signMessage(message, options.timestamp, options.salt, undefined, acknowledgements) : undefined,
|
||||
+ signature: (client.profileKeys && client._session) ? await client.signMessage(message, options.timestamp, options.salt, undefined, acknowledgements) : undefined,
|
||||
offset: client._lastSeenMessages.pending,
|
||||
acknowledged
|
||||
})
|
||||
@@ -418,7 +418,7 @@ module.exports = function (client, options) {
|
||||
message,
|
||||
timestamp: options.timestamp,
|
||||
salt: options.salt,
|
||||
- signature: client.profileKeys ? client.signMessage(message, options.timestamp, options.salt, options.preview) : Buffer.alloc(0),
|
||||
+ signature: client.profileKeys ? await client.signMessage(message, options.timestamp, options.salt, options.preview) : Buffer.alloc(0),
|
||||
signedPreview: options.didPreview,
|
||||
previousMessages: client._lastSeenMessages.map((e) => ({
|
||||
messageSender: e.sender,
|
||||
|
|
|
|||
27
patches/pixelarticons@1.8.1.patch
Normal file
27
patches/pixelarticons@1.8.1.patch
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
diff --git a/fonts/pixelart-icons-font.css b/fonts/pixelart-icons-font.css
|
||||
index 3b2ebe839370d96bf93ef5ca94a827f07e49378d..103ab4d6b9f3b5c9f41d1407e3cbf4ac392fbf41 100644
|
||||
--- a/fonts/pixelart-icons-font.css
|
||||
+++ b/fonts/pixelart-icons-font.css
|
||||
@@ -1,16 +1,13 @@
|
||||
@font-face {
|
||||
font-family: "pixelart-icons-font";
|
||||
- src: url('pixelart-icons-font.eot?t=1711815892278'); /* IE9*/
|
||||
- src: url('pixelart-icons-font.eot?t=1711815892278#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
+ src:
|
||||
url("pixelart-icons-font.woff2?t=1711815892278") format("woff2"),
|
||||
url("pixelart-icons-font.woff?t=1711815892278") format("woff"),
|
||||
url('pixelart-icons-font.ttf?t=1711815892278') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
|
||||
- url('pixelart-icons-font.svg?t=1711815892278#pixelart-icons-font') format('svg'); /* iOS 4.1- */
|
||||
}
|
||||
|
||||
[class^="pixelart-icons-font-"], [class*=" pixelart-icons-font-"] {
|
||||
font-family: 'pixelart-icons-font' !important;
|
||||
- font-size:24px;
|
||||
font-style:normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
@@ -503,4 +500,3 @@
|
||||
.pixelart-icons-font-zap:before { content: "\ebe4"; }
|
||||
.pixelart-icons-font-zoom-in:before { content: "\ebe5"; }
|
||||
.pixelart-icons-font-zoom-out:before { content: "\ebe6"; }
|
||||
-
|
||||
16
patches/three@0.154.0.patch
Normal file
16
patches/three@0.154.0.patch
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
diff --git a/examples/jsm/webxr/VRButton.js b/examples/jsm/webxr/VRButton.js
|
||||
index 6856a21b17aa45d7922bbf776fd2d7e63c7a9b4e..0925b706f7629bd52f0bb5af469536af8f5fce2c 100644
|
||||
--- a/examples/jsm/webxr/VRButton.js
|
||||
+++ b/examples/jsm/webxr/VRButton.js
|
||||
@@ -62,7 +62,10 @@ class VRButton {
|
||||
// ('local' is always available for immersive sessions and doesn't need to
|
||||
// be requested separately.)
|
||||
|
||||
- const sessionInit = { optionalFeatures: [ 'local-floor', 'bounded-floor', 'hand-tracking', 'layers' ] };
|
||||
+ const sessionInit = {
|
||||
+ optionalFeatures: ['local-floor', 'bounded-floor', 'layers'],
|
||||
+ domOverlay: { root: document.body },
|
||||
+ };
|
||||
navigator.xr.requestSession( 'immersive-vr', sessionInit ).then( onSessionStarted );
|
||||
|
||||
} else {
|
||||
384
pnpm-lock.yaml
generated
384
pnpm-lock.yaml
generated
|
|
@ -12,14 +12,20 @@ overrides:
|
|||
prismarine-world: github:zardoy/prismarine-world#next-era
|
||||
minecraft-data: 3.65.0
|
||||
prismarine-provider-anvil: github:zardoy/prismarine-provider-anvil#everything
|
||||
minecraft-protocol: github:PrismarineJS/node-minecraft-protocol
|
||||
minecraft-protocol: github:PrismarineJS/node-minecraft-protocol#master
|
||||
react: ^18.2.0
|
||||
prismarine-chunk: github:zardoy/prismarine-chunk
|
||||
|
||||
patchedDependencies:
|
||||
minecraft-protocol@1.47.0:
|
||||
hash: 2uxevyasyasdavsxuehfavgkjq
|
||||
hash: 7otpchsbv7hxsuis4rrrwdtbve
|
||||
path: patches/minecraft-protocol@1.47.0.patch
|
||||
pixelarticons@1.8.1:
|
||||
hash: cclg2qo6d4yjs4evj64nr2mbwa
|
||||
path: patches/pixelarticons@1.8.1.patch
|
||||
three@0.154.0:
|
||||
hash: sj7ocb4p23jym6bkfgueanti2e
|
||||
path: patches/three@0.154.0.patch
|
||||
|
||||
importers:
|
||||
|
||||
|
|
@ -62,8 +68,8 @@ importers:
|
|||
specifier: ^2.1.3
|
||||
version: 2.1.3
|
||||
'@zardoy/react-util':
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
specifier: ^0.2.4
|
||||
version: 0.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
'@zardoy/utils':
|
||||
specifier: ^0.0.11
|
||||
version: 0.0.11
|
||||
|
|
@ -107,17 +113,14 @@ importers:
|
|||
specifier: ^10.0.12
|
||||
version: 10.0.12
|
||||
flying-squid:
|
||||
specifier: npm:@zardoy/flying-squid@^0.0.20
|
||||
version: '@zardoy/flying-squid@0.0.20(encoding@0.1.13)'
|
||||
specifier: npm:@zardoy/flying-squid@^0.0.33
|
||||
version: '@zardoy/flying-squid@0.0.33(encoding@0.1.13)'
|
||||
fs-extra:
|
||||
specifier: ^11.1.1
|
||||
version: 11.1.1
|
||||
google-drive-browserfs:
|
||||
specifier: github:zardoy/browserfs#google-drive
|
||||
version: browserfs@https://codeload.github.com/zardoy/browserfs/tar.gz/ab58ae8ef00e3a31db01909e365e6cb5188436e0
|
||||
iconify-icon:
|
||||
specifier: ^1.0.8
|
||||
version: 1.0.8
|
||||
jszip:
|
||||
specifier: ^3.10.1
|
||||
version: 3.10.1
|
||||
|
|
@ -134,8 +137,8 @@ importers:
|
|||
specifier: 3.65.0
|
||||
version: 3.65.0
|
||||
minecraft-protocol:
|
||||
specifier: github:PrismarineJS/node-minecraft-protocol
|
||||
version: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=2uxevyasyasdavsxuehfavgkjq)(encoding@0.1.13)
|
||||
specifier: github:PrismarineJS/node-minecraft-protocol#master
|
||||
version: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=7otpchsbv7hxsuis4rrrwdtbve)(encoding@0.1.13)
|
||||
mineflayer-item-map-downloader:
|
||||
specifier: github:zardoy/mineflayer-item-map-downloader
|
||||
version: https://codeload.github.com/zardoy/mineflayer-item-map-downloader/tar.gz/642fd4f7023a98a96da4caf8f993f8e19361a1e7(encoding@0.1.13)
|
||||
|
|
@ -144,19 +147,22 @@ importers:
|
|||
version: 2.0.4
|
||||
net-browserify:
|
||||
specifier: github:zardoy/prismarinejs-net-browserify
|
||||
version: https://codeload.github.com/zardoy/prismarinejs-net-browserify/tar.gz/7d827dba61bd2f9ac9a6086fe2079a0fccadd070
|
||||
version: https://codeload.github.com/zardoy/prismarinejs-net-browserify/tar.gz/231ef1737a078e8cb51e8c695b48d7b43ce3bc53
|
||||
node-gzip:
|
||||
specifier: ^1.1.2
|
||||
version: 1.1.2
|
||||
peerjs:
|
||||
specifier: ^1.5.0
|
||||
version: 1.5.0
|
||||
pixelarticons:
|
||||
specifier: ^1.8.1
|
||||
version: 1.8.1(patch_hash=cclg2qo6d4yjs4evj64nr2mbwa)
|
||||
pretty-bytes:
|
||||
specifier: ^6.1.1
|
||||
version: 6.1.1
|
||||
prismarine-provider-anvil:
|
||||
specifier: github:zardoy/prismarine-provider-anvil#everything
|
||||
version: https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/02d81b0eba6ab1c362862970954f9a3c150c9a29(minecraft-data@3.65.0)
|
||||
version: https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/0228b5252f48a0d6ad7f36d7189851c427fbe8c4(minecraft-data@3.65.0)
|
||||
prosemirror-example-setup:
|
||||
specifier: ^1.2.2
|
||||
version: 1.2.2
|
||||
|
|
@ -223,6 +229,9 @@ importers:
|
|||
vec3:
|
||||
specifier: ^0.1.7
|
||||
version: 0.1.8
|
||||
wait-on:
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0(debug@4.3.4)
|
||||
workbox-build:
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0(@types/babel__core@7.20.2)
|
||||
|
|
@ -261,6 +270,9 @@ importers:
|
|||
'@types/ua-parser-js':
|
||||
specifier: ^0.7.39
|
||||
version: 0.7.39
|
||||
'@types/wait-on':
|
||||
specifier: ^5.3.4
|
||||
version: 5.3.4
|
||||
'@xmcl/installer':
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0
|
||||
|
|
@ -277,7 +289,7 @@ importers:
|
|||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
contro-max:
|
||||
specifier: ^0.1.6
|
||||
specifier: ^0.1.8
|
||||
version: 0.1.8(typescript@5.5.0-beta)
|
||||
crypto-browserify:
|
||||
specifier: ^3.12.0
|
||||
|
|
@ -308,10 +320,10 @@ importers:
|
|||
version: 1.0.0
|
||||
minecraft-inventory-gui:
|
||||
specifier: github:zardoy/minecraft-inventory-gui#next
|
||||
version: https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/5554c7ab0a74bce52aa5f5f04a48eb8d3b9ac65c(@types/react@18.2.20)(react@18.2.0)
|
||||
version: https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/c50afc54e39817f7e4d313ce0f6fdaad71e7e4f4(@types/react@18.2.20)(react@18.2.0)
|
||||
mineflayer:
|
||||
specifier: github:PrismarineJS/mineflayer
|
||||
version: https://codeload.github.com/PrismarineJS/mineflayer/tar.gz/ec76468c8ac4c6232bad3c2b66d4160f95f58396(encoding@0.1.13)
|
||||
specifier: github:zardoy/mineflayer
|
||||
version: https://codeload.github.com/zardoy/mineflayer/tar.gz/dddc683544317f117172077a9245a07be1b12479(encoding@0.1.13)
|
||||
mineflayer-pathfinder:
|
||||
specifier: ^2.4.4
|
||||
version: 2.4.4
|
||||
|
|
@ -344,7 +356,7 @@ importers:
|
|||
version: 3.0.0
|
||||
three:
|
||||
specifier: 0.154.0
|
||||
version: 0.154.0
|
||||
version: 0.154.0(patch_hash=sj7ocb4p23jym6bkfgueanti2e)
|
||||
timers-browserify:
|
||||
specifier: ^2.0.12
|
||||
version: 2.0.12
|
||||
|
|
@ -395,10 +407,10 @@ importers:
|
|||
version: 1.3.6
|
||||
prismarine-block:
|
||||
specifier: github:zardoy/prismarine-block#next-era
|
||||
version: https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0
|
||||
version: https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8
|
||||
prismarine-chunk:
|
||||
specifier: github:zardoy/prismarine-chunk
|
||||
version: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/eb39a905761a36f733a456110e6b49d655bf5c16(minecraft-data@3.65.0)
|
||||
version: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/9662306deea57d8d0ba0a2a3f3f7adb95f0131e3(minecraft-data@3.65.0)
|
||||
prismarine-schematic:
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.3
|
||||
|
|
@ -416,7 +428,7 @@ importers:
|
|||
version: 4.7.2
|
||||
three-stdlib:
|
||||
specifier: ^2.26.11
|
||||
version: 2.28.5(three@0.154.0)
|
||||
version: 2.28.5(three@0.154.0(patch_hash=sj7ocb4p23jym6bkfgueanti2e))
|
||||
three.meshline:
|
||||
specifier: ^1.3.0
|
||||
version: 1.4.0
|
||||
|
|
@ -1718,6 +1730,12 @@ packages:
|
|||
'@gar/promisify@1.1.3':
|
||||
resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
|
||||
|
||||
'@hapi/hoek@9.3.0':
|
||||
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
|
||||
|
||||
'@hapi/topo@5.1.0':
|
||||
resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==}
|
||||
|
||||
'@humanwhocodes/config-array@0.11.11':
|
||||
resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
|
|
@ -1729,9 +1747,6 @@ packages:
|
|||
'@humanwhocodes/object-schema@1.2.1':
|
||||
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
|
||||
|
||||
'@iconify/types@2.0.0':
|
||||
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
|
|
@ -2405,6 +2420,15 @@ packages:
|
|||
'@rushstack/eslint-patch@1.4.0':
|
||||
resolution: {integrity: sha512-cEjvTPU32OM9lUFegJagO0mRnIn+rbqrG89vV8/xLnLFX0DoR0r1oy5IlTga71Q7uT3Qus7qm7wgeiMT/+Irlg==}
|
||||
|
||||
'@sideway/address@4.1.5':
|
||||
resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==}
|
||||
|
||||
'@sideway/formula@3.0.1':
|
||||
resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==}
|
||||
|
||||
'@sideway/pinpoint@2.0.0':
|
||||
resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==}
|
||||
|
||||
'@sinclair/typebox@0.27.8':
|
||||
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
|
||||
|
||||
|
|
@ -2811,15 +2835,12 @@ packages:
|
|||
'@types/node@16.18.58':
|
||||
resolution: {integrity: sha512-YGncyA25/MaVtQkjWW9r0EFBukZ+JulsLcVZBlGUfIb96OBMjkoRWwQo5IEWJ8Fj06Go3GHw+bjYDitv6BaGsA==}
|
||||
|
||||
'@types/node@20.11.19':
|
||||
resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==}
|
||||
'@types/node@20.12.8':
|
||||
resolution: {integrity: sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==}
|
||||
|
||||
'@types/node@20.8.0':
|
||||
resolution: {integrity: sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ==}
|
||||
|
||||
'@types/node@20.8.10':
|
||||
resolution: {integrity: sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==}
|
||||
|
||||
'@types/normalize-package-data@2.4.2':
|
||||
resolution: {integrity: sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==}
|
||||
|
||||
|
|
@ -2904,6 +2925,9 @@ packages:
|
|||
'@types/unist@3.0.2':
|
||||
resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==}
|
||||
|
||||
'@types/wait-on@5.3.4':
|
||||
resolution: {integrity: sha512-EBsPjFMrFlMbbUFf9D1Fp+PAB2TwmUn7a3YtHyD9RLuTIk1jDd8SxXVAoez2Ciy+8Jsceo2MYEYZzJ/DvorOKw==}
|
||||
|
||||
'@types/webxr@0.5.7':
|
||||
resolution: {integrity: sha512-Rcgs5c2eNFnHp53YOjgtKfl/zWX1Y+uFGUwlSXrWcZWu3yhANRezmph4MninmqybUYT6g9ZE0aQ9QIdPkLR3Kg==}
|
||||
|
||||
|
|
@ -3081,17 +3105,17 @@ packages:
|
|||
resolution: {integrity: sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg==}
|
||||
engines: {node: '>=12 <14 || 14.2 - 14.9 || >14.10.0'}
|
||||
|
||||
'@zardoy/flying-squid@0.0.20':
|
||||
resolution: {integrity: sha512-WyejZS2Upzv86g6Ez5Z/4Pd0ea9tkFL2itAj24UNpO7fyzxuTN2Ag1Ouvh+MSkCloXhR4E/yoER2krHW8vzwBw==}
|
||||
'@zardoy/flying-squid@0.0.33':
|
||||
resolution: {integrity: sha512-zCgHinWrNbS4HugnA1GBMuKQ0rUemBg//b+XhefxKeGBg9ngk8UVlJoR6cCAaa67zjiauEq/rhnNKnA4V7vtuQ==}
|
||||
engines: {node: '>=8'}
|
||||
hasBin: true
|
||||
|
||||
'@zardoy/react-util@0.2.0':
|
||||
resolution: {integrity: sha512-glABtx54mh4XSaK6BNALWE3mlshPjcPwPsRj/GnOXEA7WJY/6n43iJoukbaYF3758mGZRU5Fq6gklyFjBg0yHQ==}
|
||||
'@zardoy/react-util@0.2.4':
|
||||
resolution: {integrity: sha512-YRBbXi54QOgWGDSn3NLEMMGrWbfL/gn2khxO31HT0WPFB6IW2rSnB4hcy+S/nc+2D6PRNq4kQxGs4vTAe4a7Xg==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
peerDependencies:
|
||||
react: ^18.2.0
|
||||
react-dom: ^18.0.0
|
||||
react-dom: '>=18.0.0'
|
||||
|
||||
'@zardoy/utils@0.0.11':
|
||||
resolution: {integrity: sha512-d6xBnSFCOa98HcL52xSBflJKjKpxfRhtr1eVexy89YujeCHSQhUMmSz9h07xyrulfW60k9tSeYH5reuqoh4l4w==}
|
||||
|
|
@ -3317,9 +3341,6 @@ packages:
|
|||
resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
asap@1.0.0:
|
||||
resolution: {integrity: sha512-Ej9qjcXY+8Tuy1cNqiwNMwFRXOy9UwgTeMA8LxreodygIPV48lx8PU1ecFxb5ZeU1DpMKxiq6vGLTxcitWZPbA==}
|
||||
|
||||
asn1.js@5.4.1:
|
||||
resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==}
|
||||
|
||||
|
|
@ -3403,6 +3424,9 @@ packages:
|
|||
axios@0.21.4:
|
||||
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
|
||||
|
||||
axios@1.7.2:
|
||||
resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==}
|
||||
|
||||
babel-core@7.0.0-bridge.0:
|
||||
resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==}
|
||||
peerDependencies:
|
||||
|
|
@ -4208,8 +4232,8 @@ packages:
|
|||
devlop@1.1.0:
|
||||
resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
|
||||
|
||||
diamond-square@https://codeload.github.com/zardoy/diamond-square/tar.gz/915fce8e27fe8eb45464d89b9563956afa4f7687:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/diamond-square/tar.gz/915fce8e27fe8eb45464d89b9563956afa4f7687}
|
||||
diamond-square@https://codeload.github.com/zardoy/diamond-square/tar.gz/4bbe28dcad35403abaa925055e91f601a61b9015:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/diamond-square/tar.gz/4bbe28dcad35403abaa925055e91f601a61b9015}
|
||||
version: 1.3.0
|
||||
|
||||
diff-sequences@29.6.3:
|
||||
|
|
@ -4658,12 +4682,6 @@ packages:
|
|||
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
event-promise@0.0.1:
|
||||
resolution: {integrity: sha512-ouEmk2N0BalybPM0zmj3RHE93AX4p9hAIHZfbbqxolLChqCB6pcLDbYH6zZ8TaiFWImPHfs5kFnNpA0u9RdEaQ==}
|
||||
|
||||
event-stream@3.3.4:
|
||||
resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==}
|
||||
|
||||
event-target-shim@5.0.1:
|
||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
@ -5317,9 +5335,6 @@ packages:
|
|||
hyphenate-style-name@1.0.4:
|
||||
resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==}
|
||||
|
||||
iconify-icon@1.0.8:
|
||||
resolution: {integrity: sha512-jvbUKHXf8EnGGArmhlP2IG8VqQLFFyTvTqb9LVL2TKTh7/eCCD1o2HHE9thpbJJb6B8hzhcFb6rOKhvo7reNKA==}
|
||||
|
||||
iconv-lite@0.4.24:
|
||||
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -5739,8 +5754,11 @@ packages:
|
|||
jimp@0.10.3:
|
||||
resolution: {integrity: sha512-meVWmDMtyUG5uYjFkmzu0zBgnCvvxwWNi27c4cg55vWNVC9ES4Lcwb+ogx+uBBQE3Q+dLKjXaLl0JVW+nUNwbQ==}
|
||||
|
||||
jose@4.15.4:
|
||||
resolution: {integrity: sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==}
|
||||
joi@17.13.1:
|
||||
resolution: {integrity: sha512-vaBlIKCyo4FCUtCm7Eu4QZd/q02bWcxfUO6YSXAZOWF6gzcLBeba8kwotUdYJjDLW8Cz8RywsSOqiNJZW0mNvg==}
|
||||
|
||||
jose@4.15.5:
|
||||
resolution: {integrity: sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==}
|
||||
|
||||
jpeg-js@0.3.7:
|
||||
resolution: {integrity: sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ==}
|
||||
|
|
@ -6287,8 +6305,8 @@ packages:
|
|||
minecraft-folder-path@1.2.0:
|
||||
resolution: {integrity: sha512-qaUSbKWoOsH9brn0JQuBhxNAzTDMwrOXorwuRxdJKKKDYvZhtml+6GVCUrY5HRiEsieBEjCUnhVpDuQiKsiFaw==}
|
||||
|
||||
minecraft-inventory-gui@https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/5554c7ab0a74bce52aa5f5f04a48eb8d3b9ac65c:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/5554c7ab0a74bce52aa5f5f04a48eb8d3b9ac65c}
|
||||
minecraft-inventory-gui@https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/c50afc54e39817f7e4d313ce0f6fdaad71e7e4f4:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/c50afc54e39817f7e4d313ce0f6fdaad71e7e4f4}
|
||||
version: 1.0.1
|
||||
|
||||
minecraft-protocol@https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc:
|
||||
|
|
@ -6314,8 +6332,8 @@ packages:
|
|||
resolution: {integrity: sha512-QMMNPx4IyZE7ydAzjvGLQLCnQNUOfkk1qVZKxTTS9q3qPTAewz4GhsVUBtbQ8LSbHthe5RcQ1Sgxs4wlIma/Qw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
mineflayer@https://codeload.github.com/PrismarineJS/mineflayer/tar.gz/ec76468c8ac4c6232bad3c2b66d4160f95f58396:
|
||||
resolution: {tarball: https://codeload.github.com/PrismarineJS/mineflayer/tar.gz/ec76468c8ac4c6232bad3c2b66d4160f95f58396}
|
||||
mineflayer@https://codeload.github.com/zardoy/mineflayer/tar.gz/dddc683544317f117172077a9245a07be1b12479:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/mineflayer/tar.gz/dddc683544317f117172077a9245a07be1b12479}
|
||||
version: 4.20.1
|
||||
engines: {node: '>=18'}
|
||||
|
||||
|
|
@ -6479,8 +6497,8 @@ packages:
|
|||
nested-error-stacks@2.1.1:
|
||||
resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==}
|
||||
|
||||
net-browserify@https://codeload.github.com/zardoy/prismarinejs-net-browserify/tar.gz/7d827dba61bd2f9ac9a6086fe2079a0fccadd070:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarinejs-net-browserify/tar.gz/7d827dba61bd2f9ac9a6086fe2079a0fccadd070}
|
||||
net-browserify@https://codeload.github.com/zardoy/prismarinejs-net-browserify/tar.gz/231ef1737a078e8cb51e8c695b48d7b43ce3bc53:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarinejs-net-browserify/tar.gz/231ef1737a078e8cb51e8c695b48d7b43ce3bc53}
|
||||
version: 0.2.4
|
||||
|
||||
nice-try@1.0.5:
|
||||
|
|
@ -6900,6 +6918,9 @@ packages:
|
|||
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
pixelarticons@1.8.1:
|
||||
resolution: {integrity: sha512-4taoDCleft9RtzVHLA73VDnRBwJNqlwbW8ShO6S0G9b+bM5ArGe1MVFW9xpromuPvQgVUYCSjRxNAQuNtADqyA==}
|
||||
|
||||
pixelmatch@4.0.2:
|
||||
resolution: {integrity: sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==}
|
||||
hasBin: true
|
||||
|
|
@ -6997,18 +7018,20 @@ packages:
|
|||
minecraft-data: 3.65.0
|
||||
prismarine-registry: ^1.1.0
|
||||
|
||||
prismarine-block@https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0}
|
||||
prismarine-block@https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8}
|
||||
version: 1.17.1
|
||||
|
||||
prismarine-chat@1.10.1:
|
||||
resolution: {integrity: sha512-XukYcuueuhDxzEXG7r8BZyt6jOObrPPB4JESCgb+/XenB9nExoSHF8eTQWWj8faKPLqm1dRQaYwFJlNBlJZJUw==}
|
||||
|
||||
prismarine-chat@1.9.1:
|
||||
resolution: {integrity: sha512-x7WWa5MNhiLZSO6tw+YyKpzquFZ+DNISVgiV6K3SU0GsishMXe+nto02WhF/4AuFerKdugm9u1d/r4C4zSkJOg==}
|
||||
prismarine-chunk@https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/9662306deea57d8d0ba0a2a3f3f7adb95f0131e3:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/9662306deea57d8d0ba0a2a3f3f7adb95f0131e3}
|
||||
version: 1.35.0
|
||||
engines: {node: '>=14'}
|
||||
|
||||
prismarine-chunk@https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/eb39a905761a36f733a456110e6b49d655bf5c16:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/eb39a905761a36f733a456110e6b49d655bf5c16}
|
||||
prismarine-chunk@https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/cea0b6c792d7dcbb69dfd20fa48be5fd60ce83ef:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/cea0b6c792d7dcbb69dfd20fa48be5fd60ce83ef}
|
||||
version: 1.35.0
|
||||
engines: {node: '>=14'}
|
||||
|
||||
|
|
@ -7027,9 +7050,9 @@ packages:
|
|||
prismarine-physics@1.8.0:
|
||||
resolution: {integrity: sha512-gbM+S+bmVtOKVv+Z0WGaHMeEeBHISIDsRDRlv8sr0dex3ZJRhuq8djA02CBreguXtI18ZKh6q3TSj2qDr45NHA==}
|
||||
|
||||
prismarine-provider-anvil@https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/02d81b0eba6ab1c362862970954f9a3c150c9a29:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/02d81b0eba6ab1c362862970954f9a3c150c9a29}
|
||||
version: 2.7.0
|
||||
prismarine-provider-anvil@https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/0228b5252f48a0d6ad7f36d7189851c427fbe8c4:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/0228b5252f48a0d6ad7f36d7189851c427fbe8c4}
|
||||
version: 2.8.0
|
||||
|
||||
prismarine-realms@1.3.2:
|
||||
resolution: {integrity: sha512-5apl9Ru8veTj5q2OozRc4GZOuSIcs3yY4UEtALiLKHstBe8bRw8vNlaz4Zla3jsQ8yP/ul1b1IJINTRbocuA6g==}
|
||||
|
|
@ -7048,9 +7071,9 @@ packages:
|
|||
prismarine-windows@2.9.0:
|
||||
resolution: {integrity: sha512-fm4kOLjGFPov7TEJRmXHoiPabxIQrG36r2mDjlNxfkcLfMHFb3/1ML6mp4iRQa7wL0GK4DIAyiBqCWoeWDxARg==}
|
||||
|
||||
prismarine-world@https://codeload.github.com/zardoy/prismarine-world/tar.gz/6ae6f009d38460de284f8c226c665f04cbad9465:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarine-world/tar.gz/6ae6f009d38460de284f8c226c665f04cbad9465}
|
||||
version: 3.6.2
|
||||
prismarine-world@https://codeload.github.com/zardoy/prismarine-world/tar.gz/187a87f6d71cba12881a7bbaa510ed9085bf6da7:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/prismarine-world/tar.gz/187a87f6d71cba12881a7bbaa510ed9085bf6da7}
|
||||
version: 3.6.3
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
process-nextick-args@2.0.1:
|
||||
|
|
@ -7085,9 +7108,6 @@ packages:
|
|||
resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
promise@5.0.0:
|
||||
resolution: {integrity: sha512-N2BfLz0Sigf7rsm5NnItRwTNqEDUF2ephwEXTcOAf2cO9NwZ9TnIjOmnQNtC0r70CV0S1+uc9mSMmFH7gxk87Q==}
|
||||
|
||||
prompts@2.4.2:
|
||||
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
|
||||
engines: {node: '>= 6'}
|
||||
|
|
@ -7155,9 +7175,8 @@ packages:
|
|||
proxy-from-env@1.0.0:
|
||||
resolution: {integrity: sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==}
|
||||
|
||||
proxy-middleware@0.15.0:
|
||||
resolution: {integrity: sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
psl@1.9.0:
|
||||
resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
|
||||
|
|
@ -7299,6 +7318,12 @@ packages:
|
|||
react-fast-compare@3.2.2:
|
||||
resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==}
|
||||
|
||||
react-hook-form@7.52.0:
|
||||
resolution: {integrity: sha512-mJX506Xc6mirzLsmXUJyqlAI3Kj9Ph2RhplYhUVffeOQSnubK2uVqBFOBJmvKikvbFV91pxVXmDiR+QMF19x6A==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
peerDependencies:
|
||||
react: ^18.2.0
|
||||
|
||||
react-inspector@6.0.2:
|
||||
resolution: {integrity: sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -8752,6 +8777,11 @@ packages:
|
|||
w3c-keyname@2.2.8:
|
||||
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
|
||||
|
||||
wait-on@7.2.0:
|
||||
resolution: {integrity: sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
hasBin: true
|
||||
|
||||
walker@1.0.8:
|
||||
resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
|
||||
|
||||
|
|
@ -10318,6 +10348,12 @@ snapshots:
|
|||
'@gar/promisify@1.1.3':
|
||||
optional: true
|
||||
|
||||
'@hapi/hoek@9.3.0': {}
|
||||
|
||||
'@hapi/topo@5.1.0':
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
|
||||
'@humanwhocodes/config-array@0.11.11':
|
||||
dependencies:
|
||||
'@humanwhocodes/object-schema': 1.2.1
|
||||
|
|
@ -10330,8 +10366,6 @@ snapshots:
|
|||
|
||||
'@humanwhocodes/object-schema@1.2.1': {}
|
||||
|
||||
'@iconify/types@2.0.0': {}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
dependencies:
|
||||
string-width: 5.1.2
|
||||
|
|
@ -11159,6 +11193,14 @@ snapshots:
|
|||
|
||||
'@rushstack/eslint-patch@1.4.0': {}
|
||||
|
||||
'@sideway/address@4.1.5':
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
|
||||
'@sideway/formula@3.0.1': {}
|
||||
|
||||
'@sideway/pinpoint@2.0.0': {}
|
||||
|
||||
'@sinclair/typebox@0.27.8': {}
|
||||
|
||||
'@socket.io/component-emitter@3.1.0': {}
|
||||
|
|
@ -11830,8 +11872,7 @@ snapshots:
|
|||
magic-string: 0.25.9
|
||||
string.prototype.matchall: 4.0.10
|
||||
|
||||
'@tootallnate/once@2.0.0':
|
||||
optional: true
|
||||
'@tootallnate/once@2.0.0': {}
|
||||
|
||||
'@tweenjs/tween.js@18.6.4': {}
|
||||
|
||||
|
|
@ -11861,7 +11902,7 @@ snapshots:
|
|||
'@types/body-parser@1.19.3':
|
||||
dependencies:
|
||||
'@types/connect': 3.4.36
|
||||
'@types/node': 20.8.0
|
||||
'@types/node': 20.12.8
|
||||
|
||||
'@types/chai-subset@1.3.3':
|
||||
dependencies:
|
||||
|
|
@ -11871,7 +11912,7 @@ snapshots:
|
|||
|
||||
'@types/connect@3.4.36':
|
||||
dependencies:
|
||||
'@types/node': 20.8.10
|
||||
'@types/node': 20.12.8
|
||||
|
||||
'@types/cookie@0.4.1': {}
|
||||
|
||||
|
|
@ -11907,7 +11948,7 @@ snapshots:
|
|||
|
||||
'@types/express-serve-static-core@4.17.37':
|
||||
dependencies:
|
||||
'@types/node': 20.8.0
|
||||
'@types/node': 20.12.8
|
||||
'@types/qs': 6.9.8
|
||||
'@types/range-parser': 1.2.5
|
||||
'@types/send': 0.17.2
|
||||
|
|
@ -11926,7 +11967,7 @@ snapshots:
|
|||
'@types/glob@7.2.0':
|
||||
dependencies:
|
||||
'@types/minimatch': 5.1.2
|
||||
'@types/node': 20.8.0
|
||||
'@types/node': 20.12.8
|
||||
|
||||
'@types/graceful-fs@4.1.7':
|
||||
dependencies:
|
||||
|
|
@ -11985,16 +12026,12 @@ snapshots:
|
|||
|
||||
'@types/node@16.18.58': {}
|
||||
|
||||
'@types/node@20.11.19':
|
||||
'@types/node@20.12.8':
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
|
||||
'@types/node@20.8.0': {}
|
||||
|
||||
'@types/node@20.8.10':
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
|
||||
'@types/normalize-package-data@2.4.2': {}
|
||||
|
||||
'@types/offscreencanvas@2019.7.2': {}
|
||||
|
|
@ -12051,7 +12088,7 @@ snapshots:
|
|||
dependencies:
|
||||
'@types/http-errors': 2.0.2
|
||||
'@types/mime': 3.0.2
|
||||
'@types/node': 20.8.0
|
||||
'@types/node': 20.12.8
|
||||
|
||||
'@types/sinonjs__fake-timers@8.1.1': {}
|
||||
|
||||
|
|
@ -12083,6 +12120,10 @@ snapshots:
|
|||
|
||||
'@types/unist@3.0.2': {}
|
||||
|
||||
'@types/wait-on@5.3.4':
|
||||
dependencies:
|
||||
'@types/node': 20.12.8
|
||||
|
||||
'@types/webxr@0.5.7': {}
|
||||
|
||||
'@types/wicg-file-system-access@2023.10.2': {}
|
||||
|
|
@ -12099,7 +12140,7 @@ snapshots:
|
|||
|
||||
'@types/yauzl@2.10.3':
|
||||
dependencies:
|
||||
'@types/node': 20.11.19
|
||||
'@types/node': 20.12.8
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/eslint-plugin@6.1.0(@typescript-eslint/parser@6.7.3(eslint@8.50.0)(typescript@5.5.0-beta))(eslint@8.50.0)(typescript@5.5.0-beta)':
|
||||
|
|
@ -12319,32 +12360,33 @@ snapshots:
|
|||
'@types/emscripten': 1.39.8
|
||||
tslib: 1.14.1
|
||||
|
||||
'@zardoy/flying-squid@0.0.20(encoding@0.1.13)':
|
||||
'@zardoy/flying-squid@0.0.33(encoding@0.1.13)':
|
||||
dependencies:
|
||||
'@tootallnate/once': 2.0.0
|
||||
change-case: 4.1.2
|
||||
colors: 1.4.0
|
||||
diamond-square: https://codeload.github.com/zardoy/diamond-square/tar.gz/915fce8e27fe8eb45464d89b9563956afa4f7687
|
||||
diamond-square: https://codeload.github.com/zardoy/diamond-square/tar.gz/4bbe28dcad35403abaa925055e91f601a61b9015
|
||||
emit-then: 2.0.0
|
||||
event-promise: 0.0.1
|
||||
exit-hook: 2.2.1
|
||||
flatmap: 0.0.3
|
||||
long: 5.2.3
|
||||
minecraft-data: 3.65.0
|
||||
minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=2uxevyasyasdavsxuehfavgkjq)(encoding@0.1.13)
|
||||
minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=7otpchsbv7hxsuis4rrrwdtbve)(encoding@0.1.13)
|
||||
mkdirp: 2.1.6
|
||||
node-gzip: 1.1.2
|
||||
node-rsa: 1.1.1
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/eb39a905761a36f733a456110e6b49d655bf5c16(minecraft-data@3.65.0)
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/cea0b6c792d7dcbb69dfd20fa48be5fd60ce83ef(minecraft-data@3.65.0)
|
||||
prismarine-entity: 2.3.1
|
||||
prismarine-item: 1.14.0
|
||||
prismarine-nbt: 2.5.0
|
||||
prismarine-provider-anvil: https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/02d81b0eba6ab1c362862970954f9a3c150c9a29(minecraft-data@3.65.0)
|
||||
prismarine-provider-anvil: https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/0228b5252f48a0d6ad7f36d7189851c427fbe8c4(minecraft-data@3.65.0)
|
||||
prismarine-windows: 2.9.0
|
||||
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/6ae6f009d38460de284f8c226c665f04cbad9465
|
||||
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/187a87f6d71cba12881a7bbaa510ed9085bf6da7
|
||||
rambda: 9.2.0
|
||||
random-seed: 0.3.0
|
||||
range: 0.0.3
|
||||
readline: 1.3.0
|
||||
sanitize-filename: 1.6.3
|
||||
typed-emitter: 1.4.0
|
||||
uuid-1345: 1.0.2
|
||||
vec3: 0.1.8
|
||||
|
|
@ -12354,11 +12396,12 @@ snapshots:
|
|||
- encoding
|
||||
- supports-color
|
||||
|
||||
'@zardoy/react-util@0.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
|
||||
'@zardoy/react-util@0.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
|
||||
dependencies:
|
||||
classnames: 2.5.1
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
react-hook-form: 7.52.0(react@18.2.0)
|
||||
|
||||
'@zardoy/utils@0.0.11':
|
||||
dependencies:
|
||||
|
|
@ -12592,8 +12635,6 @@ snapshots:
|
|||
|
||||
arrify@1.0.1: {}
|
||||
|
||||
asap@1.0.0: {}
|
||||
|
||||
asn1.js@5.4.1:
|
||||
dependencies:
|
||||
bn.js: 4.12.0
|
||||
|
|
@ -12668,6 +12709,14 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
axios@1.7.2(debug@4.3.4):
|
||||
dependencies:
|
||||
follow-redirects: 1.15.6(debug@4.3.4)
|
||||
form-data: 4.0.0
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
babel-core@7.0.0-bridge.0(@babel/core@7.22.11):
|
||||
dependencies:
|
||||
'@babel/core': 7.22.11
|
||||
|
|
@ -13686,10 +13735,11 @@ snapshots:
|
|||
dependencies:
|
||||
dequal: 2.0.3
|
||||
|
||||
diamond-square@https://codeload.github.com/zardoy/diamond-square/tar.gz/915fce8e27fe8eb45464d89b9563956afa4f7687:
|
||||
diamond-square@https://codeload.github.com/zardoy/diamond-square/tar.gz/4bbe28dcad35403abaa925055e91f601a61b9015:
|
||||
dependencies:
|
||||
minecraft-data: 3.65.0
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/eb39a905761a36f733a456110e6b49d655bf5c16(minecraft-data@3.65.0)
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/cea0b6c792d7dcbb69dfd20fa48be5fd60ce83ef(minecraft-data@3.65.0)
|
||||
prismarine-registry: 1.7.0
|
||||
random-seed: 0.3.0
|
||||
vec3: 0.1.8
|
||||
|
||||
|
|
@ -14413,20 +14463,6 @@ snapshots:
|
|||
|
||||
etag@1.8.1: {}
|
||||
|
||||
event-promise@0.0.1:
|
||||
dependencies:
|
||||
promise: 5.0.0
|
||||
|
||||
event-stream@3.3.4:
|
||||
dependencies:
|
||||
duplexer: 0.1.2
|
||||
from: 0.1.7
|
||||
map-stream: 0.1.0
|
||||
pause-stream: 0.0.11
|
||||
split: 0.3.3
|
||||
stream-combiner: 0.0.4
|
||||
through: 2.3.8
|
||||
|
||||
event-target-shim@5.0.1: {}
|
||||
|
||||
eventemitter2@6.4.7: {}
|
||||
|
|
@ -15254,10 +15290,6 @@ snapshots:
|
|||
|
||||
hyphenate-style-name@1.0.4: {}
|
||||
|
||||
iconify-icon@1.0.8:
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
|
||||
iconv-lite@0.4.24:
|
||||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
|
|
@ -15664,7 +15696,15 @@ snapshots:
|
|||
core-js: 3.32.1
|
||||
regenerator-runtime: 0.13.11
|
||||
|
||||
jose@4.15.4: {}
|
||||
joi@17.13.1:
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
'@hapi/topo': 5.1.0
|
||||
'@sideway/address': 4.1.5
|
||||
'@sideway/formula': 3.0.1
|
||||
'@sideway/pinpoint': 2.0.0
|
||||
|
||||
jose@4.15.5: {}
|
||||
|
||||
jpeg-js@0.3.7: {}
|
||||
|
||||
|
|
@ -16353,16 +16393,16 @@ snapshots:
|
|||
|
||||
minecraft-folder-path@1.2.0: {}
|
||||
|
||||
minecraft-inventory-gui@https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/5554c7ab0a74bce52aa5f5f04a48eb8d3b9ac65c(@types/react@18.2.20)(react@18.2.0):
|
||||
minecraft-inventory-gui@https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/c50afc54e39817f7e4d313ce0f6fdaad71e7e4f4(@types/react@18.2.20)(react@18.2.0):
|
||||
dependencies:
|
||||
valtio: 1.11.2(@types/react@18.2.20)(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
- react
|
||||
|
||||
minecraft-protocol@https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=2uxevyasyasdavsxuehfavgkjq)(encoding@0.1.13):
|
||||
minecraft-protocol@https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=7otpchsbv7hxsuis4rrrwdtbve)(encoding@0.1.13):
|
||||
dependencies:
|
||||
'@types/readable-stream': 4.0.10
|
||||
'@types/readable-stream': 4.0.12
|
||||
aes-js: 3.1.2
|
||||
buffer-equal: 1.0.1
|
||||
debug: 4.3.4(supports-color@8.1.1)
|
||||
|
|
@ -16373,7 +16413,7 @@ snapshots:
|
|||
minecraft-folder-path: 1.2.0
|
||||
node-fetch: 2.7.0(encoding@0.1.13)
|
||||
node-rsa: 0.4.2
|
||||
prismarine-auth: 2.4.1(encoding@0.1.13)
|
||||
prismarine-auth: 2.4.2(encoding@0.1.13)
|
||||
prismarine-chat: 1.10.1
|
||||
prismarine-nbt: 2.5.0
|
||||
prismarine-realms: 1.3.2(encoding@0.1.13)
|
||||
|
|
@ -16419,7 +16459,7 @@ snapshots:
|
|||
mineflayer-pathfinder@2.4.4:
|
||||
dependencies:
|
||||
minecraft-data: 3.65.0
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8
|
||||
prismarine-entity: 2.3.1
|
||||
prismarine-item: 1.14.0
|
||||
prismarine-nbt: 2.2.1
|
||||
|
|
@ -16429,11 +16469,11 @@ snapshots:
|
|||
mineflayer@4.20.1(encoding@0.1.13):
|
||||
dependencies:
|
||||
minecraft-data: 3.65.0
|
||||
minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=2uxevyasyasdavsxuehfavgkjq)(encoding@0.1.13)
|
||||
minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=7otpchsbv7hxsuis4rrrwdtbve)(encoding@0.1.13)
|
||||
prismarine-biome: 1.3.0(minecraft-data@3.65.0)(prismarine-registry@1.7.0)
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0
|
||||
prismarine-chat: 1.9.1
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/eb39a905761a36f733a456110e6b49d655bf5c16(minecraft-data@3.65.0)
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8
|
||||
prismarine-chat: 1.10.1
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/9662306deea57d8d0ba0a2a3f3f7adb95f0131e3(minecraft-data@3.65.0)
|
||||
prismarine-entity: 2.3.1
|
||||
prismarine-item: 1.14.0
|
||||
prismarine-nbt: 2.5.0
|
||||
|
|
@ -16441,7 +16481,7 @@ snapshots:
|
|||
prismarine-recipe: 1.3.1(prismarine-registry@1.7.0)
|
||||
prismarine-registry: 1.7.0
|
||||
prismarine-windows: 2.9.0
|
||||
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/6ae6f009d38460de284f8c226c665f04cbad9465
|
||||
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/187a87f6d71cba12881a7bbaa510ed9085bf6da7
|
||||
protodef: 1.15.0
|
||||
typed-emitter: 1.4.0
|
||||
vec3: 0.1.8
|
||||
|
|
@ -16449,14 +16489,14 @@ snapshots:
|
|||
- encoding
|
||||
- supports-color
|
||||
|
||||
mineflayer@https://codeload.github.com/PrismarineJS/mineflayer/tar.gz/ec76468c8ac4c6232bad3c2b66d4160f95f58396(encoding@0.1.13):
|
||||
mineflayer@https://codeload.github.com/zardoy/mineflayer/tar.gz/dddc683544317f117172077a9245a07be1b12479(encoding@0.1.13):
|
||||
dependencies:
|
||||
minecraft-data: 3.65.0
|
||||
minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=2uxevyasyasdavsxuehfavgkjq)(encoding@0.1.13)
|
||||
minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=7otpchsbv7hxsuis4rrrwdtbve)(encoding@0.1.13)
|
||||
prismarine-biome: 1.3.0(minecraft-data@3.65.0)(prismarine-registry@1.7.0)
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0
|
||||
prismarine-chat: 1.9.1
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/eb39a905761a36f733a456110e6b49d655bf5c16(minecraft-data@3.65.0)
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8
|
||||
prismarine-chat: 1.10.1
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/9662306deea57d8d0ba0a2a3f3f7adb95f0131e3(minecraft-data@3.65.0)
|
||||
prismarine-entity: 2.3.1
|
||||
prismarine-item: 1.14.0
|
||||
prismarine-nbt: 2.5.0
|
||||
|
|
@ -16464,7 +16504,7 @@ snapshots:
|
|||
prismarine-recipe: 1.3.1(prismarine-registry@1.7.0)
|
||||
prismarine-registry: 1.7.0
|
||||
prismarine-windows: 2.9.0
|
||||
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/6ae6f009d38460de284f8c226c665f04cbad9465
|
||||
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/187a87f6d71cba12881a7bbaa510ed9085bf6da7
|
||||
protodef: 1.15.0
|
||||
typed-emitter: 1.4.0
|
||||
vec3: 0.1.8
|
||||
|
|
@ -16646,7 +16686,7 @@ snapshots:
|
|||
|
||||
nested-error-stacks@2.1.1: {}
|
||||
|
||||
net-browserify@https://codeload.github.com/zardoy/prismarinejs-net-browserify/tar.gz/7d827dba61bd2f9ac9a6086fe2079a0fccadd070:
|
||||
net-browserify@https://codeload.github.com/zardoy/prismarinejs-net-browserify/tar.gz/231ef1737a078e8cb51e8c695b48d7b43ce3bc53:
|
||||
dependencies:
|
||||
body-parser: 1.20.2
|
||||
express: 4.18.2
|
||||
|
|
@ -17108,6 +17148,8 @@ snapshots:
|
|||
|
||||
pirates@4.0.6: {}
|
||||
|
||||
pixelarticons@1.8.1(patch_hash=cclg2qo6d4yjs4evj64nr2mbwa): {}
|
||||
|
||||
pixelmatch@4.0.2:
|
||||
dependencies:
|
||||
pngjs: 3.4.0
|
||||
|
|
@ -17215,11 +17257,11 @@ snapshots:
|
|||
minecraft-data: 3.65.0
|
||||
prismarine-registry: 1.7.0
|
||||
|
||||
prismarine-block@https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0:
|
||||
prismarine-block@https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8:
|
||||
dependencies:
|
||||
minecraft-data: 3.65.0
|
||||
prismarine-biome: 1.3.0(minecraft-data@3.65.0)(prismarine-registry@1.7.0)
|
||||
prismarine-chat: 1.9.1
|
||||
prismarine-chat: 1.10.1
|
||||
prismarine-item: 1.14.0
|
||||
prismarine-nbt: 2.5.0
|
||||
prismarine-registry: 1.7.0
|
||||
|
|
@ -17230,17 +17272,23 @@ snapshots:
|
|||
prismarine-nbt: 2.5.0
|
||||
prismarine-registry: 1.7.0
|
||||
|
||||
prismarine-chat@1.9.1:
|
||||
dependencies:
|
||||
mojangson: 2.0.4
|
||||
prismarine-item: 1.14.0
|
||||
prismarine-nbt: 2.5.0
|
||||
prismarine-registry: 1.7.0
|
||||
|
||||
prismarine-chunk@https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/eb39a905761a36f733a456110e6b49d655bf5c16(minecraft-data@3.65.0):
|
||||
prismarine-chunk@https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/9662306deea57d8d0ba0a2a3f3f7adb95f0131e3(minecraft-data@3.65.0):
|
||||
dependencies:
|
||||
prismarine-biome: 1.3.0(minecraft-data@3.65.0)(prismarine-registry@1.7.0)
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8
|
||||
prismarine-nbt: 2.5.0
|
||||
prismarine-registry: 1.7.0
|
||||
smart-buffer: 4.2.0
|
||||
uint4: 0.1.2
|
||||
vec3: 0.1.8
|
||||
xxhash-wasm: 0.4.2
|
||||
transitivePeerDependencies:
|
||||
- minecraft-data
|
||||
|
||||
prismarine-chunk@https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/cea0b6c792d7dcbb69dfd20fa48be5fd60ce83ef(minecraft-data@3.65.0):
|
||||
dependencies:
|
||||
prismarine-biome: 1.3.0(minecraft-data@3.65.0)(prismarine-registry@1.7.0)
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8
|
||||
prismarine-nbt: 2.5.0
|
||||
prismarine-registry: 1.7.0
|
||||
smart-buffer: 4.2.0
|
||||
|
|
@ -17276,10 +17324,12 @@ snapshots:
|
|||
prismarine-nbt: 2.5.0
|
||||
vec3: 0.1.8
|
||||
|
||||
prismarine-provider-anvil@https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/02d81b0eba6ab1c362862970954f9a3c150c9a29(minecraft-data@3.65.0):
|
||||
prismarine-provider-anvil@https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/0228b5252f48a0d6ad7f36d7189851c427fbe8c4(minecraft-data@3.65.0):
|
||||
dependencies:
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/eb39a905761a36f733a456110e6b49d655bf5c16(minecraft-data@3.65.0)
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/9662306deea57d8d0ba0a2a3f3f7adb95f0131e3(minecraft-data@3.65.0)
|
||||
prismarine-nbt: 2.5.0
|
||||
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/187a87f6d71cba12881a7bbaa510ed9085bf6da7
|
||||
uint4: 0.1.2
|
||||
vec3: 0.1.8
|
||||
transitivePeerDependencies:
|
||||
|
|
@ -17305,9 +17355,9 @@ snapshots:
|
|||
prismarine-schematic@1.2.3:
|
||||
dependencies:
|
||||
minecraft-data: 3.65.0
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/dd4954fff3b334f8ce063d18e39b2e9414ece5b8
|
||||
prismarine-nbt: 2.2.1
|
||||
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/6ae6f009d38460de284f8c226c665f04cbad9465
|
||||
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/187a87f6d71cba12881a7bbaa510ed9085bf6da7
|
||||
vec3: 0.1.8
|
||||
|
||||
prismarine-windows@2.9.0:
|
||||
|
|
@ -17316,7 +17366,7 @@ snapshots:
|
|||
prismarine-registry: 1.7.0
|
||||
typed-emitter: 2.1.0
|
||||
|
||||
prismarine-world@https://codeload.github.com/zardoy/prismarine-world/tar.gz/6ae6f009d38460de284f8c226c665f04cbad9465:
|
||||
prismarine-world@https://codeload.github.com/zardoy/prismarine-world/tar.gz/187a87f6d71cba12881a7bbaa510ed9085bf6da7:
|
||||
dependencies:
|
||||
vec3: 0.1.8
|
||||
|
||||
|
|
@ -17339,10 +17389,6 @@ snapshots:
|
|||
retry: 0.12.0
|
||||
optional: true
|
||||
|
||||
promise@5.0.0:
|
||||
dependencies:
|
||||
asap: 1.0.0
|
||||
|
||||
prompts@2.4.2:
|
||||
dependencies:
|
||||
kleur: 3.0.3
|
||||
|
|
@ -17460,7 +17506,7 @@ snapshots:
|
|||
|
||||
proxy-from-env@1.0.0: {}
|
||||
|
||||
proxy-middleware@0.15.0: {}
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
psl@1.9.0: {}
|
||||
|
||||
|
|
@ -17631,6 +17677,10 @@ snapshots:
|
|||
|
||||
react-fast-compare@3.2.2: {}
|
||||
|
||||
react-hook-form@7.52.0(react@18.2.0):
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
|
||||
react-inspector@6.0.2(react@18.2.0):
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
|
|
@ -18260,7 +18310,7 @@ snapshots:
|
|||
dependencies:
|
||||
'@types/three': 0.156.0
|
||||
skinview-utils: 0.7.1
|
||||
three: 0.154.0
|
||||
three: 0.154.0(patch_hash=sj7ocb4p23jym6bkfgueanti2e)
|
||||
|
||||
slash@3.0.0: {}
|
||||
|
||||
|
|
@ -18729,7 +18779,7 @@ snapshots:
|
|||
dependencies:
|
||||
any-promise: 1.3.0
|
||||
|
||||
three-stdlib@2.28.5(three@0.154.0):
|
||||
three-stdlib@2.28.5(three@0.154.0(patch_hash=sj7ocb4p23jym6bkfgueanti2e)):
|
||||
dependencies:
|
||||
'@types/draco3d': 1.4.7
|
||||
'@types/offscreencanvas': 2019.7.2
|
||||
|
|
@ -18737,11 +18787,11 @@ snapshots:
|
|||
draco3d: 1.5.6
|
||||
fflate: 0.6.10
|
||||
potpack: 1.0.2
|
||||
three: 0.154.0
|
||||
three: 0.154.0(patch_hash=sj7ocb4p23jym6bkfgueanti2e)
|
||||
|
||||
three.meshline@1.4.0: {}
|
||||
|
||||
three@0.154.0: {}
|
||||
three@0.154.0(patch_hash=sj7ocb4p23jym6bkfgueanti2e): {}
|
||||
|
||||
throttle-debounce@3.0.1: {}
|
||||
|
||||
|
|
@ -19291,6 +19341,16 @@ snapshots:
|
|||
|
||||
w3c-keyname@2.2.8: {}
|
||||
|
||||
wait-on@7.2.0(debug@4.3.4):
|
||||
dependencies:
|
||||
axios: 1.7.2(debug@4.3.4)
|
||||
joi: 17.13.1
|
||||
lodash: 4.17.21
|
||||
minimist: 1.2.8
|
||||
rxjs: 7.8.1
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
walker@1.0.8:
|
||||
dependencies:
|
||||
makeerror: 1.0.12
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import path from 'path'
|
|||
import { fileURLToPath } from 'url'
|
||||
import fs from 'fs'
|
||||
import { dynamicMcDataFiles } from './buildMesherConfig.mjs'
|
||||
import { mesherSharedPlugins } from '../scripts/esbuildPlugins.mjs'
|
||||
|
||||
const allowedBundleFiles = ['legacy', 'versions', 'protocolVersions', 'features']
|
||||
|
||||
|
|
@ -34,6 +35,7 @@ const buildOptions = {
|
|||
'process.env.BROWSER': '"true"',
|
||||
},
|
||||
plugins: [
|
||||
...mesherSharedPlugins,
|
||||
{
|
||||
name: 'external-json',
|
||||
setup(build) {
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
module.exports = {
|
||||
dispose3 (o) {
|
||||
o.geometry?.dispose()
|
||||
o.dispose?.()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
import * as THREE from 'three'
|
||||
import * as TWEEN from '@tweenjs/tween.js'
|
||||
import * as Entity from './entity/EntityMesh'
|
||||
import { dispose3 } from './dispose'
|
||||
import nbt from 'prismarine-nbt'
|
||||
import EventEmitter from 'events'
|
||||
import { PlayerObject, PlayerAnimation } from 'skinview3d'
|
||||
|
|
@ -14,6 +13,7 @@ import { NameTagObject } from 'skinview3d/libs/nametag'
|
|||
import { flat, fromFormattedString } from '@xmcl/text-component'
|
||||
import mojangson from 'mojangson'
|
||||
import externalTexturesJson from './entity/externalTextures.json'
|
||||
import { disposeObject } from './threeJsUtils'
|
||||
|
||||
export const TWEEN_DURATION = 50 // todo should be 100
|
||||
|
||||
|
|
@ -94,13 +94,14 @@ function getEntityMesh(entity, scene, options, overrides) {
|
|||
export class Entities extends EventEmitter {
|
||||
constructor(scene) {
|
||||
super()
|
||||
/** @type {THREE.Scene} */
|
||||
this.scene = scene
|
||||
this.entities = {}
|
||||
this.entitiesOptions = {}
|
||||
this.debugMode = 'none'
|
||||
this.onSkinUpdate = () => { }
|
||||
this.clock = new THREE.Clock()
|
||||
this.visible = true
|
||||
this.rendering = true
|
||||
this.itemsTexture = null
|
||||
this.getItemUv = undefined
|
||||
}
|
||||
|
|
@ -108,7 +109,7 @@ export class Entities extends EventEmitter {
|
|||
clear() {
|
||||
for (const mesh of Object.values(this.entities)) {
|
||||
this.scene.remove(mesh)
|
||||
dispose3(mesh)
|
||||
disposeObject(mesh)
|
||||
}
|
||||
this.entities = {}
|
||||
}
|
||||
|
|
@ -125,10 +126,14 @@ export class Entities extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
setVisible(visible, /** @type {THREE.Object3D?} */entity = null) {
|
||||
this.visible = visible
|
||||
for (const mesh of entity ? [entity] : Object.values(this.entities)) {
|
||||
mesh.visible = visible
|
||||
setRendering(rendering, /** @type {THREE.Object3D?} */entity = null) {
|
||||
this.rendering = rendering
|
||||
for (const ent of entity ? [entity] : Object.values(this.entities)) {
|
||||
if (rendering) {
|
||||
if (!this.scene.children.includes(ent)) this.scene.add(ent)
|
||||
} else {
|
||||
this.scene.remove(ent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -262,11 +267,15 @@ export class Entities extends EventEmitter {
|
|||
|
||||
}
|
||||
|
||||
displaySimpleText(jsonLike) {
|
||||
parseEntityLabel(jsonLike) {
|
||||
if (!jsonLike) return
|
||||
const parsed = typeof jsonLike === 'string' ? mojangson.simplify(mojangson.parse(jsonLike)) : nbt.simplify(jsonLike)
|
||||
const text = flat(parsed).map(x => x.text)
|
||||
return text.join('')
|
||||
try {
|
||||
const parsed = typeof jsonLike === 'string' ? mojangson.simplify(mojangson.parse(jsonLike)) : nbt.simplify(jsonLike)
|
||||
const text = flat(parsed).map(x => x.text)
|
||||
return text.join('')
|
||||
} catch (err) {
|
||||
return jsonLike
|
||||
}
|
||||
}
|
||||
|
||||
update(/** @type {import('prismarine-entity').Entity & {delete?, pos}} */entity, overrides) {
|
||||
|
|
@ -392,7 +401,7 @@ export class Entities extends EventEmitter {
|
|||
this.updatePlayerSkin(entity.id, '', overrides?.texture || stevePng)
|
||||
}
|
||||
this.setDebugMode(this.debugMode, group)
|
||||
this.setVisible(this.visible, group)
|
||||
this.setRendering(this.rendering, group)
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
|
|
@ -405,7 +414,7 @@ export class Entities extends EventEmitter {
|
|||
}
|
||||
}
|
||||
// not player
|
||||
const displayText = entity.metadata?.[3] && this.displaySimpleText(entity.metadata[2])
|
||||
const displayText = entity.metadata?.[3] && this.parseEntityLabel(entity.metadata[2])
|
||||
if (entity.name !== 'player' && displayText) {
|
||||
addNametag({ ...entity, username: displayText }, this.entitiesOptions, this.entities[entity.id].children.find(c => c.name === 'mesh'))
|
||||
}
|
||||
|
|
@ -456,7 +465,7 @@ export class Entities extends EventEmitter {
|
|||
if (e.additionalCleanup) e.additionalCleanup()
|
||||
this.emit('remove', entity)
|
||||
this.scene.remove(e)
|
||||
dispose3(e)
|
||||
disposeObject(e)
|
||||
// todo dispose textures as well ?
|
||||
delete this.entities[entity.id]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,29 @@ function sectionKey (x, y, z) {
|
|||
return `${x},${y},${z}`
|
||||
}
|
||||
|
||||
const batchMessagesLimit = 100
|
||||
|
||||
let queuedMessages = [] as any[]
|
||||
let queueWaiting = false
|
||||
const postMessage = (data, transferList = []) => {
|
||||
queuedMessages.push({ data, transferList })
|
||||
if (queuedMessages.length > batchMessagesLimit) {
|
||||
drainQueue(0, batchMessagesLimit)
|
||||
}
|
||||
if (queueWaiting) return
|
||||
queueWaiting = true
|
||||
setTimeout(() => {
|
||||
queueWaiting = false
|
||||
drainQueue(0, queuedMessages.length)
|
||||
})
|
||||
}
|
||||
|
||||
function drainQueue (from, to) {
|
||||
const messages = queuedMessages.slice(from, to)
|
||||
global.postMessage(messages.map(m => m.data), messages.flatMap(m => m.transferList) as unknown as string)
|
||||
queuedMessages = queuedMessages.slice(to)
|
||||
}
|
||||
|
||||
function setSectionDirty (pos, value = true) {
|
||||
const x = Math.floor(pos.x / 16) * 16
|
||||
const y = Math.floor(pos.y / 16) * 16
|
||||
|
|
@ -43,7 +66,7 @@ const softCleanup = () => {
|
|||
world = new World(world.config.version)
|
||||
}
|
||||
|
||||
self.onmessage = ({ data }) => {
|
||||
const handleMessage = data => {
|
||||
const globalVar: any = globalThis
|
||||
|
||||
if (data.type === 'mcData') {
|
||||
|
|
@ -53,6 +76,7 @@ self.onmessage = ({ data }) => {
|
|||
if (data.config) {
|
||||
world ??= new World(data.config.version)
|
||||
world.config = { ...world.config, ...data.config }
|
||||
globalThis.world = world
|
||||
}
|
||||
|
||||
if (data.type === 'mesherData') {
|
||||
|
|
@ -80,6 +104,15 @@ self.onmessage = ({ data }) => {
|
|||
}
|
||||
}
|
||||
|
||||
self.onmessage = ({ data }) => {
|
||||
if (Array.isArray(data)) {
|
||||
data.forEach(handleMessage)
|
||||
return
|
||||
}
|
||||
|
||||
handleMessage(data)
|
||||
}
|
||||
|
||||
setInterval(() => {
|
||||
if (world === null || !blockStatesReady) return
|
||||
|
||||
|
|
@ -96,7 +129,7 @@ setInterval(() => {
|
|||
//@ts-ignore
|
||||
postMessage({ type: 'geometry', key, geometry }, transferable)
|
||||
} else {
|
||||
console.info('[mesher] Missing section', x, y, z)
|
||||
// console.info('[mesher] Missing section', x, y, z)
|
||||
}
|
||||
const dirtyTimes = dirtySections.get(key)
|
||||
if (!dirtyTimes) throw new Error('dirtySections.get(key) is falsy')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { Vec3 } from 'vec3'
|
||||
import type { BlockStatesOutput } from '../../prepare/modelsBuilder'
|
||||
import { World } from './world'
|
||||
import { Block } from 'prismarine-block'
|
||||
import { WorldBlock as Block } from './world'
|
||||
import legacyJson from '../../../../src/preflatMap.json'
|
||||
import { versionToNumber } from '../../prepare/utils'
|
||||
import { BlockType } from '../../../examples/shared'
|
||||
import { MesherGeometryOutput } from './shared'
|
||||
|
||||
|
|
@ -48,6 +50,53 @@ function prepareTints (tints) {
|
|||
})
|
||||
}
|
||||
|
||||
const calculatedBlocksEntries = Object.entries(legacyJson.clientCalculatedBlocks)
|
||||
export function preflatBlockCalculation (block: Block, world: World, position: Vec3) {
|
||||
const type = calculatedBlocksEntries.find(([name, blocks]) => blocks.includes(block.name))?.[0]
|
||||
if (!type) return
|
||||
switch (type) {
|
||||
case 'directional': {
|
||||
const isSolidConnection = !block.name.includes('redstone') && !block.name.includes('tripwire')
|
||||
const neighbors = [
|
||||
world.getBlock(position.offset(0, 0, 1)),
|
||||
world.getBlock(position.offset(0, 0, -1)),
|
||||
world.getBlock(position.offset(1, 0, 0)),
|
||||
world.getBlock(position.offset(-1, 0, 0))
|
||||
]
|
||||
// set needed props to true: east:'false',north:'false',south:'false',west:'false'
|
||||
const props = {}
|
||||
for (const [i, neighbor] of neighbors.entries()) {
|
||||
const isConnectedToSolid = isSolidConnection ? (neighbor && !neighbor.transparent) : false
|
||||
if (isConnectedToSolid || neighbor?.name === block.name) {
|
||||
props[['south', 'north', 'east', 'west'][i]] = 'true'
|
||||
}
|
||||
}
|
||||
return props
|
||||
}
|
||||
// case 'gate_in_wall': {}
|
||||
case 'block_snowy': {
|
||||
const aboveIsSnow = world.getBlock(position.offset(0, 1, 0))?.name === 'snow'
|
||||
return {
|
||||
snowy: `${aboveIsSnow}`
|
||||
}
|
||||
}
|
||||
case 'door': {
|
||||
// upper half matches lower in
|
||||
const half = block.getProperties().half
|
||||
if (half === 'upper') {
|
||||
// copy other properties
|
||||
const lower = world.getBlock(position.offset(0, -1, 0))
|
||||
if (lower?.name === block.name) {
|
||||
return {
|
||||
...lower.getProperties(),
|
||||
half: 'upper'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function tintToGl (tint) {
|
||||
const r = (tint >> 16) & 0xff
|
||||
const g = (tint >> 8) & 0xff
|
||||
|
|
@ -267,9 +316,9 @@ function renderLiquid (world, cursor, texture, type, biome, water, attr) {
|
|||
for (const pos of corners) {
|
||||
const height = cornerHeights[pos[2] * 2 + pos[0]]
|
||||
attr.t_positions.push(
|
||||
(pos[0] ? 1 : 0) + (cursor.x & 15) - 8,
|
||||
(pos[1] ? height : 0) + (cursor.y & 15) - 8,
|
||||
(pos[2] ? 1 : 0) + (cursor.z & 15) - 8)
|
||||
(pos[0] ? 0.999 : 0.001) + (cursor.x & 15) - 8,
|
||||
(pos[1] ? height - 0.001 : 0.001) + (cursor.y & 15) - 8,
|
||||
(pos[2] ? 0.999 : 0.001) + (cursor.z & 15) - 8)
|
||||
attr.t_normals.push(...dir)
|
||||
attr.t_uvs.push(pos[3] * su + u, pos[4] * sv * (pos[1] ? 1 : height) + v)
|
||||
attr.t_colors.push(tint[0], tint[1], tint[2])
|
||||
|
|
@ -426,7 +475,7 @@ function renderElement (world: World, cursor: Vec3, element, doAO: boolean, attr
|
|||
|
||||
const aos: number[] = []
|
||||
const neighborPos = position.plus(new Vec3(...dir))
|
||||
const baseLight = world.getLight(neighborPos) / 15
|
||||
const baseLight = world.getLight(neighborPos, undefined, undefined, block.name) / 15
|
||||
for (const pos of corners) {
|
||||
let vertex = [
|
||||
(pos[0] ? maxx : minx),
|
||||
|
|
@ -543,7 +592,7 @@ export function getSectionGeometry (sx, sy, sz, world: World) {
|
|||
for (cursor.z = sz; cursor.z < sz + 16; cursor.z++) {
|
||||
for (cursor.x = sx; cursor.x < sx + 16; cursor.x++) {
|
||||
const block = world.getBlock(cursor)!
|
||||
if (block.name.includes('_sign')) {
|
||||
if (block.name.includes('_sign') || block.name === 'sign') {
|
||||
const key = `${cursor.x},${cursor.y},${cursor.z}`
|
||||
const props: any = block.getProperties()
|
||||
const facingRotationMap = {
|
||||
|
|
@ -552,14 +601,33 @@ export function getSectionGeometry (sx, sy, sz, world: World) {
|
|||
"west": 1,
|
||||
"east": 3
|
||||
}
|
||||
const isWall = block.name.endsWith('wall_sign') || block.name.endsWith('hanging_sign')
|
||||
const isWall = block.name.endsWith('wall_sign') || block.name.endsWith('wall_hanging_sign')
|
||||
const isHanging = block.name.endsWith('hanging_sign')
|
||||
attr.signs[key] = {
|
||||
isWall,
|
||||
isHanging,
|
||||
rotation: isWall ? facingRotationMap[props.facing] : +props.rotation
|
||||
}
|
||||
}
|
||||
const biome = block.biome.name
|
||||
if (block.variant === undefined) {
|
||||
|
||||
let preflatRecomputeVariant = !!(block as any)._originalProperties
|
||||
if (world.preflat) {
|
||||
const patchProperties = preflatBlockCalculation(block, world, cursor)
|
||||
if (patchProperties) {
|
||||
//@ts-ignore
|
||||
block._originalProperties ??= block._properties
|
||||
//@ts-ignore
|
||||
block._properties = { ...block._originalProperties, ...patchProperties }
|
||||
preflatRecomputeVariant = true
|
||||
} else {
|
||||
//@ts-ignore
|
||||
block._properties = block._originalProperties ?? block._properties
|
||||
//@ts-ignore
|
||||
block._originalProperties = undefined
|
||||
}
|
||||
}
|
||||
if (block.variant === undefined || preflatRecomputeVariant) {
|
||||
block.variant = getModelVariants(block)
|
||||
}
|
||||
|
||||
|
|
@ -637,7 +705,7 @@ export function getSectionGeometry (sx, sy, sz, world: World) {
|
|||
delete attr.t_uvs
|
||||
|
||||
attr.positions = new Float32Array(attr.positions) as any
|
||||
attr.normals = new Float32Array(attr.normals) as any
|
||||
attr.normals = new Int8Array(attr.normals) as any
|
||||
attr.colors = new Float32Array(attr.colors) as any
|
||||
attr.uvs = new Float32Array(attr.uvs) as any
|
||||
|
||||
|
|
@ -680,7 +748,7 @@ function matchProperties (block: Block, /* to match against */properties: Record
|
|||
return true
|
||||
}
|
||||
|
||||
function getModelVariants (block: import('prismarine-block').Block) {
|
||||
function getModelVariants (block: Block) {
|
||||
// air, cave_air, void_air and so on...
|
||||
// full list of invisible & special blocks https://minecraft.wiki/w/Model#Blocks_and_fluids
|
||||
if (block.name === '' || block.name === 'air' || block.name.endsWith('_air')) return []
|
||||
|
|
|
|||
|
|
@ -1,96 +1,140 @@
|
|||
import { test, expect } from 'vitest'
|
||||
import { setup } from './mesherTester'
|
||||
import minecraftData from 'minecraft-data'
|
||||
import minecraftAssets from 'minecraft-assets'
|
||||
|
||||
const version = '1.18.1'
|
||||
const version = minecraftAssets.versions.at(-1)
|
||||
|
||||
const addPositions = [
|
||||
// [[0, 0, 0], 'diamond_block'],
|
||||
[[1, 0, 0], 'stone'],
|
||||
[[-1, 0, 0], 'stone'],
|
||||
[[0, 1, 0], 'stone'],
|
||||
[[0, -1, 0], 'stone'],
|
||||
[[0, 0, 1], 'stone'],
|
||||
[[0, 0, -1], 'stone'],
|
||||
// [[0, 0, 0], 'diamond_block'],
|
||||
// [[1, 0, 0], 'stone'],
|
||||
// [[-1, 0, 0], 'stone'],
|
||||
// [[0, 1, 0], 'stone'],
|
||||
// [[0, -1, 0], 'stone'],
|
||||
// [[0, 0, 1], 'stone'],
|
||||
// [[0, 0, -1], 'stone'],
|
||||
] as const
|
||||
|
||||
test('Known blocks are not rendered', () => {
|
||||
const { mesherWorld, getGeometry, pos, mcData } = setup(version, addPositions as any)
|
||||
const { mesherWorld, getGeometry, pos, mcData } = setup(version, addPositions as any)
|
||||
const ignoreAsExpected = ['air', 'cave_air', 'void_air', 'barrier', 'water', 'lava', 'moving_piston', 'light']
|
||||
|
||||
let time = 0
|
||||
let times = 0
|
||||
const invalidBlocks = {}/* as {[number, number]} */
|
||||
for (const block of mcData.blocksArray) {
|
||||
if (block.maxStateId! - block.minStateId! > 100) continue
|
||||
for (let i = block.minStateId!; i <= block.maxStateId!; i++) {
|
||||
if (block.transparent) continue
|
||||
mesherWorld.setBlockStateId(pos, i)
|
||||
const start = performance.now()
|
||||
const { centerFaces, totalTiles, centerTileNeighbors } = getGeometry()
|
||||
time += performance.now() - start
|
||||
times++
|
||||
if (centerFaces === 0 && centerTileNeighbors !== 0) {
|
||||
if (invalidBlocks[block.name]) continue
|
||||
invalidBlocks[block.name] = [i - block.minStateId!, centerTileNeighbors]
|
||||
// console.log('INVALID', block.name, centerTileNeighbors, i - block.minStateId)
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log('Average time', time / times)
|
||||
// Fully expected
|
||||
expect(invalidBlocks).toMatchInlineSnapshot(`
|
||||
{
|
||||
"creeper_head": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"creeper_wall_head": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"dragon_head": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"dragon_wall_head": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"player_head": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"player_wall_head": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"powder_snow": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"skeleton_skull": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"skeleton_wall_skull": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"wither_skeleton_skull": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"wither_skeleton_wall_skull": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"zombie_head": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
"zombie_wall_head": [
|
||||
0,
|
||||
6,
|
||||
],
|
||||
let time = 0
|
||||
let times = 0
|
||||
const invalidBlocks = {}/* as {[number, number]} */
|
||||
for (const block of mcData.blocksArray) {
|
||||
if (ignoreAsExpected.includes(block.name)) continue
|
||||
// if (block.maxStateId! - block.minStateId! > 100) continue
|
||||
// for (let i = block.minStateId!; i <= block.maxStateId!; i++) {
|
||||
for (let i = block.defaultState!; i <= block.defaultState!; i++) {
|
||||
// if (block.transparent) continue
|
||||
mesherWorld.setBlockStateId(pos, i)
|
||||
const start = performance.now()
|
||||
const { centerFaces, totalTiles, centerTileNeighbors } = getGeometry()
|
||||
time += performance.now() - start
|
||||
times++
|
||||
if (centerFaces === 0) {
|
||||
if (invalidBlocks[block.name]) continue
|
||||
invalidBlocks[block.name] = true
|
||||
// invalidBlocks[block.name] = [i - block.defaultState!, centerTileNeighbors]
|
||||
// console.log('INVALID', block.name, centerTileNeighbors, i - block.minStateId)
|
||||
}
|
||||
`)
|
||||
}
|
||||
}
|
||||
console.log('Average time', time / times)
|
||||
// should be fixed, but to avoid regressions & for visibility
|
||||
expect(invalidBlocks).toMatchInlineSnapshot(`
|
||||
{
|
||||
"black_banner": true,
|
||||
"black_bed": true,
|
||||
"black_candle": true,
|
||||
"black_wall_banner": true,
|
||||
"blue_banner": true,
|
||||
"blue_bed": true,
|
||||
"blue_candle": true,
|
||||
"blue_wall_banner": true,
|
||||
"brown_banner": true,
|
||||
"brown_bed": true,
|
||||
"brown_candle": true,
|
||||
"brown_wall_banner": true,
|
||||
"bubble_column": true,
|
||||
"candle": true,
|
||||
"creeper_head": true,
|
||||
"creeper_wall_head": true,
|
||||
"cyan_banner": true,
|
||||
"cyan_bed": true,
|
||||
"cyan_candle": true,
|
||||
"cyan_wall_banner": true,
|
||||
"dragon_head": true,
|
||||
"dragon_wall_head": true,
|
||||
"end_gateway": true,
|
||||
"end_portal": true,
|
||||
"gray_banner": true,
|
||||
"gray_bed": true,
|
||||
"gray_candle": true,
|
||||
"gray_wall_banner": true,
|
||||
"green_banner": true,
|
||||
"green_bed": true,
|
||||
"green_candle": true,
|
||||
"green_wall_banner": true,
|
||||
"light_blue_banner": true,
|
||||
"light_blue_bed": true,
|
||||
"light_blue_candle": true,
|
||||
"light_blue_wall_banner": true,
|
||||
"light_gray_banner": true,
|
||||
"light_gray_bed": true,
|
||||
"light_gray_candle": true,
|
||||
"light_gray_wall_banner": true,
|
||||
"lime_banner": true,
|
||||
"lime_bed": true,
|
||||
"lime_candle": true,
|
||||
"lime_wall_banner": true,
|
||||
"magenta_banner": true,
|
||||
"magenta_bed": true,
|
||||
"magenta_candle": true,
|
||||
"magenta_wall_banner": true,
|
||||
"orange_banner": true,
|
||||
"orange_bed": true,
|
||||
"orange_candle": true,
|
||||
"orange_wall_banner": true,
|
||||
"piglin_head": true,
|
||||
"piglin_wall_head": true,
|
||||
"pink_banner": true,
|
||||
"pink_bed": true,
|
||||
"pink_candle": true,
|
||||
"pink_petals": true,
|
||||
"pink_wall_banner": true,
|
||||
"player_head": true,
|
||||
"player_wall_head": true,
|
||||
"powder_snow_cauldron": true,
|
||||
"purple_banner": true,
|
||||
"purple_bed": true,
|
||||
"purple_candle": true,
|
||||
"purple_wall_banner": true,
|
||||
"red_banner": true,
|
||||
"red_bed": true,
|
||||
"red_candle": true,
|
||||
"red_wall_banner": true,
|
||||
"repeater": true,
|
||||
"sea_pickle": true,
|
||||
"skeleton_skull": true,
|
||||
"skeleton_wall_skull": true,
|
||||
"snow": true,
|
||||
"structure_void": true,
|
||||
"turtle_egg": true,
|
||||
"water_cauldron": true,
|
||||
"white_banner": true,
|
||||
"white_bed": true,
|
||||
"white_candle": true,
|
||||
"white_wall_banner": true,
|
||||
"wither_skeleton_skull": true,
|
||||
"wither_skeleton_wall_skull": true,
|
||||
"yellow_banner": true,
|
||||
"yellow_bed": true,
|
||||
"yellow_candle": true,
|
||||
"yellow_wall_banner": true,
|
||||
"zombie_head": true,
|
||||
"zombie_wall_head": true,
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { Block } from "prismarine-block"
|
|||
import { Vec3 } from 'vec3'
|
||||
import moreBlockDataGeneratedJson from '../moreBlockDataGenerated.json'
|
||||
import { defaultMesherConfig } from './shared'
|
||||
import legacyJson from '../../../../src/preflatMap.json'
|
||||
|
||||
const ignoreAoBlocks = Object.keys(moreBlockDataGeneratedJson.noOcclusions)
|
||||
|
||||
|
|
@ -17,7 +18,7 @@ function isCube (shapes) {
|
|||
return shape[0] === 0 && shape[1] === 0 && shape[2] === 0 && shape[3] === 1 && shape[4] === 1 && shape[5] === 1
|
||||
}
|
||||
|
||||
export type WorldBlock = Block & {
|
||||
export type WorldBlock = Omit<Block, 'position'> & {
|
||||
variant?: any
|
||||
// todo
|
||||
isCube: boolean
|
||||
|
|
@ -30,14 +31,16 @@ export class World {
|
|||
columns = {} as { [key: string]: import('prismarine-chunk/types/index').PCChunk }
|
||||
blockCache = {}
|
||||
biomeCache: { [id: number]: mcData.Biome }
|
||||
preflat: boolean
|
||||
|
||||
constructor(version) {
|
||||
constructor (version) {
|
||||
this.Chunk = Chunks(version) as any
|
||||
this.biomeCache = mcData(version).biomes
|
||||
this.preflat = !mcData(version).supportFeature('blockStateId')
|
||||
this.config.version = version
|
||||
}
|
||||
|
||||
getLight (pos: Vec3, isNeighbor = false) {
|
||||
getLight (pos: Vec3, isNeighbor = false, skipMoreChecks = false, curBlockName = '') {
|
||||
const { enableLighting, skyLight } = this.config
|
||||
if (!enableLighting) return 15
|
||||
// const key = `${pos.x},${pos.y},${pos.z}`
|
||||
|
|
@ -52,8 +55,17 @@ export class World {
|
|||
) + 2
|
||||
)
|
||||
// lightsCache.set(key, result)
|
||||
if (result === 2 && this.getBlock(pos)?.name.match(/_stairs|slab/)) { // todo this is obviously wrong
|
||||
result = this.getLight(pos.offset(0, 1, 0))
|
||||
if (result === 2 && [this.getBlock(pos)?.name ?? '', curBlockName].some(x => x.match(/_stairs|slab|glass_pane/)) && !skipMoreChecks) { // todo this is obviously wrong
|
||||
const lights = [
|
||||
this.getLight(pos.offset(0, 1, 0), undefined, true),
|
||||
this.getLight(pos.offset(0, -1, 0), undefined, true),
|
||||
this.getLight(pos.offset(0, 0, 1), undefined, true),
|
||||
this.getLight(pos.offset(0, 0, -1), undefined, true),
|
||||
this.getLight(pos.offset(1, 0, 0), undefined, true),
|
||||
this.getLight(pos.offset(-1, 0, 0), undefined, true)
|
||||
].filter(x => x !== 2)
|
||||
const min = Math.min(...lights)
|
||||
result = min
|
||||
}
|
||||
if (isNeighbor && result === 2) result = 15 // TODO
|
||||
return result
|
||||
|
|
@ -91,6 +103,8 @@ export class World {
|
|||
}
|
||||
|
||||
getBlock (pos: Vec3): WorldBlock | null {
|
||||
// for easier testing
|
||||
if (!(pos instanceof Vec3)) pos = new Vec3(...pos as [number, number, number])
|
||||
const key = columnKey(Math.floor(pos.x / 16) * 16, Math.floor(pos.z / 16) * 16)
|
||||
|
||||
const column = this.columns[key]
|
||||
|
|
@ -111,6 +125,25 @@ export class World {
|
|||
throw new Error('position is not reliable, use pos parameter instead of block.position')
|
||||
}
|
||||
})
|
||||
if (this.preflat) {
|
||||
//@ts-ignore
|
||||
b._properties = {}
|
||||
|
||||
const namePropsStr = legacyJson.blocks[b.type + ':' + b.metadata] || findClosestLegacyBlockFallback(b.type, b.metadata, pos)
|
||||
if (namePropsStr) {
|
||||
b.name = namePropsStr.split('[')[0]
|
||||
const propsStr = namePropsStr.split('[')?.[1]?.split(']')
|
||||
if (propsStr) {
|
||||
const newProperties = Object.fromEntries(propsStr.join('').split(',').map(x => {
|
||||
let [key, val] = x.split('=') as any
|
||||
if (!isNaN(val)) val = parseInt(val)
|
||||
return [key, val]
|
||||
}))
|
||||
//@ts-ignore
|
||||
b._properties = newProperties
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const block = this.blockCache[stateId]
|
||||
|
|
@ -127,6 +160,15 @@ export class World {
|
|||
}
|
||||
}
|
||||
|
||||
const findClosestLegacyBlockFallback = (id, metadata, pos) => {
|
||||
console.warn(`[mesher] Unknown block with ${id}:${metadata} at ${pos}, falling back`) // todo has known issues
|
||||
for (const [key, value] of Object.entries(legacyJson.blocks)) {
|
||||
const [idKey, meta] = key.split(':')
|
||||
if (idKey === id) return value
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// todo export in chunk instead
|
||||
const hasChunkSection = (column, pos) => {
|
||||
if (column._getSection) return column._getSection(pos)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
const THREE = require('three')
|
||||
const { MeshLine, MeshLineMaterial } = require('three.meshline')
|
||||
const { dispose3 } = require('./dispose')
|
||||
|
||||
function getMesh (primitive, camera) {
|
||||
if (primitive.type === 'line') {
|
||||
|
|
@ -48,7 +47,7 @@ function getMesh (primitive, camera) {
|
|||
}
|
||||
|
||||
class Primitives {
|
||||
constructor (scene, camera) {
|
||||
constructor(scene, camera) {
|
||||
this.scene = scene
|
||||
this.camera = camera
|
||||
this.primitives = {}
|
||||
|
|
@ -57,7 +56,7 @@ class Primitives {
|
|||
clear () {
|
||||
for (const mesh of Object.values(this.primitives)) {
|
||||
this.scene.remove(mesh)
|
||||
dispose3(mesh)
|
||||
disposeObject(mesh)
|
||||
}
|
||||
this.primitives = {}
|
||||
}
|
||||
|
|
@ -65,7 +64,7 @@ class Primitives {
|
|||
update (primitive) {
|
||||
if (this.primitives[primitive.id]) {
|
||||
this.scene.remove(this.primitives[primitive.id])
|
||||
dispose3(this.primitives[primitive.id])
|
||||
disposeObject(this.primitives[primitive.id])
|
||||
delete this.primitives[primitive.id]
|
||||
}
|
||||
|
||||
|
|
|
|||
12
prismarine-viewer/viewer/lib/threeJsUtils.ts
Normal file
12
prismarine-viewer/viewer/lib/threeJsUtils.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import * as THREE from 'three'
|
||||
|
||||
export const disposeObject = (obj: THREE.Object3D) => {
|
||||
// not cleaning texture there as it might be used by other objects, but would be good to also do that
|
||||
if (obj instanceof THREE.Mesh) {
|
||||
obj.geometry?.dispose?.()
|
||||
obj.material?.dispose?.()
|
||||
}
|
||||
if (obj.children) {
|
||||
obj.children.forEach(disposeObject)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import { generateSpiralMatrix } from 'flying-squid/dist/utils'
|
|||
import { defaultWorldRendererConfig } from './worldrendererCommon'
|
||||
import { sendCameraToWorker } from '../../examples/webgpuRendererMain'
|
||||
import { WorldRendererThree } from './worldrendererThree'
|
||||
import { versionToNumber } from '../prepare/utils'
|
||||
|
||||
export class Viewer {
|
||||
scene: THREE.Scene
|
||||
|
|
@ -80,7 +81,8 @@ export class Viewer {
|
|||
}
|
||||
|
||||
setVersion (userVersion: string) {
|
||||
const texturesVersion = getVersion(userVersion)
|
||||
let texturesVersion = getVersion(userVersion)
|
||||
if (versionToNumber(userVersion) < versionToNumber('1.13')) texturesVersion = '1.13.2' // we normalize to post-flatenning in mesher
|
||||
console.log('[viewer] Using version:', userVersion, 'textures:', texturesVersion)
|
||||
this.world.setVersion(userVersion, texturesVersion)
|
||||
this.entities.clear()
|
||||
|
|
@ -203,6 +205,8 @@ export class Viewer {
|
|||
})
|
||||
|
||||
emitter.on('time', (timeOfDay) => {
|
||||
this.world.timeUpdated?.(timeOfDay)
|
||||
|
||||
let skyLight = 15
|
||||
if (timeOfDay < 0 || timeOfDay > 24000) {
|
||||
throw new Error("Invalid time of day. It should be between 0 and 24000.")
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@ export class ViewerWrapper {
|
|||
previousWindowWidth: number
|
||||
previousWindowHeight: number
|
||||
globalObject = globalThis as any
|
||||
stopRenderOnBlur = true
|
||||
stopRenderOnBlur = false
|
||||
addedToPage = false
|
||||
renderInterval = 0
|
||||
renderIntervalUnfocused: number | undefined
|
||||
fpsInterval
|
||||
|
||||
constructor(public canvas: HTMLCanvasElement, public renderer?: THREE.WebGLRenderer) {
|
||||
constructor (public canvas: HTMLCanvasElement, public renderer?: THREE.WebGLRenderer) {
|
||||
if (this.renderer) this.globalObject.renderer = this.renderer
|
||||
}
|
||||
addToPage (startRendering = true) {
|
||||
if (this.addedToPage) throw new Error('Already added to page')
|
||||
|
|
@ -29,7 +31,6 @@ export class ViewerWrapper {
|
|||
this.canvas.id = 'viewer-canvas'
|
||||
document.body.appendChild(this.canvas)
|
||||
|
||||
if (this.renderer) this.globalObject.renderer = this.renderer
|
||||
this.addedToPage = true
|
||||
|
||||
let max = 0
|
||||
|
|
@ -44,7 +45,7 @@ export class ViewerWrapper {
|
|||
this.globalObject.requestAnimationFrame(this.render.bind(this))
|
||||
}
|
||||
if (typeof window !== 'undefined') {
|
||||
// this.trackWindowFocus()
|
||||
this.trackWindowFocus()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,11 +78,12 @@ export class ViewerWrapper {
|
|||
for (const fn of beforeRenderFrame) fn()
|
||||
this.globalObject.requestAnimationFrame(this.render.bind(this))
|
||||
if (this.globalObject.stopRender || this.renderer?.xr.isPresenting || (this.stopRenderOnBlur && !this.windowFocused)) return
|
||||
if (this.renderInterval) {
|
||||
const renderInterval = (this.windowFocused ? this.renderInterval : this.renderIntervalUnfocused) ?? this.renderInterval
|
||||
if (renderInterval) {
|
||||
this.delta += time - this.lastTime
|
||||
this.lastTime = time
|
||||
if (this.delta > this.renderInterval) {
|
||||
this.delta %= this.renderInterval
|
||||
if (this.delta > renderInterval) {
|
||||
this.delta %= renderInterval
|
||||
// continue rendering
|
||||
} else {
|
||||
return
|
||||
|
|
|
|||
58
prismarine-viewer/viewer/lib/workerProxy.ts
Normal file
58
prismarine-viewer/viewer/lib/workerProxy.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
export function createWorkerProxy<T extends Record<string, (...args: any[]) => void>> (handlers: T): { __workerProxy: T } {
|
||||
addEventListener('message', (event) => {
|
||||
const { type, args } = event.data
|
||||
if (handlers[type]) {
|
||||
handlers[type](...args)
|
||||
}
|
||||
})
|
||||
return null as any
|
||||
}
|
||||
|
||||
/**
|
||||
* in main thread
|
||||
* ```ts
|
||||
* // either:
|
||||
* import type { importedTypeWorkerProxy } from './worker'
|
||||
* // or:
|
||||
* type importedTypeWorkerProxy = import('./worker').importedTypeWorkerProxy
|
||||
*
|
||||
* const workerChannel = useWorkerProxy<typeof importedTypeWorkerProxy>(worker)
|
||||
* ```
|
||||
*/
|
||||
export const useWorkerProxy = <T extends { __workerProxy: Record<string, (...args: any[]) => void> }> (worker: Worker, autoTransfer = true): T['__workerProxy'] & {
|
||||
transfer: (...args: Transferable[]) => T['__workerProxy']
|
||||
} => {
|
||||
// in main thread
|
||||
return new Proxy({} as any, {
|
||||
get: (target, prop) => {
|
||||
if (prop === 'transfer') return (...transferable: Transferable[]) => {
|
||||
return new Proxy({}, {
|
||||
get: (target, prop) => {
|
||||
return (...args: any[]) => {
|
||||
worker.postMessage({
|
||||
type: prop,
|
||||
args,
|
||||
}, transferable)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return (...args: any[]) => {
|
||||
const transfer = autoTransfer ? args.filter(arg => arg instanceof ArrayBuffer || arg instanceof MessagePort || arg instanceof ImageBitmap || arg instanceof OffscreenCanvas) : []
|
||||
worker.postMessage({
|
||||
type: prop,
|
||||
args,
|
||||
}, transfer)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// const workerProxy = createWorkerProxy({
|
||||
// startRender (canvas: HTMLCanvasElement) {
|
||||
// },
|
||||
// })
|
||||
|
||||
// const worker = useWorkerProxy(null, workerProxy)
|
||||
|
||||
// worker.
|
||||
|
|
@ -19,7 +19,7 @@ export class WorldDataEmitter extends EventEmitter {
|
|||
private eventListeners: Record<string, any> = {};
|
||||
private emitter: WorldDataEmitter
|
||||
|
||||
constructor(public world: import('prismarine-world').world.World | typeof __type_bot['world'], public viewDistance: number, position: Vec3 = new Vec3(0, 0, 0)) {
|
||||
constructor (public world: typeof __type_bot['world'], public viewDistance: number, position: Vec3 = new Vec3(0, 0, 0)) {
|
||||
super()
|
||||
this.loadedChunks = {}
|
||||
this.lastPos = new Vec3(0, 0, 0).update(position)
|
||||
|
|
@ -83,10 +83,11 @@ export class WorldDataEmitter extends EventEmitter {
|
|||
get (_target, posKey, receiver) {
|
||||
if (typeof posKey !== 'string') return
|
||||
const [x, y, z] = posKey.split(',').map(Number)
|
||||
return bot.world.getBlock(new Vec3(x, y, z)).entity
|
||||
return bot.world.getBlock(new Vec3(x, y, z))?.entity
|
||||
},
|
||||
}))
|
||||
this.emitter.emit('renderDistance', this.viewDistance)
|
||||
this.emitter.emit('time', bot.time.timeOfDay)
|
||||
})
|
||||
// node.js stream data event pattern
|
||||
if (this.emitter.listenerCount('blockEntities')) {
|
||||
|
|
@ -122,9 +123,23 @@ export class WorldDataEmitter extends EventEmitter {
|
|||
}
|
||||
|
||||
async _loadChunks (positions: Vec3[], sliceSize = 5, waitTime = 0) {
|
||||
for (let i = 0; i < positions.length; i += sliceSize) {
|
||||
await new Promise((resolve) => setTimeout(resolve, waitTime))
|
||||
await Promise.all(positions.slice(i, i + sliceSize).map((p) => this.loadChunk(p)))
|
||||
let i = 0
|
||||
const interval = setInterval(() => {
|
||||
if (i >= positions.length) {
|
||||
clearInterval(interval)
|
||||
return
|
||||
}
|
||||
this.loadChunk(positions[i])
|
||||
i++
|
||||
}, 1)
|
||||
}
|
||||
|
||||
readdDebug () {
|
||||
const clonedLoadedChunks = { ...this.loadedChunks }
|
||||
this.unloadAllChunks()
|
||||
for (const loadedChunk in clonedLoadedChunks) {
|
||||
const [x, z] = loadedChunk.split(',').map(Number)
|
||||
this.loadChunk(new Vec3(x, 0, z))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,7 +201,7 @@ export class WorldDataEmitter extends EventEmitter {
|
|||
const positions = generateSpiralMatrix(this.viewDistance).map(([x, z]) => {
|
||||
const pos = new Vec3((botX + x) * 16, 0, (botZ + z) * 16)
|
||||
if (!this.loadedChunks[`${pos.x},${pos.z}`]) return pos
|
||||
return undefined
|
||||
return undefined!
|
||||
}).filter(a => !!a)
|
||||
this.lastPos.update(pos)
|
||||
await this._loadChunks(positions)
|
||||
|
|
|
|||
|
|
@ -73,10 +73,10 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
const src = typeof window === 'undefined' ? `${__dirname}/${workerName}` : workerName
|
||||
|
||||
const worker: any = new Worker(src)
|
||||
worker.onmessage = async ({ data }) => {
|
||||
const handleMessage = (data) => {
|
||||
if (!this.active) return
|
||||
this.handleWorkerMessage(data)
|
||||
await new Promise(resolve => {
|
||||
new Promise(resolve => {
|
||||
setTimeout(resolve, 0)
|
||||
})
|
||||
if (data.type === 'sectionFinished') {
|
||||
|
|
@ -105,6 +105,13 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
this.renderUpdateEmitter.emit('update')
|
||||
}
|
||||
}
|
||||
worker.onmessage = ({ data }) => {
|
||||
if (Array.isArray(data)) {
|
||||
data.forEach(handleMessage)
|
||||
return
|
||||
}
|
||||
handleMessage(data)
|
||||
}
|
||||
if (worker.on) worker.on('message', (data) => { worker.onmessage({ data }) })
|
||||
this.workers.push(worker)
|
||||
}
|
||||
|
|
@ -123,6 +130,8 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
|
||||
allChunksLoaded?(): void
|
||||
|
||||
timeUpdated?(newTime: number): void
|
||||
|
||||
updateViewerPosition (pos: Vec3) {
|
||||
this.viewerPosition = pos
|
||||
for (const [key, value] of Object.entries(this.loadedChunks)) {
|
||||
|
|
@ -213,6 +222,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
}
|
||||
|
||||
addColumn (x: number, z: number, chunk: any, isLightUpdate: boolean) {
|
||||
if (!this.active) return
|
||||
if (this.workers.length === 0) throw new Error('workers not initialized yet')
|
||||
this.initialChunksLoad = false
|
||||
this.loadedChunks[`${x},${z}`] = true
|
||||
|
|
@ -254,6 +264,9 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
if ((pos.z & 15) === 15) this.setSectionDirty(pos.offset(0, 0, 16))
|
||||
}
|
||||
|
||||
queueAwaited = false
|
||||
messagesQueue = {} as { [workerIndex: string]: any[] }
|
||||
|
||||
setSectionDirty (pos: Vec3, value = true) {
|
||||
if (this.viewDistance === -1) throw new Error('viewDistance not set')
|
||||
this.allChunksFinished = false
|
||||
|
|
@ -267,7 +280,9 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
// is always dispatched to the same worker
|
||||
const hash = mod(Math.floor(pos.x / 16) + Math.floor(pos.y / 16) + Math.floor(pos.z / 16), this.workers.length)
|
||||
this.sectionsOutstanding.set(key, (this.sectionsOutstanding.get(key) ?? 0) + 1)
|
||||
this.workers[hash].postMessage({
|
||||
this.messagesQueue[hash] ??= []
|
||||
this.messagesQueue[hash].push({
|
||||
// this.workers[hash].postMessage({
|
||||
type: 'dirty',
|
||||
x: pos.x,
|
||||
y: pos.y,
|
||||
|
|
@ -275,6 +290,21 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
|
|||
value,
|
||||
config: this.mesherConfig,
|
||||
})
|
||||
this.dispatchMessages()
|
||||
}
|
||||
|
||||
dispatchMessages () {
|
||||
if (this.queueAwaited) return
|
||||
this.queueAwaited = true
|
||||
setTimeout(() => {
|
||||
// group messages and send as one
|
||||
for (const workerIndex in this.messagesQueue) {
|
||||
const worker = this.workers[Number(workerIndex)]
|
||||
worker.postMessage(this.messagesQueue[workerIndex])
|
||||
}
|
||||
this.messagesQueue = {}
|
||||
this.queueAwaited = false
|
||||
})
|
||||
}
|
||||
|
||||
// Listen for chunk rendering updates emitted if a worker finished a render and resolve if the number
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import * as THREE from 'three'
|
||||
import { Vec3 } from 'vec3'
|
||||
import nbt from 'prismarine-nbt'
|
||||
import { dispose3 } from './dispose'
|
||||
import PrismarineChatLoader from 'prismarine-chat'
|
||||
import { renderSign } from '../sign-renderer/'
|
||||
import { chunkPos, sectionPos } from './simpleUtils'
|
||||
|
|
@ -12,6 +11,7 @@ function mod (x, n) {
|
|||
import { WorldRendererCommon, WorldRendererConfig } from './worldrendererCommon'
|
||||
import * as tweenJs from '@tweenjs/tween.js'
|
||||
import { BloomPass, RenderPass, UnrealBloomPass, EffectComposer, WaterPass, GlitchPass } from 'three-stdlib'
|
||||
import { disposeObject } from './threeJsUtils'
|
||||
|
||||
export class WorldRendererThree extends WorldRendererCommon {
|
||||
outputFormat = 'threeJs' as const
|
||||
|
|
@ -19,13 +19,27 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
sectionObjects: Record<string, THREE.Object3D> = {}
|
||||
chunkTextures = new Map<string, { [pos: string]: THREE.Texture }>()
|
||||
signsCache = new Map<string, any>()
|
||||
starField: StarField
|
||||
cameraSectionPos: Vec3 = new Vec3(0, 0, 0)
|
||||
|
||||
get tilesRendered () {
|
||||
return Object.values(this.sectionObjects).reduce((acc, obj) => acc + (obj as any).tilesCount, 0)
|
||||
}
|
||||
|
||||
constructor(public scene: THREE.Scene, public renderer: THREE.WebGLRenderer, public config: WorldRendererConfig) {
|
||||
constructor (public scene: THREE.Scene, public renderer: THREE.WebGLRenderer, public config: WorldRendererConfig) {
|
||||
super(config)
|
||||
this.starField = new StarField(scene)
|
||||
}
|
||||
|
||||
timeUpdated (newTime: number): void {
|
||||
const nightTime = 13_500
|
||||
const morningStart = 23_000
|
||||
const displayStars = newTime > nightTime && newTime < morningStart
|
||||
if (displayStars && !this.starField.points) {
|
||||
this.starField.addToScene()
|
||||
} else if (!displayStars && this.starField.points) {
|
||||
this.starField.remove()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -33,16 +47,18 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
*/
|
||||
updatePosDataChunk (key: string) {
|
||||
const [x, y, z] = key.split(',').map(x => Math.floor(+x / 16))
|
||||
const [xPlayer, yPlayer, zPlayer] = this.camera.position.toArray().map(x => Math.floor(x / 16))
|
||||
// sum of distances: x + y + z
|
||||
const chunkDistance = Math.abs(x - xPlayer) + Math.abs(y - yPlayer) + Math.abs(z - zPlayer)
|
||||
const chunkDistance = Math.abs(x - this.cameraSectionPos.x) + Math.abs(y - this.cameraSectionPos.y) + Math.abs(z - this.cameraSectionPos.z)
|
||||
const section = this.sectionObjects[key].children.find(child => child.name === 'mesh')!
|
||||
section.renderOrder = 500 - chunkDistance
|
||||
}
|
||||
|
||||
updateViewerPosition (pos: Vec3): void {
|
||||
this.viewerPosition = pos
|
||||
for (const [key, value] of Object.entries(this.sectionObjects)) {
|
||||
const cameraPos = this.camera.position.toArray().map(x => Math.floor(x / 16)) as [number, number, number]
|
||||
this.cameraSectionPos = new Vec3(...cameraPos)
|
||||
for (const key in this.sectionObjects) {
|
||||
const value = this.sectionObjects[key]
|
||||
if (!value) continue
|
||||
this.updatePosDataChunk(key)
|
||||
}
|
||||
|
|
@ -53,7 +69,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
let object: THREE.Object3D = this.sectionObjects[data.key]
|
||||
if (object) {
|
||||
this.scene.remove(object)
|
||||
dispose3(object)
|
||||
disposeObject(object)
|
||||
delete this.sectionObjects[data.key]
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +102,10 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
mesh.name = 'mesh'
|
||||
object = new THREE.Group()
|
||||
object.add(mesh)
|
||||
const boxHelper = new THREE.BoxHelper(mesh, 0xffff00)
|
||||
// mesh with static dimensions: 16x16x16
|
||||
const staticChunkMesh = new THREE.Mesh(new THREE.BoxGeometry(16, 16, 16), new THREE.MeshBasicMaterial({ color: 0x000000, transparent: true, opacity: 0 }))
|
||||
staticChunkMesh.position.set(data.geometry.sx, data.geometry.sy, data.geometry.sz)
|
||||
const boxHelper = new THREE.BoxHelper(staticChunkMesh, 0xffff00)
|
||||
boxHelper.name = 'helper'
|
||||
object.add(boxHelper)
|
||||
object.name = 'chunk'
|
||||
|
|
@ -97,17 +116,22 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
}
|
||||
// should not compute it once
|
||||
if (Object.keys(data.geometry.signs).length) {
|
||||
for (const [posKey, { isWall, rotation }] of Object.entries(data.geometry.signs)) {
|
||||
for (const [posKey, { isWall, isHanging, rotation }] of Object.entries(data.geometry.signs)) {
|
||||
const [x, y, z] = posKey.split(',')
|
||||
const signBlockEntity = this.blockEntities[posKey]
|
||||
if (!signBlockEntity) continue
|
||||
const sign = this.renderSign(new Vec3(+x, +y, +z), rotation, isWall, nbt.simplify(signBlockEntity))
|
||||
const sign = this.renderSign(new Vec3(+x, +y, +z), rotation, isWall, isHanging, nbt.simplify(signBlockEntity))
|
||||
if (!sign) continue
|
||||
object.add(sign)
|
||||
}
|
||||
}
|
||||
this.sectionObjects[data.key] = object
|
||||
this.updatePosDataChunk(data.key)
|
||||
object.matrixAutoUpdate = false
|
||||
mesh.onAfterRender = (renderer, scene, camera, geometry, material, group) => {
|
||||
// mesh.matrixAutoUpdate = false
|
||||
}
|
||||
|
||||
this.scene.add(object)
|
||||
}
|
||||
|
||||
|
|
@ -142,10 +166,11 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
|
||||
render () {
|
||||
tweenJs.update()
|
||||
this.renderer.render(this.scene, this.camera)
|
||||
const cam = this.camera instanceof THREE.Group ? this.camera.children.find(child => child instanceof THREE.PerspectiveCamera) as THREE.PerspectiveCamera : this.camera
|
||||
this.renderer.render(this.scene, cam)
|
||||
}
|
||||
|
||||
renderSign (position: Vec3, rotation: number, isWall: boolean, blockEntity) {
|
||||
renderSign (position: Vec3, rotation: number, isWall: boolean, isHanging: boolean, blockEntity) {
|
||||
const tex = this.getSignTexture(position, blockEntity)
|
||||
|
||||
if (!tex) return
|
||||
|
|
@ -161,14 +186,16 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
const mesh = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), new THREE.MeshBasicMaterial({ map: tex, transparent: true, }))
|
||||
mesh.renderOrder = 999
|
||||
|
||||
// todo @sa2urami shouldnt all this be done in worker?
|
||||
mesh.scale.set(1, 7 / 16, 1)
|
||||
if (isWall) {
|
||||
mesh.position.set(0, 0, -(8 - 1.5) / 16 + 0.001)
|
||||
const lineHeight = 7 / 16
|
||||
const scaleFactor = isHanging ? 1.3 : 1
|
||||
mesh.scale.set(1 * scaleFactor, lineHeight * scaleFactor, 1 * scaleFactor)
|
||||
|
||||
const thickness = (isHanging ? 2 : 1.5) / 16
|
||||
const wallSpacing = 0.25 / 16
|
||||
if (isWall && !isHanging) {
|
||||
mesh.position.set(0, 0, -0.5 + thickness + wallSpacing + 0.0001)
|
||||
} else {
|
||||
// standing
|
||||
const faceEnd = 8.75
|
||||
mesh.position.set(0, 0, (faceEnd - 16 / 2) / 16 + 0.001)
|
||||
mesh.position.set(0, 0, thickness / 2 + 0.0001)
|
||||
}
|
||||
|
||||
const group = new THREE.Group()
|
||||
|
|
@ -176,8 +203,10 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
rotation * (isWall ? 90 : 45 / 2)
|
||||
), 0)
|
||||
group.add(mesh)
|
||||
const y = isWall ? 4.5 / 16 + mesh.scale.y / 2 : (1 - (mesh.scale.y / 2))
|
||||
group.position.set(position.x + 0.5, position.y + y, position.z + 0.5)
|
||||
const height = (isHanging ? 10 : 8) / 16
|
||||
const heightOffset = (isHanging ? 0 : isWall ? 4.333 : 9.333) / 16
|
||||
const textPosition = height / 2 + heightOffset
|
||||
group.position.set(position.x + 0.5, position.y + textPosition, position.z + 0.5)
|
||||
return group
|
||||
}
|
||||
|
||||
|
|
@ -244,6 +273,24 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
}
|
||||
}
|
||||
|
||||
readdChunks () {
|
||||
for (const key of Object.keys(this.sectionObjects)) {
|
||||
this.scene.remove(this.sectionObjects[key])
|
||||
}
|
||||
setTimeout(() => {
|
||||
for (const key of Object.keys(this.sectionObjects)) {
|
||||
this.scene.add(this.sectionObjects[key])
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
|
||||
disableUpdates (children = this.scene.children) {
|
||||
for (const child of children) {
|
||||
child.matrixWorldNeedsUpdate = false
|
||||
this.disableUpdates(child.children ?? [])
|
||||
}
|
||||
}
|
||||
|
||||
removeColumn (x, z) {
|
||||
super.removeColumn(x, z)
|
||||
|
||||
|
|
@ -254,7 +301,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
const mesh = this.sectionObjects[key]
|
||||
if (mesh) {
|
||||
this.scene.remove(mesh)
|
||||
dispose3(mesh)
|
||||
disposeObject(mesh)
|
||||
}
|
||||
delete this.sectionObjects[key]
|
||||
}
|
||||
|
|
@ -265,3 +312,113 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|||
super.setSectionDirty(pos, value)
|
||||
}
|
||||
}
|
||||
|
||||
class StarField {
|
||||
points?: THREE.Points
|
||||
private _enabled = true
|
||||
get enabled () {
|
||||
return this._enabled
|
||||
}
|
||||
set enabled (value) {
|
||||
this._enabled = value
|
||||
if (this.points) {
|
||||
this.points.visible = value
|
||||
}
|
||||
}
|
||||
|
||||
constructor (private scene: THREE.Scene) {
|
||||
}
|
||||
|
||||
addToScene () {
|
||||
if (this.points || !this.enabled) return
|
||||
|
||||
const radius = 80
|
||||
const depth = 50
|
||||
const count = 7000
|
||||
const factor = 7
|
||||
const saturation = 10
|
||||
const speed = 0.2
|
||||
|
||||
const geometry = new THREE.BufferGeometry()
|
||||
|
||||
const genStar = r => new THREE.Vector3().setFromSpherical(new THREE.Spherical(r, Math.acos(1 - Math.random() * 2), Math.random() * 2 * Math.PI))
|
||||
|
||||
const positions = [] as number[]
|
||||
const colors = [] as number[]
|
||||
const sizes = Array.from({ length: count }, () => (0.5 + 0.5 * Math.random()) * factor)
|
||||
const color = new THREE.Color()
|
||||
let r = radius + depth
|
||||
const increment = depth / count
|
||||
for (let i = 0; i < count; i++) {
|
||||
r -= increment * Math.random()
|
||||
positions.push(...genStar(r).toArray())
|
||||
color.setHSL(i / count, saturation, 0.9)
|
||||
colors.push(color.r, color.g, color.b)
|
||||
}
|
||||
|
||||
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))
|
||||
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3))
|
||||
geometry.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1))
|
||||
|
||||
// Create a material
|
||||
const material = new StarfieldMaterial()
|
||||
material.blending = THREE.AdditiveBlending
|
||||
material.depthTest = false
|
||||
material.transparent = true
|
||||
|
||||
// Create points and add them to the scene
|
||||
this.points = new THREE.Points(geometry, material)
|
||||
this.scene.add(this.points)
|
||||
|
||||
const clock = new THREE.Clock()
|
||||
this.points.onBeforeRender = (renderer, scene, camera) => {
|
||||
this.points?.position.copy?.(camera.position)
|
||||
material.uniforms.time.value = clock.getElapsedTime() * speed
|
||||
}
|
||||
}
|
||||
|
||||
remove () {
|
||||
if (this.points) {
|
||||
this.points.geometry.dispose();
|
||||
(this.points.material as THREE.Material).dispose()
|
||||
this.scene.remove(this.points)
|
||||
|
||||
this.points = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const version = parseInt(THREE.REVISION.replace(/\D+/g, ''))
|
||||
class StarfieldMaterial extends THREE.ShaderMaterial {
|
||||
constructor () {
|
||||
super({
|
||||
uniforms: { time: { value: 0.0 }, fade: { value: 1.0 } },
|
||||
vertexShader: /* glsl */ `
|
||||
uniform float time;
|
||||
attribute float size;
|
||||
varying vec3 vColor;
|
||||
attribute vec3 color;
|
||||
void main() {
|
||||
vColor = color;
|
||||
vec4 mvPosition = modelViewMatrix * vec4(position, 0.5);
|
||||
gl_PointSize = size * (30.0 / -mvPosition.z) * (3.0 + sin(time + 100.0));
|
||||
gl_Position = projectionMatrix * mvPosition;
|
||||
}`,
|
||||
fragmentShader: /* glsl */ `
|
||||
uniform sampler2D pointTexture;
|
||||
uniform float fade;
|
||||
varying vec3 vColor;
|
||||
void main() {
|
||||
float opacity = 1.0;
|
||||
if (fade == 1.0) {
|
||||
float d = distance(gl_PointCoord, vec2(0.5, 0.5));
|
||||
opacity = 1.0 / (1.0 + exp(16.0 * (d - 0.25)));
|
||||
}
|
||||
gl_FragColor = vec4(vColor, opacity);
|
||||
|
||||
#include <tonemapping_fragment>
|
||||
#include <${version >= 154 ? 'colorspace_fragment' : 'encodings_fragment'}>
|
||||
}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,20 +31,11 @@ export type JsonAtlas = {
|
|||
[file: string]: {
|
||||
u: number,
|
||||
v: number,
|
||||
su?: number,
|
||||
sv?: number,
|
||||
animatedFrames?: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const makeTextureAtlas = (
|
||||
input: string[],
|
||||
getInputData: (name) => { contents: string, tileWidthMult?: number },
|
||||
tilesCount = input.length,
|
||||
suSvOptimize: 'remove' | null = null,
|
||||
renderAnimated = true
|
||||
): {
|
||||
export const makeTextureAtlas = (input: string[], getInputData: (name) => { contents: string, tileWidthMult?: number, origSizeTextures?}, tilesCount = input.length, suSvOptimize: 'remove' | null = null): {
|
||||
image: Buffer,
|
||||
canvas: Canvas,
|
||||
json: JsonAtlas
|
||||
|
|
@ -56,53 +47,62 @@ export const makeTextureAtlas = (
|
|||
const canvas = new Canvas(imgSize, imgSize, 'png' as any)
|
||||
const g = canvas.getContext('2d')
|
||||
|
||||
const texturesIndex = {} as JsonAtlas['textures']
|
||||
const texturesIndex = {}
|
||||
|
||||
let nextX = 0
|
||||
let nextY = 0
|
||||
let rowMaxY = 0
|
||||
|
||||
const goToNextRow = () => {
|
||||
nextX = 0
|
||||
nextY += rowMaxY
|
||||
rowMaxY = 0
|
||||
}
|
||||
|
||||
let offset = 0
|
||||
const suSv = tileSize / imgSize
|
||||
for (const i in input) {
|
||||
const pos = +i + offset
|
||||
const x = (pos % texSize) * tileSize
|
||||
const y = Math.floor(pos / texSize) * tileSize
|
||||
|
||||
const img = new Image()
|
||||
const keyValue = input[i];
|
||||
const inputData = getInputData(keyValue);
|
||||
const keyValue = input[i]
|
||||
const inputData = getInputData(keyValue)
|
||||
img.src = inputData.contents
|
||||
const renderWidth = tileSize * (inputData.tileWidthMult ?? 1)
|
||||
let animatedFrames = 0
|
||||
const addDebugText = (x, y) => {
|
||||
return // disable debug text
|
||||
g.fillStyle = 'black'
|
||||
g.font = '8px Arial'
|
||||
g.fillText(i, x, y)
|
||||
}
|
||||
if (img.height > tileSize && renderAnimated) {
|
||||
const frames = img.height / tileSize;
|
||||
animatedFrames = frames
|
||||
console.log("Animated texture", keyValue, frames)
|
||||
offset += frames - 1
|
||||
for (let i = 0; i < frames; i++) {
|
||||
const x = ((pos + i) % texSize) * tileSize
|
||||
const y = Math.floor((pos + i) / texSize) * tileSize
|
||||
g.drawImage(img, 0, i * tileSize, renderWidth, tileSize, x, y, renderWidth, tileSize)
|
||||
addDebugText(x, y)
|
||||
let su = suSv
|
||||
let sv = suSv
|
||||
let renderWidth = tileSize * (inputData.tileWidthMult ?? 1)
|
||||
let renderHeight = tileSize
|
||||
if (inputData.origSizeTextures?.[keyValue]) {
|
||||
// todo check have enough space
|
||||
renderWidth = Math.ceil(img.width / tileSize) * tileSize
|
||||
renderHeight = Math.ceil(img.height / tileSize) * tileSize
|
||||
su = renderWidth / imgSize
|
||||
sv = renderHeight / imgSize
|
||||
if (renderHeight > imgSize || renderWidth > imgSize) {
|
||||
throw new Error('Texture ' + keyValue + ' is too big')
|
||||
}
|
||||
} else {
|
||||
g.drawImage(img, 0, 0, renderWidth, tileSize, x, y, renderWidth, tileSize)
|
||||
addDebugText(x, y)
|
||||
}
|
||||
|
||||
if (nextX + renderWidth > imgSize) {
|
||||
goToNextRow()
|
||||
}
|
||||
|
||||
const x = nextX
|
||||
const y = nextY
|
||||
|
||||
nextX += renderWidth
|
||||
rowMaxY = Math.max(rowMaxY, renderHeight)
|
||||
if (nextX >= imgSize) {
|
||||
goToNextRow()
|
||||
}
|
||||
|
||||
g.drawImage(img, 0, 0, renderWidth, renderHeight, x, y, renderWidth, renderHeight)
|
||||
|
||||
const cleanName = keyValue.split('.').slice(0, -1).join('.') || keyValue
|
||||
texturesIndex[cleanName] = {
|
||||
u: x / imgSize,
|
||||
v: y / imgSize,
|
||||
...suSvOptimize === 'remove' ? {} : {
|
||||
su: suSv,
|
||||
sv: suSv
|
||||
},
|
||||
textureName: cleanName,
|
||||
animatedFrames: animatedFrames || undefined
|
||||
su: su,
|
||||
sv: sv
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ export function makeBlockTextureAtlas (mcAssets: McAssets) {
|
|||
// const textureFiles = mostEncounteredBlocks.map(x => x + '.png')
|
||||
textureFiles.unshift(...localTextures)
|
||||
|
||||
const { generated: additionalTextures, twoTileTextures } = getAdditionalTextures()
|
||||
const { generated: additionalTextures, origSizeTextures } = getAdditionalTextures()
|
||||
textureFiles.push(...Object.keys(additionalTextures))
|
||||
|
||||
const atlas = makeTextureAtlas(textureFiles, name => {
|
||||
|
|
@ -136,7 +136,8 @@ export function makeBlockTextureAtlas (mcAssets: McAssets) {
|
|||
|
||||
return {
|
||||
contents,
|
||||
tileWidthMult: twoTileTextures.includes(name) ? 2 : undefined,
|
||||
// tileWidthMult: twoTileTextures.includes(name) ? 2 : undefined,
|
||||
origSizeTextures
|
||||
}
|
||||
})
|
||||
return atlas
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/sign"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/sign"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
{
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
7.25,
|
||||
0,
|
||||
7.25
|
||||
],
|
||||
"to": [
|
||||
8.75,
|
||||
9.333,
|
||||
8.75
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
1.5,
|
||||
8,
|
||||
2,
|
||||
15
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
1,
|
||||
8,
|
||||
1.5,
|
||||
15
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0.5,
|
||||
8,
|
||||
1,
|
||||
15
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
8,
|
||||
0.5,
|
||||
15
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0.5,
|
||||
7,
|
||||
1,
|
||||
8
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
1,
|
||||
7,
|
||||
1.5,
|
||||
8
|
||||
],
|
||||
"texture": "#sign"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
0,
|
||||
9.333,
|
||||
7.25
|
||||
],
|
||||
"to": [
|
||||
16,
|
||||
17.333,
|
||||
8.75
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
7,
|
||||
1,
|
||||
13,
|
||||
7
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
6.5,
|
||||
1,
|
||||
7,
|
||||
7
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0.5,
|
||||
1,
|
||||
6.5,
|
||||
7
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
1,
|
||||
0.5,
|
||||
7
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0.5,
|
||||
0,
|
||||
6.5,
|
||||
1
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
6.5,
|
||||
1,
|
||||
12.5,
|
||||
0
|
||||
],
|
||||
"texture": "#sign"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
0,
|
||||
4.333,
|
||||
0.25
|
||||
],
|
||||
"to": [
|
||||
16,
|
||||
12.333,
|
||||
1.75
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
7,
|
||||
1,
|
||||
13,
|
||||
7
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
6.5,
|
||||
1,
|
||||
7,
|
||||
7
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0.5,
|
||||
1,
|
||||
6.5,
|
||||
7
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
1,
|
||||
0.5,
|
||||
7
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0.5,
|
||||
0,
|
||||
6.5,
|
||||
1
|
||||
],
|
||||
"texture": "#sign"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
6.5,
|
||||
1,
|
||||
12.5,
|
||||
0
|
||||
],
|
||||
"texture": "#sign"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"variants": {
|
||||
"rotation=0": {
|
||||
"model": "sign/oak"
|
||||
},
|
||||
"rotation=1": {
|
||||
"model": "sign/oak",
|
||||
"y": 22.5
|
||||
},
|
||||
"rotation=2": {
|
||||
"model": "sign/oak",
|
||||
"y": 45
|
||||
},
|
||||
"rotation=3": {
|
||||
"model": "sign/oak",
|
||||
"y": 67.5
|
||||
},
|
||||
"rotation=4": {
|
||||
"model": "sign/oak",
|
||||
"y": 90
|
||||
},
|
||||
"rotation=5": {
|
||||
"model": "sign/oak",
|
||||
"y": 112.5
|
||||
},
|
||||
"rotation=6": {
|
||||
"model": "sign/oak",
|
||||
"y": 135
|
||||
},
|
||||
"rotation=7": {
|
||||
"model": "sign/oak",
|
||||
"y": 157.5
|
||||
},
|
||||
"rotation=8": {
|
||||
"model": "sign/oak",
|
||||
"y": 180
|
||||
},
|
||||
"rotation=9": {
|
||||
"model": "sign/oak",
|
||||
"y": 202.5
|
||||
},
|
||||
"rotation=10": {
|
||||
"model": "sign/oak",
|
||||
"y": 225
|
||||
},
|
||||
"rotation=11": {
|
||||
"model": "sign/oak",
|
||||
"y": 247.5
|
||||
},
|
||||
"rotation=12": {
|
||||
"model": "sign/oak",
|
||||
"y": 270
|
||||
},
|
||||
"rotation=13": {
|
||||
"model": "sign/oak",
|
||||
"y": 292.5
|
||||
},
|
||||
"rotation=14": {
|
||||
"model": "sign/oak",
|
||||
"y": 315
|
||||
},
|
||||
"rotation=15": {
|
||||
"model": "sign/oak",
|
||||
"y": 337.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=south": {
|
||||
"model": "sign/oak_wall"
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "sign/oak_wall",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "sign/oak_wall",
|
||||
"y": 180
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "sign/oak_wall",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/signs/acacia"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/signs/acacia"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/signs/birch"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/signs/birch"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/signs/dark_oak"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/signs/dark_oak"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/signs/jungle"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/signs/jungle"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/signs/spruce"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/signs/spruce"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"variants": {
|
||||
"rotation=0": {
|
||||
"model": "sign/acacia"
|
||||
},
|
||||
"rotation=1": {
|
||||
"model": "sign/acacia",
|
||||
"y": 22.5
|
||||
},
|
||||
"rotation=2": {
|
||||
"model": "sign/acacia",
|
||||
"y": 45
|
||||
},
|
||||
"rotation=3": {
|
||||
"model": "sign/acacia",
|
||||
"y": 67.5
|
||||
},
|
||||
"rotation=4": {
|
||||
"model": "sign/acacia",
|
||||
"y": 90
|
||||
},
|
||||
"rotation=5": {
|
||||
"model": "sign/acacia",
|
||||
"y": 112.5
|
||||
},
|
||||
"rotation=6": {
|
||||
"model": "sign/acacia",
|
||||
"y": 135
|
||||
},
|
||||
"rotation=7": {
|
||||
"model": "sign/acacia",
|
||||
"y": 157.5
|
||||
},
|
||||
"rotation=8": {
|
||||
"model": "sign/acacia",
|
||||
"y": 180
|
||||
},
|
||||
"rotation=9": {
|
||||
"model": "sign/acacia",
|
||||
"y": 202.5
|
||||
},
|
||||
"rotation=10": {
|
||||
"model": "sign/acacia",
|
||||
"y": 225
|
||||
},
|
||||
"rotation=11": {
|
||||
"model": "sign/acacia",
|
||||
"y": 247.5
|
||||
},
|
||||
"rotation=12": {
|
||||
"model": "sign/acacia",
|
||||
"y": 270
|
||||
},
|
||||
"rotation=13": {
|
||||
"model": "sign/acacia",
|
||||
"y": 292.5
|
||||
},
|
||||
"rotation=14": {
|
||||
"model": "sign/acacia",
|
||||
"y": 315
|
||||
},
|
||||
"rotation=15": {
|
||||
"model": "sign/acacia",
|
||||
"y": 337.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=south": {
|
||||
"model": "sign/acacia_wall"
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "sign/acacia_wall",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "sign/acacia_wall",
|
||||
"y": 180
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "sign/acacia_wall",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"variants": {
|
||||
"rotation=0": {
|
||||
"model": "sign/birch"
|
||||
},
|
||||
"rotation=1": {
|
||||
"model": "sign/birch",
|
||||
"y": 22.5
|
||||
},
|
||||
"rotation=2": {
|
||||
"model": "sign/birch",
|
||||
"y": 45
|
||||
},
|
||||
"rotation=3": {
|
||||
"model": "sign/birch",
|
||||
"y": 67.5
|
||||
},
|
||||
"rotation=4": {
|
||||
"model": "sign/birch",
|
||||
"y": 90
|
||||
},
|
||||
"rotation=5": {
|
||||
"model": "sign/birch",
|
||||
"y": 112.5
|
||||
},
|
||||
"rotation=6": {
|
||||
"model": "sign/birch",
|
||||
"y": 135
|
||||
},
|
||||
"rotation=7": {
|
||||
"model": "sign/birch",
|
||||
"y": 157.5
|
||||
},
|
||||
"rotation=8": {
|
||||
"model": "sign/birch",
|
||||
"y": 180
|
||||
},
|
||||
"rotation=9": {
|
||||
"model": "sign/birch",
|
||||
"y": 202.5
|
||||
},
|
||||
"rotation=10": {
|
||||
"model": "sign/birch",
|
||||
"y": 225
|
||||
},
|
||||
"rotation=11": {
|
||||
"model": "sign/birch",
|
||||
"y": 247.5
|
||||
},
|
||||
"rotation=12": {
|
||||
"model": "sign/birch",
|
||||
"y": 270
|
||||
},
|
||||
"rotation=13": {
|
||||
"model": "sign/birch",
|
||||
"y": 292.5
|
||||
},
|
||||
"rotation=14": {
|
||||
"model": "sign/birch",
|
||||
"y": 315
|
||||
},
|
||||
"rotation=15": {
|
||||
"model": "sign/birch",
|
||||
"y": 337.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=south": {
|
||||
"model": "sign/birch_wall"
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "sign/birch_wall",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "sign/birch_wall",
|
||||
"y": 180
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "sign/birch_wall",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"variants": {
|
||||
"rotation=0": {
|
||||
"model": "sign/dark_oak"
|
||||
},
|
||||
"rotation=1": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 22.5
|
||||
},
|
||||
"rotation=2": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 45
|
||||
},
|
||||
"rotation=3": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 67.5
|
||||
},
|
||||
"rotation=4": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 90
|
||||
},
|
||||
"rotation=5": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 112.5
|
||||
},
|
||||
"rotation=6": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 135
|
||||
},
|
||||
"rotation=7": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 157.5
|
||||
},
|
||||
"rotation=8": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 180
|
||||
},
|
||||
"rotation=9": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 202.5
|
||||
},
|
||||
"rotation=10": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 225
|
||||
},
|
||||
"rotation=11": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 247.5
|
||||
},
|
||||
"rotation=12": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 270
|
||||
},
|
||||
"rotation=13": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 292.5
|
||||
},
|
||||
"rotation=14": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 315
|
||||
},
|
||||
"rotation=15": {
|
||||
"model": "sign/dark_oak",
|
||||
"y": 337.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=south": {
|
||||
"model": "sign/dark_oak_wall"
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "sign/dark_oak_wall",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "sign/dark_oak_wall",
|
||||
"y": 180
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "sign/dark_oak_wall",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"variants": {
|
||||
"rotation=0": {
|
||||
"model": "sign/jungle"
|
||||
},
|
||||
"rotation=1": {
|
||||
"model": "sign/jungle",
|
||||
"y": 22.5
|
||||
},
|
||||
"rotation=2": {
|
||||
"model": "sign/jungle",
|
||||
"y": 45
|
||||
},
|
||||
"rotation=3": {
|
||||
"model": "sign/jungle",
|
||||
"y": 67.5
|
||||
},
|
||||
"rotation=4": {
|
||||
"model": "sign/jungle",
|
||||
"y": 90
|
||||
},
|
||||
"rotation=5": {
|
||||
"model": "sign/jungle",
|
||||
"y": 112.5
|
||||
},
|
||||
"rotation=6": {
|
||||
"model": "sign/jungle",
|
||||
"y": 135
|
||||
},
|
||||
"rotation=7": {
|
||||
"model": "sign/jungle",
|
||||
"y": 157.5
|
||||
},
|
||||
"rotation=8": {
|
||||
"model": "sign/jungle",
|
||||
"y": 180
|
||||
},
|
||||
"rotation=9": {
|
||||
"model": "sign/jungle",
|
||||
"y": 202.5
|
||||
},
|
||||
"rotation=10": {
|
||||
"model": "sign/jungle",
|
||||
"y": 225
|
||||
},
|
||||
"rotation=11": {
|
||||
"model": "sign/jungle",
|
||||
"y": 247.5
|
||||
},
|
||||
"rotation=12": {
|
||||
"model": "sign/jungle",
|
||||
"y": 270
|
||||
},
|
||||
"rotation=13": {
|
||||
"model": "sign/jungle",
|
||||
"y": 292.5
|
||||
},
|
||||
"rotation=14": {
|
||||
"model": "sign/jungle",
|
||||
"y": 315
|
||||
},
|
||||
"rotation=15": {
|
||||
"model": "sign/jungle",
|
||||
"y": 337.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=south": {
|
||||
"model": "sign/jungle_wall"
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "sign/jungle_wall",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "sign/jungle_wall",
|
||||
"y": 180
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "sign/jungle_wall",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"variants": {
|
||||
"rotation=0": {
|
||||
"model": "sign/oak"
|
||||
},
|
||||
"rotation=1": {
|
||||
"model": "sign/oak",
|
||||
"y": 22.5
|
||||
},
|
||||
"rotation=2": {
|
||||
"model": "sign/oak",
|
||||
"y": 45
|
||||
},
|
||||
"rotation=3": {
|
||||
"model": "sign/oak",
|
||||
"y": 67.5
|
||||
},
|
||||
"rotation=4": {
|
||||
"model": "sign/oak",
|
||||
"y": 90
|
||||
},
|
||||
"rotation=5": {
|
||||
"model": "sign/oak",
|
||||
"y": 112.5
|
||||
},
|
||||
"rotation=6": {
|
||||
"model": "sign/oak",
|
||||
"y": 135
|
||||
},
|
||||
"rotation=7": {
|
||||
"model": "sign/oak",
|
||||
"y": 157.5
|
||||
},
|
||||
"rotation=8": {
|
||||
"model": "sign/oak",
|
||||
"y": 180
|
||||
},
|
||||
"rotation=9": {
|
||||
"model": "sign/oak",
|
||||
"y": 202.5
|
||||
},
|
||||
"rotation=10": {
|
||||
"model": "sign/oak",
|
||||
"y": 225
|
||||
},
|
||||
"rotation=11": {
|
||||
"model": "sign/oak",
|
||||
"y": 247.5
|
||||
},
|
||||
"rotation=12": {
|
||||
"model": "sign/oak",
|
||||
"y": 270
|
||||
},
|
||||
"rotation=13": {
|
||||
"model": "sign/oak",
|
||||
"y": 292.5
|
||||
},
|
||||
"rotation=14": {
|
||||
"model": "sign/oak",
|
||||
"y": 315
|
||||
},
|
||||
"rotation=15": {
|
||||
"model": "sign/oak",
|
||||
"y": 337.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=south": {
|
||||
"model": "sign/oak_wall"
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "sign/oak_wall",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "sign/oak_wall",
|
||||
"y": 180
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "sign/oak_wall",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"variants": {
|
||||
"rotation=0": {
|
||||
"model": "sign/spruce"
|
||||
},
|
||||
"rotation=1": {
|
||||
"model": "sign/spruce",
|
||||
"y": 22.5
|
||||
},
|
||||
"rotation=2": {
|
||||
"model": "sign/spruce",
|
||||
"y": 45
|
||||
},
|
||||
"rotation=3": {
|
||||
"model": "sign/spruce",
|
||||
"y": 67.5
|
||||
},
|
||||
"rotation=4": {
|
||||
"model": "sign/spruce",
|
||||
"y": 90
|
||||
},
|
||||
"rotation=5": {
|
||||
"model": "sign/spruce",
|
||||
"y": 112.5
|
||||
},
|
||||
"rotation=6": {
|
||||
"model": "sign/spruce",
|
||||
"y": 135
|
||||
},
|
||||
"rotation=7": {
|
||||
"model": "sign/spruce",
|
||||
"y": 157.5
|
||||
},
|
||||
"rotation=8": {
|
||||
"model": "sign/spruce",
|
||||
"y": 180
|
||||
},
|
||||
"rotation=9": {
|
||||
"model": "sign/spruce",
|
||||
"y": 202.5
|
||||
},
|
||||
"rotation=10": {
|
||||
"model": "sign/spruce",
|
||||
"y": 225
|
||||
},
|
||||
"rotation=11": {
|
||||
"model": "sign/spruce",
|
||||
"y": 247.5
|
||||
},
|
||||
"rotation=12": {
|
||||
"model": "sign/spruce",
|
||||
"y": 270
|
||||
},
|
||||
"rotation=13": {
|
||||
"model": "sign/spruce",
|
||||
"y": 292.5
|
||||
},
|
||||
"rotation=14": {
|
||||
"model": "sign/spruce",
|
||||
"y": 315
|
||||
},
|
||||
"rotation=15": {
|
||||
"model": "sign/spruce",
|
||||
"y": 337.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=south": {
|
||||
"model": "sign/spruce_wall"
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "sign/spruce_wall",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "sign/spruce_wall",
|
||||
"y": 180
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "sign/spruce_wall",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/signs/crimson"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/signs/crimson"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/signs/warped"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/signs/warped"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"variants": {
|
||||
"rotation=0": {
|
||||
"model": "sign/crimson"
|
||||
},
|
||||
"rotation=1": {
|
||||
"model": "sign/crimson",
|
||||
"y": 22.5
|
||||
},
|
||||
"rotation=2": {
|
||||
"model": "sign/crimson",
|
||||
"y": 45
|
||||
},
|
||||
"rotation=3": {
|
||||
"model": "sign/crimson",
|
||||
"y": 67.5
|
||||
},
|
||||
"rotation=4": {
|
||||
"model": "sign/crimson",
|
||||
"y": 90
|
||||
},
|
||||
"rotation=5": {
|
||||
"model": "sign/crimson",
|
||||
"y": 112.5
|
||||
},
|
||||
"rotation=6": {
|
||||
"model": "sign/crimson",
|
||||
"y": 135
|
||||
},
|
||||
"rotation=7": {
|
||||
"model": "sign/crimson",
|
||||
"y": 157.5
|
||||
},
|
||||
"rotation=8": {
|
||||
"model": "sign/crimson",
|
||||
"y": 180
|
||||
},
|
||||
"rotation=9": {
|
||||
"model": "sign/crimson",
|
||||
"y": 202.5
|
||||
},
|
||||
"rotation=10": {
|
||||
"model": "sign/crimson",
|
||||
"y": 225
|
||||
},
|
||||
"rotation=11": {
|
||||
"model": "sign/crimson",
|
||||
"y": 247.5
|
||||
},
|
||||
"rotation=12": {
|
||||
"model": "sign/crimson",
|
||||
"y": 270
|
||||
},
|
||||
"rotation=13": {
|
||||
"model": "sign/crimson",
|
||||
"y": 292.5
|
||||
},
|
||||
"rotation=14": {
|
||||
"model": "sign/crimson",
|
||||
"y": 315
|
||||
},
|
||||
"rotation=15": {
|
||||
"model": "sign/crimson",
|
||||
"y": 337.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=south": {
|
||||
"model": "sign/crimson_wall"
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "sign/crimson_wall",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "sign/crimson_wall",
|
||||
"y": 180
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "sign/crimson_wall",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"variants": {
|
||||
"rotation=0": {
|
||||
"model": "sign/warped"
|
||||
},
|
||||
"rotation=1": {
|
||||
"model": "sign/warped",
|
||||
"y": 22.5
|
||||
},
|
||||
"rotation=2": {
|
||||
"model": "sign/warped",
|
||||
"y": 45
|
||||
},
|
||||
"rotation=3": {
|
||||
"model": "sign/warped",
|
||||
"y": 67.5
|
||||
},
|
||||
"rotation=4": {
|
||||
"model": "sign/warped",
|
||||
"y": 90
|
||||
},
|
||||
"rotation=5": {
|
||||
"model": "sign/warped",
|
||||
"y": 112.5
|
||||
},
|
||||
"rotation=6": {
|
||||
"model": "sign/warped",
|
||||
"y": 135
|
||||
},
|
||||
"rotation=7": {
|
||||
"model": "sign/warped",
|
||||
"y": 157.5
|
||||
},
|
||||
"rotation=8": {
|
||||
"model": "sign/warped",
|
||||
"y": 180
|
||||
},
|
||||
"rotation=9": {
|
||||
"model": "sign/warped",
|
||||
"y": 202.5
|
||||
},
|
||||
"rotation=10": {
|
||||
"model": "sign/warped",
|
||||
"y": 225
|
||||
},
|
||||
"rotation=11": {
|
||||
"model": "sign/warped",
|
||||
"y": 247.5
|
||||
},
|
||||
"rotation=12": {
|
||||
"model": "sign/warped",
|
||||
"y": 270
|
||||
},
|
||||
"rotation=13": {
|
||||
"model": "sign/warped",
|
||||
"y": 292.5
|
||||
},
|
||||
"rotation=14": {
|
||||
"model": "sign/warped",
|
||||
"y": 315
|
||||
},
|
||||
"rotation=15": {
|
||||
"model": "sign/warped",
|
||||
"y": 337.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=south": {
|
||||
"model": "sign/warped_wall"
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "sign/warped_wall",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "sign/warped_wall",
|
||||
"y": 180
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "sign/warped_wall",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/signs/mangrove"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/signs/mangrove"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"variants": {
|
||||
"rotation=0": {
|
||||
"model": "sign/mangrove"
|
||||
},
|
||||
"rotation=1": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 22.5
|
||||
},
|
||||
"rotation=2": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 45
|
||||
},
|
||||
"rotation=3": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 67.5
|
||||
},
|
||||
"rotation=4": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 90
|
||||
},
|
||||
"rotation=5": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 112.5
|
||||
},
|
||||
"rotation=6": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 135
|
||||
},
|
||||
"rotation=7": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 157.5
|
||||
},
|
||||
"rotation=8": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 180
|
||||
},
|
||||
"rotation=9": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 202.5
|
||||
},
|
||||
"rotation=10": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 225
|
||||
},
|
||||
"rotation=11": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 247.5
|
||||
},
|
||||
"rotation=12": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 270
|
||||
},
|
||||
"rotation=13": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 292.5
|
||||
},
|
||||
"rotation=14": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 315
|
||||
},
|
||||
"rotation=15": {
|
||||
"model": "sign/mangrove",
|
||||
"y": 337.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=south": {
|
||||
"model": "sign/mangrove_wall"
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "sign/mangrove_wall",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "sign/mangrove_wall",
|
||||
"y": 180
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "sign/mangrove_wall",
|
||||
"y": 270
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"texture_size": [32, 32],
|
||||
"textures": {
|
||||
"0": "entity/decorated_pot/decorated_pot_base"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Body",
|
||||
"from": [1, 0, 1],
|
||||
"to": [15, 16, 15],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 6.5, 7, 13.5], "texture": "#0"},
|
||||
"east": {"uv": [0, 6.5, 7, 13.5], "texture": "#0"},
|
||||
"south": {"uv": [0, 6.5, 7, 13.5], "texture": "#0"},
|
||||
"west": {"uv": [0, 6.5, 7, 13.5], "texture": "#0"},
|
||||
"up": {"uv": [7, 6.5, 14, 13.5], "texture": "#0"},
|
||||
"down": {"uv": [7, 6.5, 14, 13.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Neck",
|
||||
"from": [5, 16, 5],
|
||||
"to": [11, 17, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [6, 5.5, 9, 6], "texture": "#0"},
|
||||
"east": {"uv": [9, 5.5, 12, 6], "texture": "#0"},
|
||||
"south": {"uv": [2.5, 5.5, 5.5, 6], "texture": "#0"},
|
||||
"west": {"uv": [0, 5.5, 3, 6], "texture": "#0"},
|
||||
"up": {"uv": [0, 0, 3, 3], "texture": "#0"},
|
||||
"down": {"uv": [0, 0, 3, 3], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Head",
|
||||
"from": [4, 17, 4],
|
||||
"to": [12, 20, 12],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 4, 4, 5.5], "texture": "#0"},
|
||||
"east": {"uv": [4, 4, 8, 5.5], "texture": "#0"},
|
||||
"south": {"uv": [8, 4, 12, 5.5], "texture": "#0"},
|
||||
"west": {"uv": [12, 4, 16, 5.5], "texture": "#0"},
|
||||
"up": {"uv": [4, 0, 8, 4], "texture": "#0"},
|
||||
"down": {"uv": [8, 0, 12, 4], "texture": "#0"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/hanging",
|
||||
"textures": {
|
||||
"wood": "entity/signs/hanging/acacia"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/wall_hanging",
|
||||
"textures": {
|
||||
"wood": "entity/signs/hanging/acacia"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/signs/bamboo"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/hanging",
|
||||
"textures": {
|
||||
"wood": "entity/signs/hanging/bamboo"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/signs/bamboo"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/wall_hanging",
|
||||
"textures": {
|
||||
"wood": "entity/signs/hanging/bamboo"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/hanging",
|
||||
"textures": {
|
||||
"wood": "entity/signs/hanging/birch"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/wall_hanging",
|
||||
"textures": {
|
||||
"wood": "entity/signs/hanging/birch"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign",
|
||||
"textures": {
|
||||
"sign": "entity/signs/cherry"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/hanging",
|
||||
"textures": {
|
||||
"wood": "entity/signs/hanging/cherry"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "sign/sign_wall",
|
||||
"textures": {
|
||||
"sign": "entity/signs/cherry"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/wall_hanging",
|
||||
"textures": {
|
||||
"wood": "entity/signs/hanging/cherry"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/hanging",
|
||||
"textures": {
|
||||
"wood": "entity/signs/hanging/crimson"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"credit": "Made with Blockbench by TyBraniff for Bluemaps support.",
|
||||
"parent": "sign/wall_hanging",
|
||||
"textures": {
|
||||
"wood": "entity/signs/hanging/crimson"
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue