Commit Graph

224 Commits

Author SHA1 Message Date
afb54f1ae4 World: flip orderChunkPopulation() condition around
this makes it more obvious that the code is similar to requestChunkPopulation() barring one distinct difference.
2021-11-01 00:25:30 +00:00
8f803df511 World: check population locks _after_ checking if the chunk is already populated, not before
this led to another case where a population request would be queued up for an already-populated chunk for no reason.
2021-10-31 23:54:27 +00:00
f4a3c40b5c World: use better variable names in orderChunkPopulation() 2021-10-31 23:48:00 +00:00
9dec82cdbc World: fixed requestChunkPopulation() queuing requests for chunks which are already populated
this led to chunk sending getting bogged down if there were more than population-queue-size chunks waiting to be generated.
2021-10-31 23:40:34 +00:00
74031d2fbe World: remove the fulfilled promise from the population request map
fixes crash when unregistering chunk loaders
2021-10-31 23:05:12 +00:00
96cfdc79b8 World: fixed original promise not getting fulfilled if the chunk became populated=true after a promise was already made (but not fulfilled) to populate it
this could happen if a plugin calls setPopulated(true) on a chunk after a request for its population landed in the queue, but before it actually got processed. In that case, the promise would never get fulfilled.
2021-10-31 22:54:37 +00:00
2fa0a914ff World::orderChunkPopulation() may return a pre-resolved promise
this does not indicate a failure; it indicates that the chunk has already been successfully populated.
In this case, we shouldn't be putting the task back on the queue.

This is skirting around the real bug, which is that requestChunkPopulation() doesn't check if the target chunk is already populated before it creates a new promise that it will be.
2021-10-31 22:51:37 +00:00
0f78a2b5ef Advisory chunk locking for chunk population (#4513)
this allows chunks locked for population to be modified. If the PopulationTask detects that the chunk was modified during the onCompletion(), the result of the population will be discarded and rescheduled, so that it includes user modifications.
2021-10-31 21:11:20 +00:00
f1a791ef75 Improved Promise API - separate resolver and consumer APIs
this makes creating a promise slightly more cumbersome, but I'm more concerned about people who might try to call 'new Promise' directly.
2021-10-31 19:49:57 +00:00
4fe3f69702 World: eliminate final remaining 'no loaders attached' debug message on player creation 2021-10-31 14:33:27 +00:00
fbb91d123d World::unregisterChunkListenerFromAll(): go through unregisterChunkListener()
this ensures that everything gets cleaned up properly (e.g. player chunk listeners).
2021-10-31 14:03:40 +00:00
3dc75644d9 World: avoid duplicated logger code in initChunk() 2021-10-31 14:02:25 +00:00
1cabe4baf3 World: do not crash on duplicate tiles loaded from disk
closes #4049
2021-10-31 13:58:32 +00:00
faad2365e2 World: Register a temporary chunk loader on chunks used by PopulationTask
fixes #3839
2021-10-30 22:17:06 +01:00
465a509858 World: remove spammy debug message 2021-10-30 16:13:01 +01:00
a4eda9a8f5 World: call nearby entities' onNearbyBlockChange() in setChunk()
fixes #2779 in all known cases.
2021-10-28 23:59:32 +01:00
eb75df6f8e World: Intelligently perform automatic transfer or deletion of tiles in setChunk(), depending on the context
tiles may be deleted in the following circumstances:
1) the target block in the new chunk doesn't expect a tile
2) the target block in the new chunk expects a different type of tile (responsibility of the plugin developer to create the new tile)
3) there's already a tile in the target chunk which conflicts with the old one

In all other cases, the tile will be transferred.

This resolves a large number of unintentional bugs caused by world editors replacing chunks without setting the deleteTilesAndEntities parameter to false (even the core itself does it).

closes #4520
2021-10-28 23:48:17 +01:00
c66790b6a6 World: never delete entities in setChunk()
entities exist completely independently from chunks now, so there is no need to interact with them whatsoever.
As I wrote in #4520, there's no sense in deleting entities here, since a chunk replacement is essentially just a mass block update.

