@@ -1878,6 +1878,11 @@ protected void checkBlockCollision() {
1878
1878
1879
1879
if (this .inPortalTicks == (this .gamemode == CREATIVE ? 1 : 80 )) {
1880
1880
EntityPortalEnterEvent ev = new EntityPortalEnterEvent (this , EntityPortalEnterEvent .PortalType .NETHER );
1881
+
1882
+ if (this .portalPos == null ) {
1883
+ ev .setCancelled ();
1884
+ }
1885
+
1881
1886
this .getServer ().getPluginManager ().callEvent (ev );
1882
1887
1883
1888
if (ev .isCancelled ()) {
@@ -2379,7 +2384,7 @@ public boolean onUpdate(int currentTick) {
2379
2384
Item elytra = inv .getChestplate ();
2380
2385
if (elytra == null || elytra .getId () != ItemID .ELYTRA ) {
2381
2386
this .setGliding (false );
2382
- } else if ((this .gamemode & 0x01 ) == 0 && this .age % (20 * (elytra .getEnchantmentLevel (Enchantment .ID_DURABILITY ) + 1 )) == 0 ) {
2387
+ } else if ((this .gamemode & 0x01 ) == 0 && this .age % (20 * (elytra .getEnchantmentLevel (Enchantment .ID_DURABILITY ) + 1 )) == 0 && ! elytra . isUnbreakable () ) {
2383
2388
elytra .setDamage (elytra .getDamage () + 1 );
2384
2389
if (elytra .getDamage () >= elytra .getMaxDurability ()) {
2385
2390
this .setGliding (false );
@@ -3338,6 +3343,48 @@ public void onCompletion(Server server) {
3338
3343
}
3339
3344
}
3340
3345
3346
+ if (authPacket .getInputData ().contains (AuthInputAction .START_SPIN_ATTACK )) {
3347
+ Enchantment riptide = this .getInventory ().getItemInHandFast ().getEnchantment (Enchantment .ID_TRIDENT_RIPTIDE );
3348
+ if (riptide != null ) {
3349
+ PlayerToggleSpinAttackEvent playerToggleSpinAttackEvent = new PlayerToggleSpinAttackEvent (this , true );
3350
+
3351
+ if (riptide .getLevel () < 1 ) {
3352
+ playerToggleSpinAttackEvent .setCancelled (true );
3353
+ } else {
3354
+ boolean inWater = false ;
3355
+ for (Block block : this .getCollisionBlocks ()) {
3356
+ if (block instanceof BlockWater || block .level .isBlockWaterloggedAt (this .chunk , (int ) block .x , (int ) block .y , (int ) block .z )) {
3357
+ inWater = true ;
3358
+ break ;
3359
+ }
3360
+ }
3361
+ if (!(inWater || (this .getLevel ().isRaining () && this .canSeeSky ()))) {
3362
+ playerToggleSpinAttackEvent .setCancelled (true );
3363
+ }
3364
+ }
3365
+
3366
+ server .getPluginManager ().callEvent (playerToggleSpinAttackEvent );
3367
+
3368
+ if (playerToggleSpinAttackEvent .isCancelled ()) {
3369
+ this .setNeedSendData (true );
3370
+ } else {
3371
+ this .onSpinAttack (riptide .getLevel ());
3372
+ this .setSpinAttack (true );
3373
+ this .setUsingItem (false );
3374
+ this .resetFallDistance ();
3375
+ int riptideSound ;
3376
+ if (riptide .getLevel () >= 3 ) {
3377
+ riptideSound = LevelSoundEventPacket .SOUND_ITEM_TRIDENT_RIPTIDE_3 ;
3378
+ } else if (riptide .getLevel () == 2 ) {
3379
+ riptideSound = LevelSoundEventPacket .SOUND_ITEM_TRIDENT_RIPTIDE_2 ;
3380
+ } else {
3381
+ riptideSound = LevelSoundEventPacket .SOUND_ITEM_TRIDENT_RIPTIDE_1 ;
3382
+ }
3383
+ this .getLevel ().addLevelSoundEvent (this , riptideSound );
3384
+ }
3385
+ }
3386
+ }
3387
+
3341
3388
if (authPacket .getInputData ().contains (AuthInputAction .STOP_SPIN_ATTACK )) {
3342
3389
PlayerToggleSpinAttackEvent playerToggleSpinAttackEvent = new PlayerToggleSpinAttackEvent (this , false );
3343
3390
this .server .getPluginManager ().callEvent (playerToggleSpinAttackEvent );
@@ -3554,6 +3601,8 @@ public void onCompletion(Server server) {
3554
3601
this .inventoryOpen = true ;
3555
3602
this .awardAchievement ("openInventory" );
3556
3603
}
3604
+ } else if (Nukkit .DEBUG > 1 ) {
3605
+ server .getLogger ().debug (this .username + " tried to open inventory but one is already open" );
3557
3606
}
3558
3607
return ;
3559
3608
case InteractPacket .ACTION_MOUSEOVER :
@@ -3764,36 +3813,47 @@ public void onCompletion(Server server) {
3764
3813
return ;
3765
3814
case ProtocolInfo .CONTAINER_CLOSE_PACKET :
3766
3815
ContainerClosePacket containerClosePacket = (ContainerClosePacket ) packet ;
3767
- if (!this .spawned || (containerClosePacket .windowId == ContainerIds .INVENTORY && !inventoryOpen )) {
3768
- return ;
3769
- }
3770
3816
3771
- if (this .windowIndex .containsKey (containerClosePacket .windowId )) {
3772
- this .server .getPluginManager ().callEvent (new InventoryCloseEvent (this .windowIndex .get (containerClosePacket .windowId ), this ));
3773
- if (containerClosePacket .windowId == ContainerIds .INVENTORY ) this .inventoryOpen = false ;
3774
- this .closingWindowId = containerClosePacket .windowId ;
3775
- this .removeWindow (this .windowIndex .get (containerClosePacket .windowId ), true );
3776
- this .closingWindowId = Integer .MIN_VALUE ;
3817
+ if (!this .spawned ) {
3818
+ return ;
3777
3819
}
3778
3820
3779
3821
if (containerClosePacket .windowId == -1 ) {
3822
+ // At least 1.21 does sometimes send windowId -1 when opening and closing containers quickly
3823
+ if (this .inventoryOpen ) {
3824
+ this .inventoryOpen = false ;
3825
+
3826
+ if (this .craftingType == CRAFTING_SMALL ) {
3827
+ for (Entry <Inventory , Integer > open : new ArrayList <>(this .windows .entrySet ())) {
3828
+ if (open .getKey () instanceof ContainerInventory || open .getKey () instanceof PlayerEnderChestInventory ) {
3829
+ this .server .getPluginManager ().callEvent (new InventoryCloseEvent (open .getKey (), this ));
3830
+ this .closingWindowId = Integer .MAX_VALUE ;
3831
+ this .removeWindow (open .getKey (), true );
3832
+ this .closingWindowId = Integer .MIN_VALUE ;
3833
+ }
3834
+ }
3835
+ return ;
3836
+ }
3837
+ }
3838
+
3780
3839
this .resetCraftingGridType ();
3781
3840
this .addWindow (this .craftingGrid , ContainerIds .NONE );
3782
3841
ContainerClosePacket pk = new ContainerClosePacket ();
3783
3842
pk .windowId = -1 ;
3784
3843
pk .wasServerInitiated = false ;
3785
3844
this .dataPacket (pk );
3786
- } else { // TODO: check this
3845
+ } else if (this .windowIndex .containsKey (containerClosePacket .windowId )) {
3846
+ this .inventoryOpen = false ;
3847
+ Inventory inn = this .windowIndex .get (containerClosePacket .windowId );
3848
+ this .server .getPluginManager ().callEvent (new InventoryCloseEvent (inn , this ));
3849
+ this .closingWindowId = containerClosePacket .windowId ;
3850
+ this .removeWindow (inn , true );
3851
+ this .closingWindowId = Integer .MIN_VALUE ;
3852
+ } else { // Close the bugged inventory client refused with id -1 above
3787
3853
ContainerClosePacket pk = new ContainerClosePacket ();
3788
3854
pk .windowId = containerClosePacket .windowId ;
3789
3855
pk .wasServerInitiated = false ;
3790
3856
this .dataPacket (pk );
3791
-
3792
- for (Inventory open : new ArrayList <>(this .windows .keySet ())) {
3793
- if (open instanceof ContainerInventory ) {
3794
- this .removeWindow (open );
3795
- }
3796
- }
3797
3857
}
3798
3858
return ;
3799
3859
case ProtocolInfo .BLOCK_ENTITY_DATA_PACKET :
@@ -6494,7 +6554,7 @@ public void resetCraftingGridType() {
6494
6554
*/
6495
6555
private void moveBlockUIContents (int window ) {
6496
6556
Inventory inventory = this .getWindowById (window );
6497
- if (inventory != null && !( inventory instanceof ContainerInventory ) ) {
6557
+ if (inventory instanceof FakeBlockUIComponent ) {
6498
6558
Item [] drops = this .inventory .addItem (inventory .getContents ().values ().toArray (new Item [0 ]));
6499
6559
inventory .clearAll ();
6500
6560
for (Item drop : drops ) {
0 commit comments