Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: allow usage in browser #633

Merged
merged 18 commits into from
Dec 31, 2023
Merged

Conversation

zardoy
Copy link
Contributor

@zardoy zardoy commented Sep 3, 2023

Depends on PrismarineJS/node-minecraft-protocol#1254

fixes #491

Usage:

Both esbuild and webpack needs Node.js modules polyfilling.

  • esbuild: needs custom plugin like this one
  • webpack: needs module: { parser: { javascript: { commonjsMagicComments: true } } }

First of all, I'm really sorry for the delay, I wish I could do it early.

Anyway, right now I decided to squash all changes from here into one commit.

Will try to provide a brief overview of the changes I made here in comments.

  • Refactored plugin loading so its compatible with webpack (at least I tested the first version of it) and esbuild that I use currently.

  • I did initially a huge refactor by adding types, but I reverted them so its easier to review. Anyway, feel free to ask any questions

@socket-security
Copy link

socket-security bot commented Sep 3, 2023

New and removed dependencies detected. Learn more about Socket for GitHub ↗︎

Packages Version New capabilities Transitives Size Publisher
exit-hook 2.2.1 None +0 4.83 kB sindresorhus

🚮 Removed packages: [email protected]

@@ -21,7 +19,11 @@
"test": "npm run mocha_test",
"pretest": "npm run lint"
},
"keywords": [],
"keywords": [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI just added some keywords (why not)

src/index.js Outdated Show resolved Hide resolved
@@ -38,23 +38,23 @@ function createMCServer (options) {

class MCServer extends EventEmitter {
constructor () {
plugins.initPlugins()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we now load plugins lazily

if (isInNode) {
import(/* webpackIgnore: true */ 'exit-hook').then((hook) => {
hook.default(() => {
for (const serv of _servers) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the context of this refactor also fixed an important bug: worlds are not saved when server crashed or stopped by ctrl+c

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the intent and I agree the feature is nice. However that couple the lib and the app parts of flying-squid
What about instead define this as some ServerManager class and use it in app.js ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about exit-hook: this is totally okay to have it as part of the library and why not have it so "better behavior is enabled by default"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, as I understand there is also no way to disable readline, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"exit-hook: this is totally okay to have it as part of the library"

no that's exactly the part I don't like.

I think it's good if the library exposes a function that makes this possible, and then it's called by default in https://github.com/PrismarineJS/flying-squid/blob/master/app.js

having the library actually call it forces the user into a specific application setup

Copy link
Contributor Author

@zardoy zardoy Sep 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no that's exactly the part I don't like.

Alright, I don't mind making it an opt-in behavior, however, then I think it would make sense to make creating readline interface optional as well. What do you think?
Otherwise I might be missing use-cases of this library (sorry)

I think it's good if the library exposes a function that makes this possible

Will extract & doc it later today or tomorrow, not a problem

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's good if the library exposes a function that makes this possible, and then it's called by default

Maybe this should be done as option? like registerExitHook: true ?

src/lib/plugins/log.js Outdated Show resolved Hide resolved
try {
const player = serv.initEntity('player', null, serv.overworld, new Vec3(0, 0, 0))
player._client = client
player._client.socket ??= { remoteAddress: '' }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about instead checking if it's defined where it's used ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed mocking remoteAddress since nothing will crash if it is undefined, but maybe it should be documented in some way I don't really know (so other plugins can know it can be undefined)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where did you remove it ? I don't understand

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, sorry for now making it clear I meant this 18fe14a . However I removed mocking : 6dff61f is it better?
I'm open to any option here.


module.exports.server = function (serv, options) {
serv._server.on('connection', client =>
client.on('error', error => serv.emit('clientError', client, error)))

serv._server.on('login', async (client) => {
if (client.socket.listeners('end').length === 0) return // TODO: should be fixed properly in nmp instead
if (client.socket?.listeners('end').length === 0) return // TODO: should be fixed properly in nmp instead
if (!serv.worldsReady) throw new Error('World is still preparing.')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I remember this is another bugfix: when a player connects when world is not ready yet it crashes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about returning instead of throwing if this is not an error ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes of course it makes sense I fixed it here 923a829

theItem = mcData.blocksByName[itemName]
}
const itemName = item.id.value.slice(10) // skip game brand prefix
const theItem = mcData.itemsByName[itemName] || mcData.blocksByName[itemName]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just refactored thats it

player.emit('spawned')

await player.waitPlayerLogin()
player.sendRestMap()
sendChunkWhenMove()

player.save()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by doing this a new entry in playerdata/ appears immediately after a new player joins

src/lib/plugins/world.js Outdated Show resolved Hide resolved
src/lib/plugins/world.js Outdated Show resolved Hide resolved
src/lib/plugins/world.js Outdated Show resolved Hide resolved

module.exports.server = function (serv, settings) {
_servers.push(serv)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is _servers ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it was possible to create multiple servers. However, now I understand that I could just inline exit-hook handler here.

@rom1504
Copy link
Member

rom1504 commented Sep 3, 2023

Overall looks good, but left some comments

@rom1504 rom1504 merged commit 768b69b into PrismarineJS:master Dec 31, 2023
11 checks passed
@rom1504
Copy link
Member

rom1504 commented Dec 31, 2023

overall lgtm, merged

@rom1504
Copy link
Member

rom1504 commented Dec 31, 2023

/makerelease

@rom1504bot rom1504bot mentioned this pull request Dec 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Closed
Development

Successfully merging this pull request may close these issues.

[feat req] Use in browser via webpack, browserify
2 participants