On that theme, it might be a good idea to call Entity->onNearbyBlockChange() for all entities in the target and adjacent chunks when replacing a chunk, to ensure that they get the proper movement updates.
2021-10-28 23:42:28 +01:00
d78801b9d5 World: fixed tiles and entities getting deleted when adjacent chunks are modified during population 2021-10-28 22:24:47 +01:00
a7d8a598e1 World: reduce code duplication for chunk coordinate calculation 2021-10-26 22:58:17 +01:00
51fbff204b World: make PhpStorm understand return type of getAdjacentChunks() 2021-10-26 20:32:09 +01:00
fca70efbb1 World: move chunk population related methods to be in the same overall place 2021-10-26 16:44:08 +01:00
8f88393184 World: Specialize generateChunkCallback() for PopulationTask
this allows us to also set the adjacent chunks before calling ChunkPopulateEvent, to give a more accurate picture of what changed.
2021-10-26 15:28:00 +01:00
c773e43eda Updated BedrockProtocol to pmmp/BedrockProtocol@97fa88e9ef 2021-10-23 01:16:45 +01:00
34f54750c8 Added support for creation-time validation of generator options, closes #2717 2021-10-11 17:37:47 +01:00
7b6632941d GeneratorManager::getGenerator() now returns null for unknown generator aliases
instead of returning Normal::class (indistinguishable from successful match) or throwing an exception (pain in the ass to handle).
2021-10-11 16:04:36 +01:00
f5266ec816 World: remove dead code leftover from 34f01a3ce3
fixes #4486
2021-10-02 12:33:46 +01:00
5ddd94b7e8 Remove redundant World->isChunkGenerated() calls
isChunkGenerated() merely checks if the chunk can be loaded from disk, if it's not in the runtime cache already.
This is pointless in all of these cases, because the check is prefaced by an isChunkLoaded() check, which already limits the possibility anyway. If the chunk is not generated, it'll also be considered not loaded.
2021-09-12 15:21:09 +01:00
f0fa561c2f World: use arrow functions in useBreakOn() 2021-09-12 15:16:55 +01:00
4111d92b98 Stop hardcoding chunk dimensions everywhere (#4443) 2021-09-10 16:13:25 +01:00
9d5a86fe53 Revert "World: make the second parameter for getCollidingEntities() mandatory and non-nullable"
This reverts commit e1b7bf31bb.

fixes #4447
2021-09-10 16:06:08 +01:00
e0e19c67ef World: do not warn about leaked Player entities during world unload
this raises false-positives during shutdown if players were online.
The fact that the player entity leans on the World to clean up after it is slightly problematic, but I'm not sure what else to do about it for now.
2021-09-09 15:55:37 +01:00
34f01a3ce3 World: Track entities separately from chunks
this allows entities to exist outside of generated chunks, with one caveat: they won't be saved in such cases.
Obviously, for player entities, this doesn't matter.

fixes #3947
2021-09-09 01:17:41 +01:00
ba2bfe0e11 World: depopulate neighbourBlockUpdateQueueIndex sooner
this fixes 2 problems:
1) Blocks which set themselves to something else during onNearbyBlockChange() would not receive any block update
2) A memory leak when blocks in unloaded chunks were scheduled for an update.

I'm a little uneasy about this change, because there must have been some reason why I put this at the end of the block and not at the start, but whatever it is, I can't reason about it, and there's reasons not to put it at the end too.
2021-09-08 22:11:17 +01:00
72fb49b356 World: add notifyNeighbourBlockUpdate() to allow triggering neighbour block updates on blocks manually
this can be useful if blocks were modified asynchronously.
2021-09-07 20:18:53 +01:00
e1b7bf31bb World: make the second parameter for getCollidingEntities() mandatory and non-nullable
the only reason to use getCollidingEntities() instead of getNearbyEntities() is if you have an entity that may or may not be collidable depending on certain conditions.
Really, I don't think this logic belongs in World at all, but for now it has to stay, because some other stuff depends on it.
2021-09-05 15:22:12 +01:00
2fc33d3bff World: remove unused variable 2021-09-05 15:15:48 +01:00
19513c65f0 World: avoid code duplication between getCollidingEntities() and getNearbyEntities()
these two methods are very misleadingly named, but they do almost exactly the same thing - the only difference is that getCollidingEntities() does a couple of additional checks.
2021-09-05 15:13:22 +01:00
0289b45202 Chunk: Drop dirty flags for tiles and entities
instead, just ungate this and allow the provider to decide what to do.
Any chunk that contains entities or tiles is already always considered dirty, so the only thing the flags are good for is flagging chunks that previously had tiles and/or entities but no longer do.
In those cases, it's just removing keys from LevelDB anyway, so it's already very cheap.
Avoiding these redundant deletions is not worth the extra complexity and fragility of relying on flags to track this stuff.
2021-08-30 00:09:36 +01:00
994a2c9eb9 Clean up entity/tile data loading from world providers 2021-08-29 23:11:18 +01:00
ee16a00c57 World: do not attempt placement of itemblock if stack size is zero (#4410)
This doesn't make any sense, and also caused a crash.
2021-08-27 13:14:56 +01:00
224d71f272 World: renamed getChunks() to getLoadedChunks() (#4393) 2021-08-23 21:23:35 +01:00
7fd712c1ff Refactor Block & Tile: getPos() to getPosition() (#4395)
this also changes the name of the class property 'pos' to 'position' as well as Block->getPosOffset() to Block->getPositionOffset()
2021-08-23 14:01:32 +01:00
7d9f8ff4ed World: do not use static:: for private property access 2021-08-21 15:46:19 +01:00
2293bd948d Added KnownTranslationFactory and use it in as many places as possible
this makes translation usage much more statically analysable.
The only places this isn't used are:
- places that prefix translations with colours (those are still a problem)
- places where server/client translations don't match (e.g. gameMode.changed accepts different parameters in vanilla than in PM)
2021-08-10 14:50:40 +01:00
91d54ff0ad Removed unnecessary and/or obsolete GC hacks
the intent of these hacks was to break cyclic references to avoid having objects lingering in memory. However, all of the stuff that's being removed in this commit no longer has any effect anyway, due to the fact that these things don't circularly reference each other anymore. Notably, Tile inventories now keep Position instead of a Tile ref.
2021-06-30 19:16:25 +01:00
94e16f416d Added KnownTranslationKeys (generated) and start using it 2021-06-29 22:46:04 +01:00
02fab77e55 World: change 'closed' to 'unloaded'
this makes more sense overall from a reader's perspective.
and also provide a rug-jerk for any idiots using World->close() when they aren't supposed to? ....
2021-06-26 21:54:18 +01:00
fc70b625b3 ExperienceOrb: Require providing XP value in constructor 2021-06-19 19:42:13 +01:00
981b0285d1 Isolate config casting nastiness in one place
this doesn't solve the underlying problem, but it does reduce the amount of noise made by PHPStan about it, as well as avoiding code litter.
2021-06-19 19:14:02 +01:00