Skip to content

Commit

Permalink
Merge branch 'next' into perf-test
Browse files Browse the repository at this point in the history
  • Loading branch information
zardoy committed Jul 10, 2024
2 parents 92187a6 + ac04d45 commit ea16d88
Show file tree
Hide file tree
Showing 60 changed files with 2,189 additions and 315 deletions.
2 changes: 0 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -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
3 changes: 2 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -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 }}
Expand All @@ -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
Expand Down
11 changes: 6 additions & 5 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
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: [
(Story, c) => {
const noScaling = c.parameters.noScaling
return <div id={noScaling ? '' : 'ui-root'}>
<Story />
</div>;
</div>
},
],
parameters: {
Expand All @@ -23,6 +24,6 @@ const preview: Preview = {
},
},
},
};
}

export default preview;
export default preview
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand All @@ -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

Expand Down
19 changes: 16 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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 [email protected]
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"]
14 changes: 7 additions & 7 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

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)
Expand Down Expand Up @@ -39,9 +39,9 @@ Whatever offline mode you used (zip, folder, just single player), you can always

### 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
Expand All @@ -67,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)).

Expand Down Expand Up @@ -113,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`
Expand Down
6 changes: 5 additions & 1 deletion README.NPM.MD
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Minecraft React

Minecraft UI components for React.

```bash
yarn add minecraft-react
pnpm i minecraft-react
```

![demo](https://github-production-user-asset-6210df.s3.amazonaws.com/46503702/346295584-80f3ed4a-cab6-45d2-8896-5e20233cc9b1.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAVCODYLSA53PQK4ZA%2F20240706%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240706T195400Z&X-Amz-Expires=300&X-Amz-Signature=5b063823a57057c4042c15edd1db3edd107e00940fd0e66a2ba1df4e564a2809&X-Amz-SignedHeaders=host&actor_id=46503702&key_id=0&repo_id=432411890)

## Usage

```jsx
Expand Down
Binary file removed assets/extra-textures/loading.png
Binary file not shown.
Binary file modified assets/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion cypress/e2e/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const compareRenderedFlatWorld = () => {
}

const testWorldLoad = () => {
return 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)
})
Expand Down
4 changes: 4 additions & 0 deletions esbuild.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const buildOptions = {
net: 'net-browserify',
assert: 'assert',
dns: './src/dns.js',
'yggdrasil': './src/yggdrasilReplacement.ts',
// todo write advancedAliases plugin
},
inject: [
Expand All @@ -84,6 +85,9 @@ const buildOptions = {
'.vert': 'text',
'.frag': 'text',
'.obj': 'text',
'.woff': 'dataurl',
'.woff2': 'dataurl',
'.ttf': 'dataurl',
},
write: false,
// todo would be better to enable?
Expand Down
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"@types/react-dom": "^18.2.7",
"@types/wicg-file-system-access": "^2023.10.2",
"@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",
Expand All @@ -64,20 +64,20 @@
"esbuild-plugin-polyfill-node": "^0.3.0",
"express": "^4.18.2",
"filesize": "^10.0.12",
"flying-squid": "npm:@zardoy/flying-squid@^0.0.32",
"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",
"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",
Expand Down Expand Up @@ -161,7 +161,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"
},
Expand All @@ -170,7 +170,8 @@
},
"patchedDependencies": {
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected]"
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected]"
}
},
"packageManager": "[email protected]"
Expand Down
74 changes: 66 additions & 8 deletions patches/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -83,7 +83,7 @@ index c89375e32babbf3559655b1e95f6441b9a30796f..f24cd5dc8fa9a0a4000b184fb3c79590
+ }
endSocket()
}

@@ -195,6 +206,8 @@ class Client extends EventEmitter {
serializer -> framer -> socket -> splitter -> deserializer */
if (this.serializer) {
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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 changes: 27 additions & 0 deletions patches/[email protected]
Original file line number Diff line number Diff line change
@@ -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"; }
-
Loading

0 comments on commit ea16d88

Please sign in to comment.